diff options
| author | 2013-07-09 10:56:11 +0200 | |
|---|---|---|
| committer | 2013-07-09 11:19:23 +0200 | |
| commit | 7d658cf06827d409d76686da1cd2b6acb5977885 (patch) | |
| tree | 0a0ee93edb8c28c859c47af7390fad05a9fc356a | |
| parent | 3dd9f76ff8fa99be9ff6b18354528c5def7b26f7 (diff) | |
Fix -Xint mode.
Bug: 9700950
Make ClassLinker::FixupStaticTrampolines updates entry point from compiled code
with interpreter entry point when interpreter mode is enabled.
Change-Id: Ie52ace8ea054ae7cb17442264dc62f68472409c6
| -rw-r--r-- | src/class_linker.cc | 49 | ||||
| -rw-r--r-- | src/jni_internal.cc | 16 |
2 files changed, 31 insertions, 34 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index 68d0fbbc55..159fbf728b 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -1560,6 +1560,18 @@ const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint32_t method_ return oat_class->GetOatMethod(oat_method_idx).GetCode(); } +// Returns true if the method must run with interpreter, false otherwise. +static bool NeedsInterpreter(const mirror::AbstractMethod* method, const void* code) { + if (code == NULL) { + // No code: need interpreter. + return true; + } + // If interpreter mode is enabled, every method (except native and proxy) must + // be run with interpreter. + return Runtime::Current()->GetInstrumentation()->InterpretOnly() && + !method->IsNative() && !method->IsProxyMethod(); +} + void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { ClassHelper kh(klass); const DexFile::ClassDef* dex_class_def = kh.GetClassDef(); @@ -1584,19 +1596,20 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { while (it.HasNextInstanceField()) { it.Next(); } - size_t method_index = 0; // Link the code of methods skipped by LinkCode - for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) { - mirror::AbstractMethod* method = klass->GetDirectMethod(i); - if (method->IsStatic()) { - const void* code = oat_class->GetOatMethod(method_index).GetCode(); - if (code == NULL) { - // No code? You must mean to go into the interpreter. - code = GetInterpreterEntryPoint(); - } - runtime->GetInstrumentation()->UpdateMethodsCode(method, code); + for (size_t method_index = 0; it.HasNextDirectMethod(); ++method_index, it.Next()) { + mirror::AbstractMethod* method = klass->GetDirectMethod(method_index); + if (!method->IsStatic()) { + // Only update static methods. + continue; + } + const void* code = oat_class->GetOatMethod(method_index).GetCode(); + const bool enter_interpreter = NeedsInterpreter(method, code); + if (enter_interpreter) { + // Use interpreter entry point. + code = GetInterpreterEntryPoint(); } - method_index++; + runtime->GetInstrumentation()->UpdateMethodsCode(method, code); } // Ignore virtual methods on the iterator. } @@ -1613,9 +1626,7 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat // Install entry point from interpreter. Runtime* runtime = Runtime::Current(); - bool enter_interpreter = method->GetEntryPointFromCompiledCode() == NULL || - (runtime->GetInstrumentation()->InterpretOnly() && - !method->IsNative() && !method->IsProxyMethod()); + bool enter_interpreter = NeedsInterpreter(method.get(), method->GetEntryPointFromCompiledCode()); if (enter_interpreter) { method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterEntry); } else { @@ -1629,7 +1640,12 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat if (method->IsStatic() && !method->IsConstructor()) { // For static methods excluding the class initializer, install the trampoline. + // It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines + // after initializing class (see ClassLinker::InitializeClass method). method->SetEntryPointFromCompiledCode(GetResolutionTrampoline(runtime->GetClassLinker())); + } else if (enter_interpreter) { + // Set entry point from compiled code if there's no code or in interpreter only mode. + method->SetEntryPointFromCompiledCode(GetInterpreterEntryPoint()); } if (method->IsNative()) { @@ -1637,11 +1653,6 @@ static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::Oat method->UnregisterNative(Thread::Current()); } - if (enter_interpreter) { - // Set entry point from compiled code if there's no code or in interpreter only mode. - method->SetEntryPointFromCompiledCode(GetInterpreterEntryPoint()); - } - // Allow instrumentation its chance to hijack code. runtime->GetInstrumentation()->UpdateMethodsCode(method.get(), method->GetEntryPointFromCompiledCode()); diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 5ea1f77172..cbdf3cde4d 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -135,21 +135,7 @@ void InvokeWithArgArray(const ScopedObjectAccess& soa, AbstractMethod* method, if (UNLIKELY(soa.Env()->check_jni)) { CheckMethodArguments(method, args); } - // Check interpreter only mode for methods invoked through JNI. - // TODO: Check that this catches all remaining paths to invoke. - // TODO: Move check up a level to avoid building arg array and then shadow frame? - if (Runtime::Current()->GetInstrumentation()->InterpretOnly()) { - Object* receiver = method->IsStatic() ? NULL : reinterpret_cast<Object*>(args[0]); - if (!method->IsStatic()) { - args++; - } - ManagedStack fragment; - soa.Self()->PushManagedStackFragment(&fragment); - art::interpreter::EnterInterpreterFromInvoke(soa.Self(), method, receiver, args, result); - soa.Self()->PopManagedStackFragment(fragment); - } else { - method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type); - } + method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type); } static JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj, |