Merge "Remove interpreter entrypoint in ArtMethod."
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 73e121f..93dd29d 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1417,9 +1417,6 @@
if (UNLIKELY(orig->IsAbstract())) {
copy->SetEntryPointFromQuickCompiledCodePtrSize(
GetOatAddress(quick_to_interpreter_bridge_offset_), target_ptr_size_);
- copy->SetEntryPointFromInterpreterPtrSize(
- reinterpret_cast<EntryPointFromInterpreter*>(const_cast<uint8_t*>(
- 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 @@
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<EntryPointFromInterpreter*>(
- const_cast<uint8_t*>(GetOatAddress(interpreter_code)));
- copy->SetEntryPointFromInterpreterPtrSize(interpreter_entrypoint, target_ptr_size_);
}
}
}
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index f324881..dce5206 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -548,10 +548,6 @@
os << " entryPointFromJni: "
<< reinterpret_cast<const void*>(
art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", ";
- os << " entryPointFromInterpreter: "
- << reinterpret_cast<const void*>(
- art_method->GetEntryPointFromInterpreterPtrSize(pointer_size))
- << ", ";
os << " entryPointFromQuickCompiledCode: "
<< reinterpret_cast<const void*>(
art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size))
@@ -631,10 +627,6 @@
os << " entryPointFromJni: "
<< reinterpret_cast<const void*>(
art_method->GetEntryPointFromJniPtrSize(pointer_size)) << ", ";
- os << " entryPointFromInterpreter: "
- << reinterpret_cast<const void*>(
- art_method->GetEntryPointFromInterpreterPtrSize(pointer_size))
- << ", ";
os << " entryPointFromQuickCompiledCode: "
<< reinterpret_cast<const void*>(
art_method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size))
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 3a155be..dbd1d23 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -651,8 +651,6 @@
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 4a1e2c4..e8c47d9 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -43,9 +43,6 @@
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 @@
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<EntryPointFromInterpreter*>(
- 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 @@
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 @@
// 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 10ed0f4..20d75f3 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -189,11 +189,11 @@
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 7972158..6f45dc8 100644
--- a/runtime/base/bit_utils.h
+++ b/runtime/base/bit_utils.h
@@ -137,7 +137,7 @@
}
template<int n, typename T>
-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 23c5942..0694227 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1195,13 +1195,9 @@
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 @@
// 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 @@
// 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 @@
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 762f061..5f91566 100644
--- a/runtime/fault_handler.cc
+++ b/runtime/fault_handler.cc
@@ -320,7 +320,7 @@
return false;
}
- ArtMethod* method_obj = 0;
+ ArtMethod* method_obj = nullptr;
uintptr_t return_pc = 0;
uintptr_t sp = 0;
@@ -331,7 +331,9 @@
// 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<kObjectAlignment>(method_obj)) {
+ DCHECK(IsAligned<sizeof(void*)>(ArtMethod::ObjectSize(sizeof(void*))))
+ << "ArtMethod is not pointer aligned";
+ if (method_obj == nullptr || !IsAligned<sizeof(void*)>(method_obj)) {
VLOG(signals) << "no method";
return false;
}
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index d37ddcb..abe9dc2 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -99,19 +99,6 @@
}
}
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 fa103b1..0980ea1 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -19,6 +19,7 @@
#include <cmath>
#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 @@
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<bool is_range, bool do_assignability_check>
static inline bool DoCallCommon(ArtMethod* called_method,
Thread* self,
@@ -660,28 +678,11 @@
// 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 bc9545b..fda97db 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -132,11 +132,7 @@
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 000ae8e..5706c4e 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
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 11c94db..6f3b0a3 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -857,7 +857,6 @@
<< " native=" << method->IsNative()
<< " entrypoints=" << method->GetEntryPointFromQuickCompiledCode()
<< "," << method->GetEntryPointFromJni()
- << "," << method->GetEntryPointFromInterpreter()
<< " next=" << *cur_quick_frame_;
}