diff options
-rw-r--r-- | compiler/exception_test.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 2 | ||||
-rw-r--r-- | dex2oat/linker/image_writer.cc | 4 | ||||
-rw-r--r-- | openjdkjvmti/ti_method.cc | 9 | ||||
-rw-r--r-- | openjdkjvmti/ti_redefine.cc | 5 | ||||
-rw-r--r-- | runtime/art_method-inl.h | 11 | ||||
-rw-r--r-- | runtime/art_method.cc | 2 | ||||
-rw-r--r-- | runtime/art_method.h | 27 | ||||
-rw-r--r-- | runtime/cha.cc | 3 | ||||
-rw-r--r-- | runtime/class_linker.cc | 34 | ||||
-rw-r--r-- | runtime/dex/dex_file_annotations.cc | 2 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 6 | ||||
-rw-r--r-- | runtime/interpreter/interpreter.cc | 2 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm64ng/main.S | 11 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86_64ng/main.S | 16 | ||||
-rw-r--r-- | tools/cpp-define-generator/art_method.def | 4 |
16 files changed, 84 insertions, 57 deletions
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc index 7d56da07fb..9212ea6c90 100644 --- a/compiler/exception_test.cc +++ b/compiler/exception_test.cc @@ -17,6 +17,7 @@ #include <memory> #include <type_traits> +#include "art_method-inl.h" #include "base/arena_allocator.h" #include "base/callee_save_type.h" #include "base/enums.h" @@ -128,7 +129,7 @@ class ExceptionTest : public CommonRuntimeTest { TEST_F(ExceptionTest, FindCatchHandler) { ScopedObjectAccess soa(Thread::Current()); - CodeItemDataAccessor accessor(*dex_, dex_->GetCodeItem(method_f_->GetCodeItemOffset())); + CodeItemDataAccessor accessor(*dex_, method_f_->GetCodeItem()); ASSERT_TRUE(accessor.HasCodeItem()); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 392aaddaa6..3c168bad65 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -1238,7 +1238,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, const DexFile* dex_file = method->GetDexFile(); const uint16_t class_def_idx = method->GetClassDefIndex(); - const dex::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset()); + const dex::CodeItem* code_item = method->GetCodeItem(); const uint32_t method_idx = method->GetDexMethodIndex(); const uint32_t access_flags = method->GetAccessFlags(); diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc index fbdffa8502..42c570f0a0 100644 --- a/dex2oat/linker/image_writer.cc +++ b/dex2oat/linker/image_writer.cc @@ -3473,8 +3473,10 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig, StubType stub_type = orig->IsCriticalNative() ? StubType::kJNIDlsymLookupCriticalTrampoline : StubType::kJNIDlsymLookupTrampoline; copy->SetEntryPointFromJniPtrSize(GetOatAddress(stub_type), target_ptr_size_); - } else { + } else if (!orig->HasCodeItem()) { CHECK(copy->GetDataPtrSize(target_ptr_size_) == nullptr); + } else { + CHECK(copy->GetDataPtrSize(target_ptr_size_) != nullptr); } } } diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc index e7f071fac8..f2646c6c45 100644 --- a/openjdkjvmti/ti_method.cc +++ b/openjdkjvmti/ti_method.cc @@ -190,7 +190,8 @@ jvmtiError MethodUtil::GetArgumentsSize(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } - DCHECK_NE(art_method->GetCodeItemOffset(), 0u); + DCHECK(art_method->HasCodeItem()); + DCHECK_NE(art_method->GetCodeItem(), nullptr); *size_ptr = art_method->DexInstructionData().InsSize(); return ERR(NONE); @@ -306,7 +307,8 @@ jvmtiError MethodUtil::GetMaxLocals(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } - DCHECK_NE(art_method->GetCodeItemOffset(), 0u); + DCHECK(art_method->HasCodeItem()); + DCHECK_NE(art_method->GetCodeItem(), nullptr); *max_ptr = art_method->DexInstructionData().RegistersSize(); return ERR(NONE); @@ -420,7 +422,8 @@ jvmtiError MethodUtil::GetMethodLocation(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } - DCHECK_NE(art_method->GetCodeItemOffset(), 0u); + DCHECK(art_method->HasCodeItem()); + DCHECK_NE(art_method->GetCodeItem(), nullptr); *start_location_ptr = 0; *end_location_ptr = art_method->DexInstructions().InsnsSizeInCodeUnits() - 1; diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc index d442799379..afaea6279d 100644 --- a/openjdkjvmti/ti_redefine.cc +++ b/openjdkjvmti/ti_redefine.cc @@ -2583,7 +2583,10 @@ void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id); method.SetDexMethodIndex(dex_method_idx); linker->SetEntryPointsToInterpreter(&method); - method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(class_def, dex_method_idx)); + if (method.HasCodeItem()) { + method.SetCodeItem( + dex_file_->GetCodeItem(dex_file_->FindCodeItemOffset(class_def, dex_method_idx))); + } // Clear all the intrinsics related flags. method.SetNotIntrinsic(); } diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 03b4ce9078..01fa33fc65 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -223,7 +223,14 @@ inline ObjPtr<mirror::String> ArtMethod::ResolveNameString() { } inline const dex::CodeItem* ArtMethod::GetCodeItem() { - return GetDexFile()->GetCodeItem(GetCodeItemOffset()); + if (!HasCodeItem()) { + return nullptr; + } + Runtime* runtime = Runtime::Current(); + PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize(); + return runtime->IsAotCompiler() + ? GetDexFile()->GetCodeItem(reinterpret_cast32<uint32_t>(GetDataPtrSize(pointer_size))) + : reinterpret_cast<const dex::CodeItem*>(GetDataPtrSize(pointer_size)); } inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx) { @@ -384,8 +391,6 @@ inline void ArtMethod::UpdateEntrypoints(const Visitor& visitor, PointerSize poi if (old_native_code != new_native_code) { SetEntryPointFromJniPtrSize(new_native_code, pointer_size); } - } else { - DCHECK(GetDataPtrSize(pointer_size) == nullptr); } const void* old_code = GetEntryPointFromQuickCompiledCodePtrSize(pointer_size); const void* new_code = visitor(old_code); diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 45a6938694..0a824e3374 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -771,7 +771,7 @@ void ArtMethod::CopyFrom(ArtMethod* src, PointerSize image_pointer_size) { } // Clear the data pointer, it will be set if needed by the caller. - if (!src->IsNative()) { + if (!src->HasCodeItem() && !src->IsNative()) { SetDataPtrSize(nullptr, image_pointer_size); } // Clear hotness to let the JIT properly decide when to compile this method. diff --git a/runtime/art_method.h b/runtime/art_method.h index 6050f003c0..30357f7c4a 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -78,7 +78,7 @@ class ArtMethod final { // constexpr, and ensure that the value is correct in art_method.cc. static constexpr uint32_t kRuntimeMethodDexMethodIndex = 0xFFFFFFFF; - ArtMethod() : access_flags_(0), dex_code_item_offset_(0), dex_method_index_(0), + ArtMethod() : access_flags_(0), dex_method_index_(0), method_index_(0), hotness_count_(0) { } ArtMethod(ArtMethod* src, PointerSize image_pointer_size) { @@ -419,15 +419,6 @@ class ArtMethod final { return MemberOffset(OFFSETOF_MEMBER(ArtMethod, imt_index_)); } - uint32_t GetCodeItemOffset() const { - return dex_code_item_offset_; - } - - void SetCodeItemOffset(uint32_t new_code_off) REQUIRES_SHARED(Locks::mutator_lock_) { - // Not called within a transaction. - dex_code_item_offset_ = new_code_off; - } - // Number of 32bit registers that would be required to hold all the arguments static size_t NumArgRegisters(const char* shorty); @@ -587,6 +578,15 @@ class ArtMethod final { return dex_method_index_ == kRuntimeMethodDexMethodIndex; } + bool HasCodeItem() REQUIRES_SHARED(Locks::mutator_lock_) { + return !IsRuntimeMethod() && !IsNative() && !IsProxyMethod() && !IsAbstract(); + } + + void SetCodeItem(const dex::CodeItem* code_item) REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK(HasCodeItem()); + SetDataPtrSize(code_item, kRuntimePointerSize); + } + // Is this a hand crafted method used for something like describing callee saves? bool IsCalleeSaveMethod() REQUIRES_SHARED(Locks::mutator_lock_); @@ -742,7 +742,6 @@ class ArtMethod final { DCHECK(IsImagePointerSize(kRuntimePointerSize)); visitor(this, &declaring_class_, "declaring_class_"); visitor(this, &access_flags_, "access_flags_"); - visitor(this, &dex_code_item_offset_, "dex_code_item_offset_"); visitor(this, &dex_method_index_, "dex_method_index_"); visitor(this, &method_index_, "method_index_"); visitor(this, &hotness_count_, "hotness_count_"); @@ -782,9 +781,6 @@ class ArtMethod final { /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */ - // Offset to the CodeItem. - uint32_t dex_code_item_offset_; - // Index into method_ids of the dex file associated with this method. uint32_t dex_method_index_; @@ -816,7 +812,8 @@ class ArtMethod final { // - conflict method: ImtConflictTable, // - abstract/interface method: the single-implementation if any, // - proxy method: the original interface method or constructor, - // - other methods: the profiling data. + // - other methods: during AOT the code item offset, at runtime a pointer + // to the code item. void* data_; // Method dispatch from quick compiled code invokes this pointer which may cause bridging into diff --git a/runtime/cha.cc b/runtime/cha.cc index a142723e31..c345af8232 100644 --- a/runtime/cha.cc +++ b/runtime/cha.cc @@ -543,7 +543,8 @@ void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> // Abstract method starts with single-implementation flag set and null // implementation method. method->SetHasSingleImplementation(true); - DCHECK(method->GetSingleImplementation(pointer_size) == nullptr); + DCHECK(!method->HasCodeItem()) << method->PrettyMethod(); + DCHECK(method->GetSingleImplementation(pointer_size) == nullptr) << method->PrettyMethod(); } // Default conflicting methods cannot be treated with single implementations, // as we need to call them (and not inline them) in case of ICCE. diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 09fa99b35a..c181c225aa 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2199,10 +2199,21 @@ bool ClassLinker::AddImageSpace( }, space->Begin(), image_pointer_size_); } - if (interpreter::CanRuntimeUseNterp()) { - // Set image methods' entry point that point to the interpreter bridge to the nterp entry point. + if (!runtime->IsAotCompiler()) { + bool can_use_nterp = interpreter::CanRuntimeUseNterp(); header.VisitPackedArtMethods([&](ArtMethod& method) REQUIRES_SHARED(Locks::mutator_lock_) { - ChangeInterpreterBridgeToNterp(&method, this); + // In the image, the `data` pointer field of the ArtMethod contains the code + // item offset. Change this to the actual pointer to the code item. + if (method.HasCodeItem()) { + const dex::CodeItem* code_item = method.GetDexFile()->GetCodeItem( + reinterpret_cast32<uint32_t>(method.GetDataPtrSize(image_pointer_size_))); + method.SetDataPtrSize(code_item, image_pointer_size_); + } + // Set image methods' entry point that point to the interpreter bridge to the + // nterp entry point. + if (can_use_nterp) { + ChangeInterpreterBridgeToNterp(&method, this); + } }, space->Begin(), image_pointer_size_); } @@ -3977,7 +3988,6 @@ void ClassLinker::LoadMethod(const DexFile& dex_file, ScopedAssertNoThreadSuspension ants("LoadMethod"); dst->SetDexMethodIndex(dex_method_idx); dst->SetDeclaringClass(klass.Get()); - dst->SetCodeItemOffset(method.GetCodeItemOffset()); // Get access flags from the DexFile and set hiddenapi runtime access flags. uint32_t access_flags = method.GetAccessFlags() | hiddenapi::CreateRuntimeFlags(method); @@ -4026,6 +4036,18 @@ void ClassLinker::LoadMethod(const DexFile& dex_file, if (klass->IsInterface() && dst->IsAbstract()) { dst->CalculateAndSetImtIndex(); } + if (dst->HasCodeItem()) { + DCHECK_NE(method.GetCodeItemOffset(), 0u); + if (Runtime::Current()->IsAotCompiler()) { + dst->SetDataPtrSize(reinterpret_cast32<void*>(method.GetCodeItemOffset()), image_pointer_size_); + } else { + dst->SetDataPtrSize(dst->GetDexFile()->GetCodeItem(method.GetCodeItemOffset()), + image_pointer_size_); + } + } else { + dst->SetDataPtrSize(nullptr, image_pointer_size_); + DCHECK_EQ(method.GetCodeItemOffset(), 0u); + } } void ClassLinker::AppendToBootClassPath(Thread* self, const DexFile* dex_file) { @@ -5304,10 +5326,6 @@ void ClassLinker::CreateProxyMethod(Handle<mirror::Class> klass, ArtMethod* prot const uint32_t kAddFlags = kAccFinal | kAccCompileDontBother; out->SetAccessFlags((out->GetAccessFlags() & ~kRemoveFlags) | kAddFlags); - // Clear the dex_code_item_offset_. It needs to be 0 since proxy methods have no CodeItems but the - // method they copy might (if it's a default method). - out->SetCodeItemOffset(0); - // Set the original interface method. out->SetDataPtrSize(prototype, image_pointer_size_); diff --git a/runtime/dex/dex_file_annotations.cc b/runtime/dex/dex_file_annotations.cc index 6261a93a5d..c149aeadf4 100644 --- a/runtime/dex/dex_file_annotations.cc +++ b/runtime/dex/dex_file_annotations.cc @@ -1745,7 +1745,7 @@ bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> int32_t GetLineNumFromPC(const DexFile* dex_file, ArtMethod* method, uint32_t rel_pc) { // For native method, lineno should be -2 to indicate it is native. Note that // "line number == -2" is how libcore tells from StackTraceElement. - if (method->GetCodeItemOffset() == 0) { + if (!method->HasCodeItem()) { return -2; } diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index e357b756c7..af63f68ca4 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -2872,8 +2872,10 @@ class ImageSpace::BootImageLoader { image_header.VisitPackedArtMethods([&](ArtMethod& method) REQUIRES_SHARED(Locks::mutator_lock_) { main_patch_object_visitor.PatchGcRoot(&method.DeclaringClassRoot()); - void** data_address = PointerAddress(&method, ArtMethod::DataOffset(kPointerSize)); - main_patch_object_visitor.PatchNativePointer(data_address); + if (!method.HasCodeItem()) { + void** data_address = PointerAddress(&method, ArtMethod::DataOffset(kPointerSize)); + main_patch_object_visitor.PatchNativePointer(data_address); + } void** entrypoint_address = PointerAddress(&method, ArtMethod::EntryPointFromQuickCompiledCodeOffset(kPointerSize)); main_patch_object_visitor.PatchNativePointer(entrypoint_address); diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index b5e52388b8..67644d66cd 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -445,7 +445,7 @@ void EnterInterpreterFromInvoke(Thread* self, method->ThrowInvocationTimeError(); return; } else { - DCHECK(method->IsNative()); + DCHECK(method->IsNative()) << method->PrettyMethod(); num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); if (!method->IsStatic()) { num_regs++; diff --git a/runtime/interpreter/mterp/arm64ng/main.S b/runtime/interpreter/mterp/arm64ng/main.S index b4b3283a54..51ebea164b 100644 --- a/runtime/interpreter/mterp/arm64ng/main.S +++ b/runtime/interpreter/mterp/arm64ng/main.S @@ -645,13 +645,10 @@ END \name ldp x0, x1, [sp], #16 .endm +// Input: x0 contains the ArtMethod // Output: x8 contains the code item .macro GET_CODE_ITEM - // TODO: Get code item in a better way. - stp x0, x1, [sp, #-16]! - bl NterpGetCodeItem - mov x8, x0 - ldp x0, x1, [sp], #16 + ldr x8, [x0, #ART_METHOD_DATA_OFFSET_64] .endm .macro DO_ENTRY_POINT_CHECK call_compiled_code @@ -1498,11 +1495,9 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl bl NterpGetShorty // Save shorty in callee-save xIBASE. mov xIBASE, x0 - mov x0, xINST - bl NterpGetCodeItem - mov xPC, x0 RESTORE_ALL_ARGUMENTS + ldr xPC, [xINST, #ART_METHOD_DATA_OFFSET_64] // Setup the stack for executing the method. SETUP_STACK_FRAME xPC, xREFS, xFP, CFI_REFS diff --git a/runtime/interpreter/mterp/x86_64ng/main.S b/runtime/interpreter/mterp/x86_64ng/main.S index 8966490602..cce72824e8 100644 --- a/runtime/interpreter/mterp/x86_64ng/main.S +++ b/runtime/interpreter/mterp/x86_64ng/main.S @@ -784,6 +784,9 @@ END_FUNCTION \name // - rPC: the new PC pointer to execute // - edi: number of arguments // - ecx: first dex register +// +// This helper expects: +// - rax to contain the code item .macro SETUP_STACK_FOR_INVOKE // We do the same stack overflow check as the compiler. See CanMethodUseNterp // in how we limit the maximum nterp frame size. @@ -969,13 +972,7 @@ END_FUNCTION \name cmpq %rax, ART_METHOD_QUICK_CODE_OFFSET_64(%rdi) jne VAR(call_compiled_code) - // TODO: Get code item in a better way and remove below - push %rdi - push %rsi - call SYMBOL(NterpGetCodeItem) - pop %rsi - pop %rdi - // TODO: Get code item in a better way and remove above + movq ART_METHOD_DATA_OFFSET_64(%rdi), %rax .endm // Uses r9 and r10 as temporary @@ -1389,9 +1386,6 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl call SYMBOL(NterpGetShorty) // Save shorty in callee-save rbp. movq %rax, %rbp - movq %rbx, %rdi - call SYMBOL(NterpGetCodeItem) - movq %rax, rPC // Restore xmm registers + alignment. movq 0(%rsp), %xmm0 @@ -1413,6 +1407,8 @@ OAT_ENTRY ExecuteNterpImpl, EndExecuteNterpImpl POP rdi // TODO: Get shorty in a better way and remove above + movq ART_METHOD_DATA_OFFSET_64(%rdi), rPC + // Setup the stack for executing the method. SETUP_STACK_FRAME rPC, rREFS, rFP, CFI_REFS diff --git a/tools/cpp-define-generator/art_method.def b/tools/cpp-define-generator/art_method.def index 75fbab0c28..097d4662e1 100644 --- a/tools/cpp-define-generator/art_method.def +++ b/tools/cpp-define-generator/art_method.def @@ -28,6 +28,10 @@ ASM_DEFINE(ART_METHOD_JNI_OFFSET_32, art::ArtMethod::EntryPointFromJniOffset(art::PointerSize::k32).Int32Value()) ASM_DEFINE(ART_METHOD_JNI_OFFSET_64, art::ArtMethod::EntryPointFromJniOffset(art::PointerSize::k64).Int32Value()) +ASM_DEFINE(ART_METHOD_DATA_OFFSET_32, + art::ArtMethod::DataOffset(art::PointerSize::k32).Int32Value()) +ASM_DEFINE(ART_METHOD_DATA_OFFSET_64, + art::ArtMethod::DataOffset(art::PointerSize::k64).Int32Value()) ASM_DEFINE(ART_METHOD_QUICK_CODE_OFFSET_32, art::ArtMethod::EntryPointFromQuickCompiledCodeOffset(art::PointerSize::k32).Int32Value()) ASM_DEFINE(ART_METHOD_QUICK_CODE_OFFSET_64, |