From fa2c054b28d4b540c1b3651401a7a091282a015f Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Wed, 1 Jul 2015 14:32:54 +0100 Subject: [PATCH] Remove interpreter entrypoint in ArtMethod. Saves 4/8 bytes for each ArtMethod. Change-Id: I110ecdddf8516b0759a31fa157609643e6d60b15 --- compiler/image_writer.cc | 13 ---------- imgdiag/imgdiag.cc | 8 ------ patchoat/patchoat.cc | 2 -- runtime/art_method.h | 29 ---------------------- runtime/asm_support.h | 4 +-- runtime/base/bit_utils.h | 2 +- runtime/class_linker.cc | 19 +++----------- runtime/fault_handler.cc | 6 +++-- runtime/instrumentation.cc | 13 ---------- runtime/interpreter/interpreter_common.cc | 41 ++++++++++++++++--------------- runtime/jit/jit.cc | 6 +---- runtime/oat.h | 2 +- runtime/stack.cc | 1 - 13 files changed, 33 insertions(+), 113 deletions(-) diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 73e121f1c..93dd29d95 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -1417,9 +1417,6 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig, ArtMethod* copy) { if (UNLIKELY(orig->IsAbstract())) { copy->SetEntryPointFromQuickCompiledCodePtrSize( GetOatAddress(quick_to_interpreter_bridge_offset_), target_ptr_size_); - copy->SetEntryPointFromInterpreterPtrSize( - reinterpret_cast(const_cast( - GetOatAddress(interpreter_to_interpreter_bridge_offset_))), target_ptr_size_); } else { bool quick_is_interpreted; const uint8_t* quick_code = GetQuickCode(orig, &quick_is_interpreted); @@ -1432,16 +1429,6 @@ void ImageWriter::CopyAndFixupMethod(ArtMethod* orig, ArtMethod* copy) { copy->SetEntryPointFromJniPtrSize( GetOatAddress(jni_dlsym_lookup_offset_), target_ptr_size_); } - - // Interpreter entrypoint: - // Set the interpreter entrypoint depending on whether there is compiled code or not. - uint32_t interpreter_code = (quick_is_interpreted) - ? interpreter_to_interpreter_bridge_offset_ - : interpreter_to_compiled_code_bridge_offset_; - EntryPointFromInterpreter* interpreter_entrypoint = - reinterpret_cast( - const_cast(GetOatAddress(interpreter_code))); - copy->SetEntryPointFromInterpreterPtrSize(interpreter_entrypoint, target_ptr_size_); } } } diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc index f32488133..dce520660 100644 --- a/imgdiag/imgdiag.cc +++ b/imgdiag/imgdiag.cc @@ -548,10 +548,6 @@ class ImgDiagDumper { os << " entryPointFromJni: " << reinterpret_cast( art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", "; - os << " entryPointFromInterpreter: " - << reinterpret_cast( - art_method->GetEntryPointFromInterpreterPtrSize(pointer_size)) - << ", "; os << " entryPointFromQuickCompiledCode: " << reinterpret_cast( art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)) @@ -631,10 +627,6 @@ class ImgDiagDumper { os << " entryPointFromJni: " << reinterpret_cast( art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", "; - os << " entryPointFromInterpreter: " - << reinterpret_cast( - art_method->GetEntryPointFromInterpreterPtrSize(pointer_size)) - << ", "; os << " entryPointFromQuickCompiledCode: " << reinterpret_cast( art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)) diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 04017273a..687ebe817 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -649,8 +649,6 @@ void PatchOat::FixupMethod(ArtMethod* object, ArtMethod* copy) { copy->SetDexCacheResolvedTypes(RelocatedAddressOfPointer(object->GetDexCacheResolvedTypes())); copy->SetEntryPointFromQuickCompiledCodePtrSize(RelocatedAddressOfPointer( object->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size)), pointer_size); - copy->SetEntryPointFromInterpreterPtrSize(RelocatedAddressOfPointer( - object->GetEntryPointFromInterpreterPtrSize(pointer_size)), pointer_size); copy->SetEntryPointFromJniPtrSize(RelocatedAddressOfPointer( object->GetEntryPointFromJniPtrSize(pointer_size)), pointer_size); } diff --git a/runtime/art_method.h b/runtime/art_method.h index 4a1e2c453..e8c47d94b 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -43,9 +43,6 @@ class Class; class PointerArray; } // namespace mirror -typedef void (EntryPointFromInterpreter)(Thread* self, const DexFile::CodeItem* code_item, - ShadowFrame* shadow_frame, JValue* result); - class ArtMethod FINAL { public: ArtMethod() : access_flags_(0), dex_code_item_offset_(0), dex_method_index_(0), @@ -272,23 +269,6 @@ class ArtMethod FINAL { void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - EntryPointFromInterpreter* GetEntryPointFromInterpreter() { - return GetEntryPointFromInterpreterPtrSize(sizeof(void*)); - } - EntryPointFromInterpreter* GetEntryPointFromInterpreterPtrSize(size_t pointer_size) { - return GetEntryPoint( - EntryPointFromInterpreterOffset(pointer_size), pointer_size); - } - - void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter) { - SetEntryPointFromInterpreterPtrSize(entry_point_from_interpreter, sizeof(void*)); - } - void SetEntryPointFromInterpreterPtrSize(EntryPointFromInterpreter* entry_point_from_interpreter, - size_t pointer_size) { - SetEntryPoint(EntryPointFromInterpreterOffset(pointer_size), entry_point_from_interpreter, - pointer_size); - } - const void* GetEntryPointFromQuickCompiledCode() { return GetEntryPointFromQuickCompiledCodePtrSize(sizeof(void*)); } @@ -398,11 +378,6 @@ class ArtMethod FINAL { void UnregisterNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - static MemberOffset EntryPointFromInterpreterOffset(size_t pointer_size) { - return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER( - PtrSizedFields, entry_point_from_interpreter_) / sizeof(void*) * pointer_size); - } - static MemberOffset EntryPointFromJniOffset(size_t pointer_size) { return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER( PtrSizedFields, entry_point_from_jni_) / sizeof(void*) * pointer_size); @@ -573,10 +548,6 @@ class ArtMethod FINAL { // PACKED(4) is necessary for the correctness of // RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size). struct PACKED(4) PtrSizedFields { - // Method dispatch from the interpreter invokes this pointer which may cause a bridge into - // compiled code. - void* entry_point_from_interpreter_; - // Pointer to JNI function registered to this method, or a function to resolve the JNI function. void* entry_point_from_jni_; diff --git a/runtime/asm_support.h b/runtime/asm_support.h index 10ed0f4df..20d75f37b 100644 --- a/runtime/asm_support.h +++ b/runtime/asm_support.h @@ -189,11 +189,11 @@ ADD_TEST_EQ(ART_METHOD_DEX_CACHE_METHODS_OFFSET, ADD_TEST_EQ(ART_METHOD_DEX_CACHE_TYPES_OFFSET, art::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()) -#define ART_METHOD_QUICK_CODE_OFFSET_32 36 +#define ART_METHOD_QUICK_CODE_OFFSET_32 32 ADD_TEST_EQ(ART_METHOD_QUICK_CODE_OFFSET_32, art::ArtMethod::EntryPointFromQuickCompiledCodeOffset(4).Int32Value()) -#define ART_METHOD_QUICK_CODE_OFFSET_64 48 +#define ART_METHOD_QUICK_CODE_OFFSET_64 40 ADD_TEST_EQ(ART_METHOD_QUICK_CODE_OFFSET_64, art::ArtMethod::EntryPointFromQuickCompiledCodeOffset(8).Int32Value()) diff --git a/runtime/base/bit_utils.h b/runtime/base/bit_utils.h index 797215822..6f45dc820 100644 --- a/runtime/base/bit_utils.h +++ b/runtime/base/bit_utils.h @@ -137,7 +137,7 @@ static inline T* AlignUp(T* x, uintptr_t n) { } template -static inline bool IsAligned(T x) { +static constexpr bool IsAligned(T x) { static_assert((n & (n - 1)) == 0, "n is not a power of two"); return (x & (n - 1)) == 0; } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 23c59422c..06942275c 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1195,13 +1195,9 @@ void ClassLinker::InitFromImage() { if (kIsDebugBuild && !method->IsRuntimeMethod()) { CHECK(method->GetDeclaringClass() != nullptr); } - if (!method->IsNative()) { - method->SetEntryPointFromInterpreterPtrSize( - artInterpreterToInterpreterBridge, image_pointer_size_); - if (!method->IsRuntimeMethod() && method != runtime->GetResolutionMethod()) { - method->SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), - image_pointer_size_); - } + if (!method->IsNative() && !method->IsRuntimeMethod() && !method->IsResolutionMethod()) { + method->SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), + image_pointer_size_); } } } @@ -2206,11 +2202,6 @@ void ClassLinker::LinkCode(ArtMethod* method, const OatFile::OatClass* oat_class // Install entry point from interpreter. bool enter_interpreter = NeedsInterpreter(method, method->GetEntryPointFromQuickCompiledCode()); - if (enter_interpreter && !method->IsNative()) { - method->SetEntryPointFromInterpreter(artInterpreterToInterpreterBridge); - } else { - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); - } if (method->IsAbstract()) { method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge()); @@ -3516,7 +3507,6 @@ void ClassLinker::CreateProxyMethod(Handle klass, ArtMethod* prot // At runtime the method looks like a reference and argument saving method, clone the code // related parameters from this method. out->SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler()); - out->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); } void ClassLinker::CheckProxyMethod(ArtMethod* method, ArtMethod* prototype) const { @@ -5647,18 +5637,15 @@ void ClassLinker::SetEntryPointsToCompiledCode(ArtMethod* method, const void* method_code) const { OatFile::OatMethod oat_method = CreateOatMethod(method_code); oat_method.LinkMethod(method); - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); } void ClassLinker::SetEntryPointsToInterpreter(ArtMethod* method) const { if (!method->IsNative()) { - method->SetEntryPointFromInterpreter(artInterpreterToInterpreterBridge); method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge()); } else { const void* quick_method_code = GetQuickGenericJniStub(); OatFile::OatMethod oat_method = CreateOatMethod(quick_method_code); oat_method.LinkMethod(method); - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); } } diff --git a/runtime/fault_handler.cc b/runtime/fault_handler.cc index 762f061ce..5f915663c 100644 --- a/runtime/fault_handler.cc +++ b/runtime/fault_handler.cc @@ -320,7 +320,7 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che return false; } - ArtMethod* method_obj = 0; + ArtMethod* method_obj = nullptr; uintptr_t return_pc = 0; uintptr_t sp = 0; @@ -331,7 +331,9 @@ bool FaultManager::IsInGeneratedCode(siginfo_t* siginfo, void* context, bool che // If we don't have a potential method, we're outta here. VLOG(signals) << "potential method: " << method_obj; // TODO: Check linear alloc and image. - if (method_obj == 0 || !IsAligned(method_obj)) { + DCHECK(IsAligned(ArtMethod::ObjectSize(sizeof(void*)))) + << "ArtMethod is not pointer aligned"; + if (method_obj == nullptr || !IsAligned(method_obj)) { VLOG(signals) << "no method"; return false; } diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index d37ddcb88..abe9dc24e 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -99,19 +99,6 @@ static void UpdateEntrypoints(ArtMethod* method, const void* quick_code) } } method->SetEntryPointFromQuickCompiledCode(quick_code); - if (!method->IsResolutionMethod()) { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - if (class_linker->IsQuickToInterpreterBridge(quick_code) || - (class_linker->IsQuickResolutionStub(quick_code) && - Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly() && - !method->IsNative() && !method->IsProxyMethod())) { - DCHECK(!method->IsNative()) << PrettyMethod(method); - DCHECK(!method->IsProxyMethod()) << PrettyMethod(method); - method->SetEntryPointFromInterpreter(art::artInterpreterToInterpreterBridge); - } else { - method->SetEntryPointFromInterpreter(art::artInterpreterToCompiledCodeBridge); - } - } } void Instrumentation::InstallStubsForMethod(ArtMethod* method) { diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index fa103b15d..0980ea1bc 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -19,6 +19,7 @@ #include #include "debugger.h" +#include "entrypoints/runtime_asm_entrypoints.h" #include "mirror/array-inl.h" #include "unstarted_runtime.h" #include "verifier/method_verifier.h" @@ -490,6 +491,23 @@ static inline bool DoCallCommon(ArtMethod* called_method, uint32_t arg[Instruction::kMaxVarArgRegs], uint32_t vregC) ALWAYS_INLINE; +SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) +static inline bool NeedsInterpreter(Thread* self, ShadowFrame* new_shadow_frame) ALWAYS_INLINE; + +static inline bool NeedsInterpreter(Thread* self, ShadowFrame* new_shadow_frame) { + ArtMethod* target = new_shadow_frame->GetMethod(); + if (UNLIKELY(target->IsNative() || target->IsProxyMethod())) { + return false; + } + Runtime* runtime = Runtime::Current(); + ClassLinker* class_linker = runtime->GetClassLinker(); + return runtime->GetInstrumentation()->IsForcedInterpretOnly() || + // Doing this check avoids doing compiled/interpreter transitions. + class_linker->IsQuickToInterpreterBridge(target->GetEntryPointFromQuickCompiledCode()) || + // Force the use of interpreter when it is required by the debugger. + Dbg::IsForcedInterpreterNeededForCalling(self, target); +} + template static inline bool DoCallCommon(ArtMethod* called_method, Thread* self, @@ -660,28 +678,11 @@ static inline bool DoCallCommon(ArtMethod* called_method, // Do the call now. if (LIKELY(Runtime::Current()->IsStarted())) { - if (kIsDebugBuild && new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter() == nullptr) { - LOG(FATAL) << "Attempt to invoke non-executable method: " - << PrettyMethod(new_shadow_frame->GetMethod()); - UNREACHABLE(); - } - if (kIsDebugBuild && Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly() && - !new_shadow_frame->GetMethod()->IsNative() && - !new_shadow_frame->GetMethod()->IsProxyMethod() && - new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter() - == artInterpreterToCompiledCodeBridge) { - LOG(FATAL) << "Attempt to call compiled code when -Xint: " - << PrettyMethod(new_shadow_frame->GetMethod()); - UNREACHABLE(); - } - // Force the use of interpreter when it is required by the debugger. - EntryPointFromInterpreter* entry; - if (UNLIKELY(Dbg::IsForcedInterpreterNeededForCalling(self, new_shadow_frame->GetMethod()))) { - entry = &art::artInterpreterToInterpreterBridge; + if (NeedsInterpreter(self, new_shadow_frame)) { + artInterpreterToInterpreterBridge(self, code_item, new_shadow_frame, result); } else { - entry = new_shadow_frame->GetMethod()->GetEntryPointFromInterpreter(); + artInterpreterToCompiledCodeBridge(self, code_item, new_shadow_frame, result); } - entry(self, code_item, new_shadow_frame, result); } else { UnstartedRuntime::Invoke(self, code_item, new_shadow_frame, result, first_dest_reg); } diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index bc9545b5a..fda97db5e 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -132,11 +132,7 @@ bool Jit::CompileMethod(ArtMethod* method, Thread* self) { VLOG(jit) << "JIT not compiling " << PrettyMethod(method) << " due to breakpoint"; return false; } - const bool result = jit_compile_method_(jit_compiler_handle_, method, self); - if (result) { - method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge); - } - return result; + return jit_compile_method_(jit_compiler_handle_, method, self); } void Jit::CreateThreadPool() { diff --git a/runtime/oat.h b/runtime/oat.h index 000ae8ed5..5706c4e68 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,7 +32,7 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - static constexpr uint8_t kOatVersion[] = { '0', '6', '4', '\0' }; + static constexpr uint8_t kOatVersion[] = { '0', '6', '5', '\0' }; static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/stack.cc b/runtime/stack.cc index 11c94dbbb..6f3b0a3bf 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -857,7 +857,6 @@ void StackVisitor::WalkStack(bool include_transitions) { << " native=" << method->IsNative() << " entrypoints=" << method->GetEntryPointFromQuickCompiledCode() << "," << method->GetEntryPointFromJni() - << "," << method->GetEntryPointFromInterpreter() << " next=" << *cur_quick_frame_; } -- 2.11.0