diff options
-rw-r--r-- | compiler/dex/quick/mips/int_mips.cc | 4 | ||||
-rw-r--r-- | runtime/class_linker.cc | 18 | ||||
-rw-r--r-- | runtime/class_linker.h | 8 | ||||
-rw-r--r-- | runtime/mirror/art_method.cc | 20 | ||||
-rw-r--r-- | runtime/mirror/art_method.h | 5 |
5 files changed, 53 insertions, 2 deletions
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc index ea56989..95c1262 100644 --- a/compiler/dex/quick/mips/int_mips.cc +++ b/compiler/dex/quick/mips/int_mips.cc @@ -220,9 +220,9 @@ void MipsMir2Lir::GenSelectConst32(RegStorage left_op, RegStorage right_op, Cond int dest_reg_class) { // Implement as a branch-over. // TODO: Conditional move? - LoadConstant(rs_dest, false_val); // Favors false. - LIR* ne_branchover = OpCmpBranch(code, left_op, right_op, NULL); LoadConstant(rs_dest, true_val); + LIR* ne_branchover = OpCmpBranch(code, left_op, right_op, NULL); + LoadConstant(rs_dest, false_val); LIR* target_label = NewLIR0(kPseudoTargetLabel); ne_branchover->target = target_label; } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 3ab4ef8..f31e273 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2167,6 +2167,24 @@ const void* ClassLinker::GetPortableOatCodeFor(mirror::ArtMethod* method, return result; } +const void* ClassLinker::GetOatMethodQuickCodeFor(mirror::ArtMethod* method) { + if (method->IsNative() || method->IsAbstract() || method->IsProxyMethod()) { + return nullptr; + } + bool found; + OatFile::OatMethod oat_method = FindOatMethodFor(method, &found); + return found ? oat_method.GetQuickCode() : nullptr; +} + +const void* ClassLinker::GetOatMethodPortableCodeFor(mirror::ArtMethod* method) { + if (method->IsNative() || method->IsAbstract() || method->IsProxyMethod()) { + return nullptr; + } + bool found; + OatFile::OatMethod oat_method = FindOatMethodFor(method, &found); + return found ? oat_method.GetPortableCode() : nullptr; +} + const void* ClassLinker::GetQuickOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx) { bool found; diff --git a/runtime/class_linker.h b/runtime/class_linker.h index d2c9b40..9ae3862 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -344,6 +344,14 @@ class ClassLinker { const void* GetPortableOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // Get compiled code for a method, return null if no code + // exists. This is unlike Get..OatCodeFor which will return a bridge + // or interpreter entrypoint. + const void* GetOatMethodQuickCodeFor(mirror::ArtMethod* method) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + const void* GetOatMethodPortableCodeFor(mirror::ArtMethod* method) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + pid_t GetClassesLockOwner(); // For SignalCatcher. pid_t GetDexLockOwner(); // For SignalCatcher. diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc index 370bfb9..131f5d6 100644 --- a/runtime/mirror/art_method.cc +++ b/runtime/mirror/art_method.cc @@ -281,6 +281,19 @@ uint32_t ArtMethod::FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> excep return found_dex_pc; } +bool ArtMethod::IsEntrypointInterpreter() { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + const void* oat_quick_code = class_linker->GetOatMethodQuickCodeFor(this); + const void* oat_portable_code = class_linker->GetOatMethodPortableCodeFor(this); + if (!IsPortableCompiled()) { // Quick. + return oat_quick_code == nullptr || + oat_quick_code != GetEntryPointFromQuickCompiledCode(); + } else { // Portable. + return oat_portable_code == nullptr || + oat_portable_code != GetEntryPointFromPortableCompiledCode(); + } +} + void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty) { if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { @@ -318,6 +331,13 @@ void ArtMethod::Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* have_quick_code ? GetEntryPointFromQuickCompiledCode() : GetEntryPointFromPortableCompiledCode()); } + + // Ensure that we won't be accidentally calling quick/portable compiled code when -Xint. + if (kIsDebugBuild && Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly()) { + CHECK(IsEntrypointInterpreter()) + << "Don't call compiled code when -Xint " << PrettyMethod(this); + } + if (!IsPortableCompiled()) { #ifdef __LP64__ if (!IsStatic()) { diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index fa592c2..ebd5bd5 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -309,6 +309,11 @@ class MANAGED ArtMethod FINAL : public Object { void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // Returns true if the entrypoint points to the interpreter, as + // opposed to the compiled code, that is, this method will be + // interpretered on invocation. + bool IsEntrypointInterpreter() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + uint32_t GetQuickOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); uint32_t GetPortableOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void SetQuickOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); |