Make ART compile with GCC -O0 again.
Tidy up InstructionSetFeatures so that it has a type hierarchy dependent on
architecture.
Add to instruction_set_test to warn when InstructionSetFeatures don't agree
with ones from system properties, AT_HWCAP and /proc/cpuinfo.
Clean-up class linker entry point logic to not return entry points but to
test whether the passed code is the particular entrypoint. This works around
image trampolines that replicate entrypoints.
Bug: 17993736
Change-Id: I5f4b49e88c3b02a79f9bee04f83395146ed7be23
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 8fb1712..dfb03cd 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -507,8 +507,9 @@
ret_val->SetJ(value.GetJ());
}
-JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
- ShadowFrame& shadow_frame) {
+JValue EnterInterpreterFromEntryPoint(Thread* self, MethodHelper* mh,
+ const DexFile::CodeItem* code_item,
+ ShadowFrame* shadow_frame) {
DCHECK_EQ(self, Thread::Current());
bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
@@ -516,10 +517,10 @@
return JValue();
}
- return Execute(self, mh, code_item, shadow_frame, JValue());
+ return Execute(self, *mh, code_item, *shadow_frame, JValue());
}
-extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh,
+extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper* mh,
const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame, JValue* result) {
bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
@@ -529,10 +530,10 @@
}
self->PushShadowFrame(shadow_frame);
- DCHECK_EQ(shadow_frame->GetMethod(), mh.Get());
+ DCHECK_EQ(shadow_frame->GetMethod(), mh->Get());
// Ensure static methods are initialized.
- if (mh.Get()->IsStatic()) {
- mirror::Class* declaring_class = mh.Get()->GetDeclaringClass();
+ if (mh->Get()->IsStatic()) {
+ mirror::Class* declaring_class = mh->Get()->GetDeclaringClass();
if (UNLIKELY(!declaring_class->IsInitialized())) {
StackHandleScope<1> hs(self);
HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
@@ -546,15 +547,15 @@
}
}
- if (LIKELY(!mh.Get()->IsNative())) {
- result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ());
+ if (LIKELY(!mh->Get()->IsNative())) {
+ result->SetJ(Execute(self, *mh, code_item, *shadow_frame, JValue()).GetJ());
} else {
// We don't expect to be asked to interpret native code (which is entered via a JNI compiler
// generated stub) except during testing and image writing.
CHECK(!Runtime::Current()->IsStarted());
- Object* receiver = mh.Get()->IsStatic() ? nullptr : shadow_frame->GetVRegReference(0);
- uint32_t* args = shadow_frame->GetVRegArgs(mh.Get()->IsStatic() ? 0 : 1);
- UnstartedRuntimeJni(self, mh.Get(), receiver, args, result);
+ Object* receiver = mh->Get()->IsStatic() ? nullptr : shadow_frame->GetVRegReference(0);
+ uint32_t* args = shadow_frame->GetVRegArgs(mh->Get()->IsStatic() ? 0 : 1);
+ UnstartedRuntimeJni(self, mh->Get(), receiver, args, result);
}
self->PopShadowFrame();
diff --git a/runtime/interpreter/interpreter.h b/runtime/interpreter/interpreter.h
index 0750eb5..d327a71 100644
--- a/runtime/interpreter/interpreter.h
+++ b/runtime/interpreter/interpreter.h
@@ -42,19 +42,20 @@
JValue* ret_val)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-extern JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh,
- const DexFile::CodeItem* code_item,
- ShadowFrame& shadow_frame)
+extern JValue EnterInterpreterFromEntryPoint(Thread* self, MethodHelper* mh,
+ const DexFile::CodeItem* code_item,
+ ShadowFrame* shadow_frame)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh,
+
+} // namespace interpreter
+
+extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper* mh,
const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-} // namespace interpreter
-
-extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper& mh,
+extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, MethodHelper* mh,
const DexFile::CodeItem* code_item,
ShadowFrame* shadow_frame, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 52583ae..3ccdd03 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -506,7 +506,7 @@
exit(0); // Unreachable, keep GCC happy.
}
-static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
+static void UnstartedRuntimeInvoke(Thread* self, MethodHelper* mh,
const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
JValue* result, size_t arg_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -666,9 +666,9 @@
mh.Get()->GetEntryPointFromInterpreter() == artInterpreterToCompiledCodeBridge) {
LOG(FATAL) << "Attempt to call compiled code when -Xint: " << PrettyMethod(mh.Get());
}
- (mh.Get()->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result);
+ (mh.Get()->GetEntryPointFromInterpreter())(self, &mh, code_item, new_shadow_frame, result);
} else {
- UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, first_dest_reg);
+ UnstartedRuntimeInvoke(self, &mh, code_item, new_shadow_frame, result, first_dest_reg);
}
return !self->IsExceptionPending();
}
@@ -809,7 +809,7 @@
result->SetL(found);
}
-static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh,
+static void UnstartedRuntimeInvoke(Thread* self, MethodHelper* mh,
const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame,
JValue* result, size_t arg_offset) {
// In a runtime that's not started we intercept certain methods to avoid complicated dependency