diff options
76 files changed, 1292 insertions, 747 deletions
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk index dc5385309a..02bce411b4 100644 --- a/build/Android.common_build.mk +++ b/build/Android.common_build.mk @@ -118,8 +118,7 @@ endif ART_TARGET_CLANG_arm := false ART_TARGET_CLANG_arm64 := ART_TARGET_CLANG_mips := -# b/25928358, illegal instruction on mips64r6 with -O0 -ART_TARGET_CLANG_mips64 := false +ART_TARGET_CLANG_mips64 := ART_TARGET_CLANG_x86 := ART_TARGET_CLANG_x86_64 := diff --git a/cmdline/cmdline_parser_test.cc b/cmdline/cmdline_parser_test.cc index dc2c9c954a..81b854e9c3 100644 --- a/cmdline/cmdline_parser_test.cc +++ b/cmdline/cmdline_parser_test.cc @@ -291,6 +291,13 @@ TEST_F(CmdlineParserTest, TestLogVerbosity) { } { + const char* log_args = "-verbose:collector"; + LogVerbosity log_verbosity = LogVerbosity(); + log_verbosity.collector = true; + EXPECT_SINGLE_PARSE_VALUE(log_verbosity, log_args, M::Verbose); + } + + { const char* log_args = "-verbose:oat"; LogVerbosity log_verbosity = LogVerbosity(); log_verbosity.oat = true; diff --git a/cmdline/cmdline_types.h b/cmdline/cmdline_types.h index 740199d541..c0a00cce70 100644 --- a/cmdline/cmdline_types.h +++ b/cmdline/cmdline_types.h @@ -584,6 +584,8 @@ struct CmdlineType<LogVerbosity> : CmdlineTypeParser<LogVerbosity> { for (size_t j = 0; j < verbose_options.size(); ++j) { if (verbose_options[j] == "class") { log_verbosity.class_linker = true; + } else if (verbose_options[j] == "collector") { + log_verbosity.collector = true; } else if (verbose_options[j] == "compiler") { log_verbosity.compiler = true; } else if (verbose_options[j] == "deopt") { diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 670fe94988..a51dd3209b 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -378,7 +378,6 @@ CompilerDriver::CompilerDriver( compiled_method_storage_(swap_fd), profile_compilation_info_(profile_compilation_info) { DCHECK(compiler_options_ != nullptr); - DCHECK(verification_results_ != nullptr); DCHECK(method_inliner_map_ != nullptr); compiler_->Init(); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 5e35cbb309..d8f23f7a73 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -138,6 +138,7 @@ class CompilerDriver { REQUIRES(!compiled_methods_lock_, !compiled_classes_lock_); VerificationResults* GetVerificationResults() const { + DCHECK(Runtime::Current()->IsAotCompiler()); return verification_results_; } diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index a8de86d059..d50528edee 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -124,7 +124,10 @@ bool ImageWriter::PrepareImageAddressSpace() { { ScopedObjectAccess soa(Thread::Current()); PruneNonImageClasses(); // Remove junk - ComputeLazyFieldsForImageClasses(); // Add useful information + if (!compile_app_image_) { + // Avoid for app image since this may increase RAM and image size. + ComputeLazyFieldsForImageClasses(); // Add useful information + } } heap->CollectGarbage(false); // Remove garbage. @@ -735,20 +738,20 @@ bool ImageWriter::IsBootClassLoaderNonImageClass(mirror::Class* klass) { return IsBootClassLoaderClass(klass) && !IsInBootImage(klass); } -bool ImageWriter::ContainsBootClassLoaderNonImageClass(mirror::Class* klass) { +bool ImageWriter::PruneAppImageClass(mirror::Class* klass) { bool early_exit = false; std::unordered_set<mirror::Class*> visited; - return ContainsBootClassLoaderNonImageClassInternal(klass, &early_exit, &visited); + return PruneAppImageClassInternal(klass, &early_exit, &visited); } -bool ImageWriter::ContainsBootClassLoaderNonImageClassInternal( +bool ImageWriter::PruneAppImageClassInternal( mirror::Class* klass, bool* early_exit, std::unordered_set<mirror::Class*>* visited) { DCHECK(early_exit != nullptr); DCHECK(visited != nullptr); DCHECK(compile_app_image_); - if (klass == nullptr) { + if (klass == nullptr || IsInBootImage(klass)) { return false; } auto found = prune_class_memo_.find(klass); @@ -762,7 +765,11 @@ bool ImageWriter::ContainsBootClassLoaderNonImageClassInternal( return false; } visited->emplace(klass); - bool result = IsBootClassLoaderNonImageClass(klass); + bool result = IsBootClassLoaderClass(klass); + std::string temp; + // Prune if not an image class, this handles any broken sets of image classes such as having a + // class in the set but not it's superclass. + result = result || !compiler_driver_.IsImageClass(klass->GetDescriptor(&temp)); bool my_early_exit = false; // Only for ourselves, ignore caller. // Remove classes that failed to verify since we don't want to have java.lang.VerifyError in the // app image. @@ -775,17 +782,15 @@ bool ImageWriter::ContainsBootClassLoaderNonImageClassInternal( // Check interfaces since these wont be visited through VisitReferences.) mirror::IfTable* if_table = klass->GetIfTable(); for (size_t i = 0, num_interfaces = klass->GetIfTableCount(); i < num_interfaces; ++i) { - result = result || ContainsBootClassLoaderNonImageClassInternal( - if_table->GetInterface(i), - &my_early_exit, - visited); + result = result || PruneAppImageClassInternal(if_table->GetInterface(i), + &my_early_exit, + visited); } } if (klass->IsObjectArrayClass()) { - result = result || ContainsBootClassLoaderNonImageClassInternal( - klass->GetComponentType(), - &my_early_exit, - visited); + result = result || PruneAppImageClassInternal(klass->GetComponentType(), + &my_early_exit, + visited); } // Check static fields and their classes. size_t num_static_fields = klass->NumReferenceStaticFields(); @@ -798,27 +803,22 @@ bool ImageWriter::ContainsBootClassLoaderNonImageClassInternal( mirror::Object* ref = klass->GetFieldObject<mirror::Object>(field_offset); if (ref != nullptr) { if (ref->IsClass()) { - result = result || - ContainsBootClassLoaderNonImageClassInternal( - ref->AsClass(), - &my_early_exit, - visited); + result = result || PruneAppImageClassInternal(ref->AsClass(), + &my_early_exit, + visited); + } else { + result = result || PruneAppImageClassInternal(ref->GetClass(), + &my_early_exit, + visited); } - result = result || - ContainsBootClassLoaderNonImageClassInternal( - ref->GetClass(), - &my_early_exit, - visited); } field_offset = MemberOffset(field_offset.Uint32Value() + sizeof(mirror::HeapReference<mirror::Object>)); } } - result = result || - ContainsBootClassLoaderNonImageClassInternal( - klass->GetSuperClass(), - &my_early_exit, - visited); + result = result || PruneAppImageClassInternal(klass->GetSuperClass(), + &my_early_exit, + visited); // Erase the element we stored earlier since we are exiting the function. auto it = visited->find(klass); DCHECK(it != visited->end()); @@ -837,15 +837,21 @@ bool ImageWriter::KeepClass(Class* klass) { if (klass == nullptr) { return false; } + if (compile_app_image_ && Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass)) { + // Already in boot image, return true. + return true; + } + std::string temp; + if (!compiler_driver_.IsImageClass(klass->GetDescriptor(&temp))) { + return false; + } if (compile_app_image_) { // For app images, we need to prune boot loader classes that are not in the boot image since // these may have already been loaded when the app image is loaded. // Keep classes in the boot image space since we don't want to re-resolve these. - return Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass) || - !ContainsBootClassLoaderNonImageClass(klass); + return !PruneAppImageClass(klass); } - std::string temp; - return compiler_driver_.IsImageClass(klass->GetDescriptor(&temp)); + return true; } class NonImageClassesVisitor : public ClassVisitor { @@ -873,6 +879,7 @@ void ImageWriter::PruneNonImageClasses() { class_linker->VisitClasses(&visitor); // Remove the undesired classes from the class roots. + VLOG(compiler) << "Pruning " << visitor.classes_to_prune_.size() << " classes"; for (mirror::Class* klass : visitor.classes_to_prune_) { std::string temp; const char* name = klass->GetDescriptor(&temp); @@ -891,10 +898,10 @@ void ImageWriter::PruneNonImageClasses() { ReaderMutexLock mu(self, *Locks::classlinker_classes_lock_); // For ClassInClassTable ReaderMutexLock mu2(self, *class_linker->DexLock()); for (const ClassLinker::DexCacheData& data : class_linker->GetDexCachesData()) { - mirror::DexCache* dex_cache = down_cast<mirror::DexCache*>(self->DecodeJObject(data.weak_root)); - if (dex_cache == nullptr) { + if (self->IsJWeakCleared(data.weak_root)) { continue; } + mirror::DexCache* dex_cache = self->DecodeJObject(data.weak_root)->AsDexCache(); for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) { Class* klass = dex_cache->GetResolvedType(i); if (klass != nullptr && !KeepClass(klass)) { @@ -2296,6 +2303,8 @@ ImageWriter::ImageWriter( image_info_map_.emplace(oat_filename, ImageInfo()); } std::fill_n(image_methods_, arraysize(image_methods_), nullptr); + CHECK_EQ(compile_app_image, !Runtime::Current()->GetHeap()->GetBootImageSpaces().empty()) + << "Compiling a boot image should occur iff there are no boot image spaces loaded"; } ImageWriter::ImageInfo::ImageInfo() diff --git a/compiler/image_writer.h b/compiler/image_writer.h index b227c44519..ee204c5081 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -410,16 +410,18 @@ class ImageWriter FINAL { // Return true if klass is loaded by the boot class loader but not in the boot image. bool IsBootClassLoaderNonImageClass(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_); - // Return true if klass depends on a boot class loader non image class live. We want to prune - // these classes since we do not want any boot class loader classes in the image. This means that + // Return true if klass depends on a boot class loader non image class. We want to prune these + // classes since we do not want any boot class loader classes in the image. This means that // we also cannot have any classes which refer to these boot class loader non image classes. - bool ContainsBootClassLoaderNonImageClass(mirror::Class* klass) + // PruneAppImageClass also prunes if klass depends on a non-image class according to the compiler + // driver. + bool PruneAppImageClass(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_); // early_exit is true if we had a cyclic dependency anywhere down the chain. - bool ContainsBootClassLoaderNonImageClassInternal(mirror::Class* klass, - bool* early_exit, - std::unordered_set<mirror::Class*>* visited) + bool PruneAppImageClassInternal(mirror::Class* klass, + bool* early_exit, + std::unordered_set<mirror::Class*>* visited) SHARED_REQUIRES(Locks::mutator_lock_); static Bin BinTypeForNativeRelocationType(NativeObjectRelocationType type); diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 3fe786141e..909d6822a8 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -23,10 +23,7 @@ #include "base/time_utils.h" #include "base/timing_logger.h" #include "base/unix_file/fd_file.h" -#include "compiler_callbacks.h" #include "debug/elf_debug_writer.h" -#include "dex/pass_manager.h" -#include "dex/quick_compiler_callbacks.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "jit/debugger_interface.h" @@ -36,7 +33,6 @@ #include "oat_quick_method_header.h" #include "object_lock.h" #include "thread_list.h" -#include "verifier/method_verifier-inl.h" namespace art { namespace jit { @@ -45,11 +41,10 @@ JitCompiler* JitCompiler::Create() { return new JitCompiler(); } -extern "C" void* jit_load(CompilerCallbacks** callbacks, bool* generate_debug_info) { +extern "C" void* jit_load(bool* generate_debug_info) { VLOG(jit) << "loading jit compiler"; auto* const jit_compiler = JitCompiler::Create(); CHECK(jit_compiler != nullptr); - *callbacks = jit_compiler->GetCompilerCallbacks(); *generate_debug_info = jit_compiler->GetCompilerOptions()->GetGenerateDebugInfo(); VLOG(jit) << "Done loading jit compiler"; return jit_compiler; @@ -151,14 +146,10 @@ JitCompiler::JitCompiler() : total_time_(0) { instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines()); } cumulative_logger_.reset(new CumulativeLogger("jit times")); - verification_results_.reset(new VerificationResults(compiler_options_.get())); method_inliner_map_.reset(new DexFileToMethodInlinerMap); - callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), - method_inliner_map_.get(), - CompilerCallbacks::CallbackMode::kCompileApp)); compiler_driver_.reset(new CompilerDriver( compiler_options_.get(), - verification_results_.get(), + /* verification_results */ nullptr, method_inliner_map_.get(), Compiler::kOptimizing, instruction_set, @@ -251,9 +242,5 @@ bool JitCompiler::CompileMethod(Thread* self, ArtMethod* method, bool osr) { return success; } -CompilerCallbacks* JitCompiler::GetCompilerCallbacks() const { - return callbacks_.get(); -} - } // namespace jit } // namespace art diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index f39699e0a7..02a1acc240 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -758,8 +758,9 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, if (!method->GetDeclaringClass()->IsVerified()) { uint16_t class_def_idx = method->GetDeclaringClass()->GetDexClassDefIndex(); - if (!compiler_driver_->IsMethodVerifiedWithoutFailures( - method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) { + if (Runtime::Current()->UseJit() || + !compiler_driver_->IsMethodVerifiedWithoutFailures( + method->GetDexMethodIndex(), class_def_idx, *method->GetDexFile())) { VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file) << " couldn't be verified, so it cannot be inlined"; return false; @@ -982,16 +983,16 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache())); DexCompilationUnit dex_compilation_unit( - nullptr, - caller_compilation_unit_.GetClassLoader(), - class_linker, - callee_dex_file, - code_item, - resolved_method->GetDeclaringClass()->GetDexClassDefIndex(), - method_index, - resolved_method->GetAccessFlags(), - compiler_driver_->GetVerifiedMethod(&callee_dex_file, method_index), - dex_cache); + nullptr, + caller_compilation_unit_.GetClassLoader(), + class_linker, + callee_dex_file, + code_item, + resolved_method->GetDeclaringClass()->GetDexClassDefIndex(), + method_index, + resolved_method->GetAccessFlags(), + /* verified_method */ nullptr, + dex_cache); bool requires_ctor_barrier = false; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index ae638dfd0b..b1891c979e 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -651,7 +651,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, DexCompilationUnit dex_compilation_unit( nullptr, class_loader, Runtime::Current()->GetClassLinker(), dex_file, code_item, class_def_idx, method_idx, access_flags, - compiler_driver->GetVerifiedMethod(&dex_file, method_idx), dex_cache); + nullptr, dex_cache); bool requires_barrier = dex_compilation_unit.IsConstructor() && compiler_driver->RequiresConstructorBarrier(Thread::Current(), diff --git a/runtime/base/logging.h b/runtime/base/logging.h index de46b0c118..8aaeaac0dc 100644 --- a/runtime/base/logging.h +++ b/runtime/base/logging.h @@ -37,6 +37,7 @@ enum LogSeverity { // and the "-verbose:" command line argument. struct LogVerbosity { bool class_linker; // Enabled with "-verbose:class". + bool collector; bool compiler; bool deopt; bool gc; diff --git a/runtime/gc/collector/immune_spaces.cc b/runtime/gc/collector/immune_spaces.cc index 0862ff0577..26da4ca5a9 100644 --- a/runtime/gc/collector/immune_spaces.cc +++ b/runtime/gc/collector/immune_spaces.cc @@ -77,8 +77,8 @@ void ImmuneSpaces::CreateLargestImmuneRegion() { } largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin)); largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end)); - VLOG(gc) << "Immune region " << largest_immune_region_.Begin() << "-" - << largest_immune_region_.End(); + VLOG(collector) << "Immune region " << largest_immune_region_.Begin() << "-" + << largest_immune_region_.End(); } void ImmuneSpaces::AddSpace(space::ContinuousSpace* space) { diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index 56aeefc2f5..e3cbf53873 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -290,6 +290,14 @@ class Instrumentation { bool IsActive() const SHARED_REQUIRES(Locks::mutator_lock_) { return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ || have_field_read_listeners_ || have_field_write_listeners_ || + have_exception_caught_listeners_ || have_method_unwind_listeners_ || + have_branch_listeners_ || have_invoke_virtual_or_interface_listeners_; + } + + // Any instrumentation *other* than what is needed for Jit profiling active? + bool NonJitProfilingActive() const SHARED_REQUIRES(Locks::mutator_lock_) { + return have_dex_pc_listeners_ || have_method_exit_listeners_ || + have_field_read_listeners_ || have_field_write_listeners_ || have_exception_caught_listeners_ || have_method_unwind_listeners_; } diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 4fd3c78f44..a595d33f04 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -320,12 +320,13 @@ static inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item, // No Mterp variant - just use the switch interpreter. return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register, false); + } else if (UNLIKELY(!Runtime::Current()->IsStarted())) { + return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, + false); } else { - const instrumentation::Instrumentation* const instrumentation = - Runtime::Current()->GetInstrumentation(); while (true) { - if (instrumentation->IsActive() || !Runtime::Current()->IsStarted()) { - // TODO: allow JIT profiling instrumentation. Now, just punt on all instrumentation. + // Mterp does not support all instrumentation/debugging. + if (MterpShouldSwitchInterpreters()) { #if !defined(__clang__) return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register); #else diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 949112de5c..19d971ead8 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -948,11 +948,15 @@ NO_RETURN void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shad __attribute__((cold)) SHARED_REQUIRES(Locks::mutator_lock_); +static inline bool TraceExecutionEnabled() { + // Return true if you want TraceExecution invocation before each bytecode execution. + return false; +} + static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst, const uint32_t dex_pc) SHARED_REQUIRES(Locks::mutator_lock_) { - constexpr bool kTracing = false; - if (kTracing) { + if (TraceExecutionEnabled()) { #define TRACE_LOG std::cerr std::ostringstream oss; oss << PrettyMethod(shadow_frame.GetMethod()) diff --git a/runtime/interpreter/mterp/arm/bincmp.S b/runtime/interpreter/mterp/arm/bincmp.S index 474bc3c276..774e1676b7 100644 --- a/runtime/interpreter/mterp/arm/bincmp.S +++ b/runtime/interpreter/mterp/arm/bincmp.S @@ -6,17 +6,29 @@ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - mov${revcmp} r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + b${revcmp} .L_${opcode}_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_${opcode}_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -25,10 +37,10 @@ GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - mov${revcmp} r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + mov${revcmp} rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST diff --git a/runtime/interpreter/mterp/arm/footer.S b/runtime/interpreter/mterp/arm/footer.S index 1dba856ecb..3456a7559b 100644 --- a/runtime/interpreter/mterp/arm/footer.S +++ b/runtime/interpreter/mterp/arm/footer.S @@ -12,7 +12,6 @@ * has not yet been thrown. Just bail out to the reference interpreter to deal with it. * TUNING: for consistency, we may want to just go ahead and handle these here. */ -#define MTERP_LOGGING 0 common_errDivideByZero: EXPORT_PC #if MTERP_LOGGING @@ -103,8 +102,12 @@ MterpException: ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] add rPC, r0, #CODEITEM_INSNS_OFFSET add rPC, rPC, r1, lsl #1 @ generate new dex_pc_ptr - str rPC, [rFP, #OFF_FP_DEX_PC_PTR] + /* Do we need to switch interpreters? */ + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE ip GOTO_OPCODE ip @@ -116,14 +119,33 @@ MterpException: */ MterpCheckSuspendAndContinue: ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) + bne 1f + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +1: EXPORT_PC mov r0, rSELF - ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) - blne MterpSuspendCheck @ (self) + bl MterpSuspendCheck @ (self) + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpLogOSR +#endif + mov r0, #1 @ Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ MterpFallback: diff --git a/runtime/interpreter/mterp/arm/header.S b/runtime/interpreter/mterp/arm/header.S index b2370bffb4..298af8a57e 100644 --- a/runtime/interpreter/mterp/arm/header.S +++ b/runtime/interpreter/mterp/arm/header.S @@ -85,6 +85,9 @@ unspecified registers or condition codes. */ #include "asm_support.h" +#define MTERP_PROFILE_BRANCHES 1 +#define MTERP_LOGGING 0 + /* During bringup, we'll use the shadow frame model instead of rFP */ /* single-purpose registers, given names for clarity */ #define rPC r4 @@ -109,14 +112,6 @@ unspecified registers or condition codes. #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) /* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - -/* * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must * be done *before* something throws. * diff --git a/runtime/interpreter/mterp/arm/invoke.S b/runtime/interpreter/mterp/arm/invoke.S index 7575865f1b..e47dd1b3ca 100644 --- a/runtime/interpreter/mterp/arm/invoke.S +++ b/runtime/interpreter/mterp/arm/invoke.S @@ -14,6 +14,9 @@ cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip diff --git a/runtime/interpreter/mterp/arm/op_goto.S b/runtime/interpreter/mterp/arm/op_goto.S index 9b3632aba2..6861950909 100644 --- a/runtime/interpreter/mterp/arm/op_goto.S +++ b/runtime/interpreter/mterp/arm/op_goto.S @@ -6,20 +6,28 @@ */ /* goto +AA */ /* tuning: use sbfx for 6t2+ targets */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsl #16 @ r0<- AAxx0000 - movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) - add r2, r1, r1 @ r2<- byte offset, set flags - @ If backwards branch refresh rIBASE - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended) + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r2, rINST, rINST @ r2<- byte offset, set flags FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST + @ If backwards branch refresh rIBASE + bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else - ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] mov r0, rINST, lsl #16 @ r0<- AAxx0000 - movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) - add r2, r1, r1 @ r2<- byte offset, set flags + movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended) + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r2, rINST, rINST @ r2<- byte offset, set flags FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST @ If backwards branch refresh rIBASE bmi MterpCheckSuspendAndContinue diff --git a/runtime/interpreter/mterp/arm/op_goto_16.S b/runtime/interpreter/mterp/arm/op_goto_16.S index 2231acdb9e..91639ca796 100644 --- a/runtime/interpreter/mterp/arm/op_goto_16.S +++ b/runtime/interpreter/mterp/arm/op_goto_16.S @@ -5,17 +5,25 @@ * double to get a byte offset. */ /* goto/16 +AAAA */ -#if MTERP_SUSPEND - FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended) - adds r1, r0, r0 @ r1<- byte offset, flags set +#if MTERP_PROFILE_BRANCHES + FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended) + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset, flags set FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else - FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended) + FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended) ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - adds r1, r0, r0 @ r1<- byte offset, flags set + adds r1, rINST, rINST @ r1<- byte offset, flags set FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST diff --git a/runtime/interpreter/mterp/arm/op_goto_32.S b/runtime/interpreter/mterp/arm/op_goto_32.S index 6b72ff5ce2..e730b527ec 100644 --- a/runtime/interpreter/mterp/arm/op_goto_32.S +++ b/runtime/interpreter/mterp/arm/op_goto_32.S @@ -10,21 +10,29 @@ * offset to byte offset. */ /* goto/32 +AAAAAAAA */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES FETCH r0, 1 @ r0<- aaaa (lo) FETCH r1, 2 @ r1<- AAAA (hi) - orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa - adds r1, r0, r0 @ r1<- byte offset + orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrle rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else FETCH r0, 1 @ r0<- aaaa (lo) FETCH r1, 2 @ r1<- AAAA (hi) + orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa - adds r1, r0, r0 @ r1<- byte offset + adds r1, rINST, rINST @ r1<- byte offset FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST diff --git a/runtime/interpreter/mterp/arm/op_packed_switch.S b/runtime/interpreter/mterp/arm/op_packed_switch.S index 1e3370ea6a..4c369cb136 100644 --- a/runtime/interpreter/mterp/arm/op_packed_switch.S +++ b/runtime/interpreter/mterp/arm/op_packed_switch.S @@ -9,7 +9,7 @@ * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES FETCH r0, 1 @ r0<- bbbb (lo) FETCH r1, 2 @ r1<- BBBB (hi) mov r3, rINST, lsr #8 @ r3<- AA @@ -17,9 +17,18 @@ GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl $func @ r0<- code-unit branch offset - adds r1, r0, r0 @ r1<- byte offset; clear V - ldrle rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + mov rINST, r0 + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST + ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -30,8 +39,9 @@ GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl $func @ r0<- code-unit branch offset + mov rINST, r0 ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - adds r1, r0, r0 @ r1<- byte offset; clear V + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST diff --git a/runtime/interpreter/mterp/arm/zcmp.S b/runtime/interpreter/mterp/arm/zcmp.S index 6e9ef55104..800804d95e 100644 --- a/runtime/interpreter/mterp/arm/zcmp.S +++ b/runtime/interpreter/mterp/arm/zcmp.S @@ -6,25 +6,37 @@ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - mov${revcmp} r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + b${revcmp} .L_${opcode}_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_${opcode}_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - mov${revcmp} r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + mov${revcmp} rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST diff --git a/runtime/interpreter/mterp/arm64/bincmp.S b/runtime/interpreter/mterp/arm64/bincmp.S index ecab2ceba7..ed850fc49d 100644 --- a/runtime/interpreter/mterp/arm64/bincmp.S +++ b/runtime/interpreter/mterp/arm64/bincmp.S @@ -6,17 +6,28 @@ * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - mov${condition} w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.${condition} .L_${opcode}_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_${opcode}_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -25,11 +36,11 @@ GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, ${condition} // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, ${condition} // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST diff --git a/runtime/interpreter/mterp/arm64/footer.S b/runtime/interpreter/mterp/arm64/footer.S index b360539a8c..aae78de1b3 100644 --- a/runtime/interpreter/mterp/arm64/footer.S +++ b/runtime/interpreter/mterp/arm64/footer.S @@ -10,7 +10,6 @@ * has not yet been thrown. Just bail out to the reference interpreter to deal with it. * TUNING: for consistency, we may want to just go ahead and handle these here. */ -#define MTERP_LOGGING 0 common_errDivideByZero: EXPORT_PC #if MTERP_LOGGING @@ -99,8 +98,11 @@ MterpException: ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] add xPC, x0, #CODEITEM_INSNS_OFFSET add xPC, xPC, x1, lsl #1 // generate new dex_pc_ptr - str xPC, [xFP, #OFF_FP_DEX_PC_PTR] + /* Do we need to switch interpreters? */ + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE ip GOTO_OPCODE ip @@ -120,10 +122,24 @@ check1: EXPORT_PC mov x0, xSELF bl MterpSuspendCheck // (self) + cbnz x0, MterpFallback // Something in the environment changed, switch interpreters GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpLogOSR +#endif + mov x0, #1 // Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ MterpFallback: diff --git a/runtime/interpreter/mterp/arm64/header.S b/runtime/interpreter/mterp/arm64/header.S index 351a6075cb..722375002b 100644 --- a/runtime/interpreter/mterp/arm64/header.S +++ b/runtime/interpreter/mterp/arm64/header.S @@ -87,6 +87,9 @@ codes. */ #include "asm_support.h" +#define MTERP_PROFILE_BRANCHES 1 +#define MTERP_LOGGING 0 + /* During bringup, we'll use the shadow frame model instead of xFP */ /* single-purpose registers, given names for clarity */ #define xPC x20 @@ -114,14 +117,6 @@ codes. #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) /* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - -/* * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must * be done *before* something throws. * diff --git a/runtime/interpreter/mterp/arm64/invoke.S b/runtime/interpreter/mterp/arm64/invoke.S index ff1974c51d..7a32df7bca 100644 --- a/runtime/interpreter/mterp/arm64/invoke.S +++ b/runtime/interpreter/mterp/arm64/invoke.S @@ -9,11 +9,12 @@ mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl $helper cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip diff --git a/runtime/interpreter/mterp/arm64/op_goto.S b/runtime/interpreter/mterp/arm64/op_goto.S index db98a45fae..7e2f6a9c11 100644 --- a/runtime/interpreter/mterp/arm64/op_goto.S +++ b/runtime/interpreter/mterp/arm64/op_goto.S @@ -6,23 +6,20 @@ */ /* goto +AA */ /* tuning: use sbfx for 6t2+ targets */ -#if MTERP_SUSPEND - mov w0, wINST, lsl #16 // w0<- AAxx0000 - movs w1, w0, asr #24 // w1<- ssssssAA (sign-extended) - add w2, w1, w1 // w2<- byte offset, set flags - // If backwards branch refresh rIBASE - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - GET_INST_OPCODE ip // extract opcode from wINST - GOTO_OPCODE ip // jump to next instruction -#else - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue lsl w0, wINST, #16 // w0<- AAxx0000 - asr w0, w0, #24 // w0<- ssssssAA (sign-extended) - adds w1, w0, w0 // Convert dalvik offset to byte offset, setting flags + asr wINST, w0, #24 // wINST<- ssssssAA (sign-extended) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST +#endif + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue + adds w1, wINST, wINST // Convert dalvik offset to byte offset, setting flags FETCH_ADVANCE_INST_RB w1 // load wINST and advance xPC // If backwards branch refresh rIBASE b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction -#endif diff --git a/runtime/interpreter/mterp/arm64/op_goto_16.S b/runtime/interpreter/mterp/arm64/op_goto_16.S index ff66a23c4e..b2b9924409 100644 --- a/runtime/interpreter/mterp/arm64/op_goto_16.S +++ b/runtime/interpreter/mterp/arm64/op_goto_16.S @@ -5,19 +5,18 @@ * double to get a byte offset. */ /* goto/16 +AAAA */ -#if MTERP_SUSPEND - FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended) - adds w1, w0, w0 // w1<- byte offset, flags set - FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST - ldrmi xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - GET_INST_OPCODE ip // extract opcode from rINST - GOTO_OPCODE ip // jump to next instruction -#else - FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended) + FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - adds w1, w0, w0 // w1<- byte offset, flags set + adds w1, wINST, wINST // w1<- byte offset, flags set FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from rINST GOTO_OPCODE ip // jump to next instruction -#endif diff --git a/runtime/interpreter/mterp/arm64/op_goto_32.S b/runtime/interpreter/mterp/arm64/op_goto_32.S index 8a6980ecea..b785857b9b 100644 --- a/runtime/interpreter/mterp/arm64/op_goto_32.S +++ b/runtime/interpreter/mterp/arm64/op_goto_32.S @@ -10,23 +10,20 @@ * offset to byte offset. */ /* goto/32 +AAAAAAAA */ -#if MTERP_SUSPEND - FETCH w0, 1 // w0<- aaaa (lo) - FETCH w1, 2 // w1<- AAAA (hi) - orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa - adds w1, w0, w0 // w1<- byte offset - FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST - ldrle xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - GET_INST_OPCODE ip // extract opcode from xINST - GOTO_OPCODE ip // jump to next instruction -#else FETCH w0, 1 // w0<- aaaa (lo) FETCH w1, 2 // w1<- AAAA (hi) + orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa - adds w1, w0, w0 // w1<- byte offset + adds w1, wINST, wINST // w1<- byte offset FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST b.le MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from xINST GOTO_OPCODE ip // jump to next instruction -#endif diff --git a/runtime/interpreter/mterp/arm64/op_iget.S b/runtime/interpreter/mterp/arm64/op_iget.S index 165c7308e1..88533bd33d 100644 --- a/runtime/interpreter/mterp/arm64/op_iget.S +++ b/runtime/interpreter/mterp/arm64/op_iget.S @@ -1,4 +1,4 @@ -%default { "is_object":"0", "helper":"artGet32InstanceFromCode"} +%default { "extend":"", "is_object":"0", "helper":"artGet32InstanceFromCode"} /* * General instance field get. * @@ -12,6 +12,7 @@ mov x3, xSELF // w3<- self bl $helper ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + $extend ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S index f087d23c0a..e8b4f04dfe 100644 --- a/runtime/interpreter/mterp/arm64/op_packed_switch.S +++ b/runtime/interpreter/mterp/arm64/op_packed_switch.S @@ -9,20 +9,6 @@ * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND - FETCH w0, 1 // w0<- bbbb (lo) - FETCH w1, 2 // w1<- BBBB (hi) - mov w3, wINST, lsr #8 // w3<- AA - orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb - GET_VREG w1, w3 // w1<- vAA - add w0, rPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 - bl $func // w0<- code-unit branch offset - adds w1, w0, w0 // w1<- byte offset; clear V - ldrle rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - GET_INST_OPCODE ip // extract opcode from wINST - GOTO_OPCODE ip // jump to next instruction -#else FETCH w0, 1 // w0<- bbbb (lo) FETCH w1, 2 // w1<- BBBB (hi) lsr w3, wINST, #8 // w3<- AA @@ -30,10 +16,18 @@ GET_VREG w1, w3 // w1<- vAA add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 bl $func // w0<- code-unit branch offset + sbfm xINST, x0, 0, 31 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + mov x2, xINST + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - adds w1, w0, w0 // w1<- byte offset; clear V + adds w1, wINST, wINST // w1<- byte offset; clear V FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST b.le MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction -#endif diff --git a/runtime/interpreter/mterp/arm64/zcmp.S b/runtime/interpreter/mterp/arm64/zcmp.S index d4856d2668..e528d9f030 100644 --- a/runtime/interpreter/mterp/arm64/zcmp.S +++ b/runtime/interpreter/mterp/arm64/zcmp.S @@ -6,26 +6,37 @@ * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - mov${condition} w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.${condition} .L_${opcode}_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_${opcode}_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, ${condition} // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, ${condition} // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 0afd2765db..1a90acd799 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -20,6 +20,8 @@ #include "interpreter/interpreter_common.h" #include "entrypoints/entrypoint_utils-inl.h" #include "mterp.h" +#include "jit/jit.h" +#include "debugger.h" namespace art { namespace interpreter { @@ -45,7 +47,9 @@ void CheckMterpAsmConstants() { void InitMterpTls(Thread* self) { self->SetMterpDefaultIBase(artMterpAsmInstructionStart); self->SetMterpAltIBase(artMterpAsmAltInstructionStart); - self->SetMterpCurrentIBase(artMterpAsmInstructionStart); + self->SetMterpCurrentIBase(TraceExecutionEnabled() ? + artMterpAsmAltInstructionStart : + artMterpAsmInstructionStart); } /* @@ -139,6 +143,20 @@ extern "C" int32_t MterpDoPackedSwitch(const uint16_t* switchData, int32_t testV return entries[index]; } +extern "C" bool MterpShouldSwitchInterpreters() + SHARED_REQUIRES(Locks::mutator_lock_) { + const instrumentation::Instrumentation* const instrumentation = + Runtime::Current()->GetInstrumentation(); + bool unhandled_instrumentation; + // TODO: enable for other targets after more extensive testing. + if (kRuntimeISA == kArm64) { + unhandled_instrumentation = instrumentation->NonJitProfilingActive(); + } else { + unhandled_instrumentation = instrumentation->IsActive(); + } + return unhandled_instrumentation || Dbg::IsDebuggerActive(); +} + extern "C" bool MterpInvokeVirtual(Thread* self, ShadowFrame* shadow_frame, uint16_t* dex_pc_ptr, uint16_t inst_data ) @@ -429,6 +447,7 @@ extern "C" void MterpCheckBefore(Thread* self, ShadowFrame* shadow_frame) } else { self->AssertNoPendingException(); } + TraceExecution(*shadow_frame, inst, shadow_frame->GetDexPC()); } extern "C" void MterpLogDivideByZeroException(Thread* self, ShadowFrame* shadow_frame) @@ -488,6 +507,14 @@ extern "C" void MterpLogFallback(Thread* self, ShadowFrame* shadow_frame) << self->IsExceptionPending(); } +extern "C" void MterpLogOSR(Thread* self, ShadowFrame* shadow_frame, int32_t offset) + SHARED_REQUIRES(Locks::mutator_lock_) { + UNUSED(self); + const Instruction* inst = Instruction::At(shadow_frame->GetDexPCPtr()); + uint16_t inst_data = inst->Fetch16(0); + LOG(INFO) << "OSR: " << inst->Opcode(inst_data) << ", offset = " << offset; +} + extern "C" void MterpLogSuspendFallback(Thread* self, ShadowFrame* shadow_frame, uint32_t flags) SHARED_REQUIRES(Locks::mutator_lock_) { UNUSED(self); @@ -500,9 +527,10 @@ extern "C" void MterpLogSuspendFallback(Thread* self, ShadowFrame* shadow_frame, } } -extern "C" void MterpSuspendCheck(Thread* self) +extern "C" bool MterpSuspendCheck(Thread* self) SHARED_REQUIRES(Locks::mutator_lock_) { self->AllowThreadSuspension(); + return MterpShouldSwitchInterpreters(); } extern "C" int artSet64IndirectStaticFromMterp(uint32_t field_idx, ArtMethod* referrer, @@ -618,5 +646,15 @@ extern "C" mirror::Object* artIGetObjectFromMterp(mirror::Object* obj, uint32_t return obj->GetFieldObject<mirror::Object>(MemberOffset(field_offset)); } +extern "C" bool MterpProfileBranch(Thread* self, ShadowFrame* shadow_frame, int32_t offset) + SHARED_REQUIRES(Locks::mutator_lock_) { + ArtMethod* method = shadow_frame->GetMethod(); + JValue* result = shadow_frame->GetResultRegister(); + uint32_t dex_pc = shadow_frame->GetDexPC(); + const auto* const instrumentation = Runtime::Current()->GetInstrumentation(); + instrumentation->Branch(self, method, dex_pc, offset); + return jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, result); +} + } // namespace interpreter } // namespace art diff --git a/runtime/interpreter/mterp/mterp.h b/runtime/interpreter/mterp/mterp.h index 90d21e9c89..8d24641ce4 100644 --- a/runtime/interpreter/mterp/mterp.h +++ b/runtime/interpreter/mterp/mterp.h @@ -30,6 +30,7 @@ namespace interpreter { void InitMterpTls(Thread* self); void CheckMterpAsmConstants(); +extern "C" bool MterpShouldSwitchInterpreters(); } // namespace interpreter } // namespace art diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S index ee195598db..519f8964fb 100644 --- a/runtime/interpreter/mterp/out/mterp_arm.S +++ b/runtime/interpreter/mterp/out/mterp_arm.S @@ -92,6 +92,9 @@ unspecified registers or condition codes. */ #include "asm_support.h" +#define MTERP_PROFILE_BRANCHES 1 +#define MTERP_LOGGING 0 + /* During bringup, we'll use the shadow frame model instead of rFP */ /* single-purpose registers, given names for clarity */ #define rPC r4 @@ -116,14 +119,6 @@ unspecified registers or condition codes. #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) /* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - -/* * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must * be done *before* something throws. * @@ -1111,20 +1106,28 @@ artMterpAsmInstructionStart = .L_op_nop */ /* goto +AA */ /* tuning: use sbfx for 6t2+ targets */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsl #16 @ r0<- AAxx0000 - movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) - add r2, r1, r1 @ r2<- byte offset, set flags - @ If backwards branch refresh rIBASE - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended) + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r2, rINST, rINST @ r2<- byte offset, set flags FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST + @ If backwards branch refresh rIBASE + bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else - ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] mov r0, rINST, lsl #16 @ r0<- AAxx0000 - movs r1, r0, asr #24 @ r1<- ssssssAA (sign-extended) - add r2, r1, r1 @ r2<- byte offset, set flags + movs rINST, r0, asr #24 @ rINST<- ssssssAA (sign-extended) + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r2, rINST, rINST @ r2<- byte offset, set flags FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST @ If backwards branch refresh rIBASE bmi MterpCheckSuspendAndContinue @@ -1143,17 +1146,25 @@ artMterpAsmInstructionStart = .L_op_nop * double to get a byte offset. */ /* goto/16 +AAAA */ -#if MTERP_SUSPEND - FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended) - adds r1, r0, r0 @ r1<- byte offset, flags set +#if MTERP_PROFILE_BRANCHES + FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended) + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset, flags set FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else - FETCH_S r0, 1 @ r0<- ssssAAAA (sign-extended) + FETCH_S rINST, 1 @ rINST<- ssssAAAA (sign-extended) ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - adds r1, r0, r0 @ r1<- byte offset, flags set + adds r1, rINST, rINST @ r1<- byte offset, flags set FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1176,21 +1187,29 @@ artMterpAsmInstructionStart = .L_op_nop * offset to byte offset. */ /* goto/32 +AAAAAAAA */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES FETCH r0, 1 @ r0<- aaaa (lo) FETCH r1, 2 @ r1<- AAAA (hi) - orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa - adds r1, r0, r0 @ r1<- byte offset + orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrle rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else FETCH r0, 1 @ r0<- aaaa (lo) FETCH r1, 2 @ r1<- AAAA (hi) + orr rINST, r0, r1, lsl #16 @ rINST<- AAAAaaaa ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - orr r0, r0, r1, lsl #16 @ r0<- AAAAaaaa - adds r1, r0, r0 @ r1<- byte offset + adds r1, rINST, rINST @ r1<- byte offset FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1211,7 +1230,7 @@ artMterpAsmInstructionStart = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES FETCH r0, 1 @ r0<- bbbb (lo) FETCH r1, 2 @ r1<- BBBB (hi) mov r3, rINST, lsr #8 @ r3<- AA @@ -1219,9 +1238,18 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl MterpDoPackedSwitch @ r0<- code-unit branch offset - adds r1, r0, r0 @ r1<- byte offset; clear V - ldrle rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + mov rINST, r0 + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST + ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1232,8 +1260,9 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl MterpDoPackedSwitch @ r0<- code-unit branch offset + mov rINST, r0 ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - adds r1, r0, r0 @ r1<- byte offset; clear V + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1255,7 +1284,7 @@ artMterpAsmInstructionStart = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES FETCH r0, 1 @ r0<- bbbb (lo) FETCH r1, 2 @ r1<- BBBB (hi) mov r3, rINST, lsr #8 @ r3<- AA @@ -1263,9 +1292,18 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl MterpDoSparseSwitch @ r0<- code-unit branch offset - adds r1, r0, r0 @ r1<- byte offset; clear V - ldrle rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh handler base + mov rINST, r0 + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST + ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1276,8 +1314,9 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r1, r3 @ r1<- vAA add r0, rPC, r0, lsl #1 @ r0<- PC + BBBBbbbb*2 bl MterpDoSparseSwitch @ r0<- code-unit branch offset + mov rINST, r0 ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - adds r1, r0, r0 @ r1<- byte offset; clear V + adds r1, rINST, rINST @ r1<- byte offset; clear V FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST ble MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1495,17 +1534,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movne r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + bne .L_op_if_eq_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_eq_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1514,10 +1565,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movne r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + movne rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1538,17 +1589,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - moveq r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + beq .L_op_if_ne_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_ne_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1557,10 +1620,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - moveq r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + moveq rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1581,17 +1644,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movge r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + bge .L_op_if_lt_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_lt_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1600,10 +1675,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movge r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + movge rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1624,17 +1699,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movlt r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + blt .L_op_if_ge_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_ge_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1643,10 +1730,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movlt r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + movlt rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1667,17 +1754,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movle r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + ble .L_op_if_gt_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_gt_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1686,10 +1785,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movle r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + movle rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1710,17 +1809,29 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r1, rINST, lsr #12 @ r1<- B ubfx r0, rINST, #8, #4 @ r0<- A GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movgt r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + bgt .L_op_if_le_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r2, rINST, rINST @ convert to bytes, check sign + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_le_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else @@ -1729,10 +1840,10 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG r3, r1 @ r3<- vB GET_VREG r2, r0 @ r2<- vA ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units cmp r2, r3 @ compare (vA, vB) - movgt r1, #2 @ r1<- BYTE branch dist for not-taken - adds r2, r1, r1 @ convert to bytes, check sign + movgt rINST, #2 @ rINST<- BYTE branch dist for not-taken + adds r2, rINST, rINST @ convert to bytes, check sign FETCH_ADVANCE_INST_RB r2 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1753,25 +1864,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movne r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + bne .L_op_if_eqz_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_eqz_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movne r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + movne rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1792,25 +1915,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - moveq r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + beq .L_op_if_nez_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_nez_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - moveq r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + moveq rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1831,25 +1966,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movge r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + bge .L_op_if_ltz_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_ltz_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movge r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + movge rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1870,25 +2017,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movlt r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + blt .L_op_if_gez_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_gez_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movlt r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + movlt rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1909,25 +2068,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movle r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + ble .L_op_if_gtz_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_gtz_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movle r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + movle rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -1948,25 +2119,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND +#if MTERP_PROFILE_BRANCHES mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units + ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movgt r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + bgt .L_op_if_lez_not_taken + EXPORT_PC + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpProfileBranch @ (self, shadow_frame, offset) + cmp r0, #0 + bne MterpOnStackReplacement @ Note: offset must be in rINST + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST - ldrmi rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh table base + bmi MterpCheckSuspendAndContinue + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +.L_op_if_lez_not_taken: + FETCH_ADVANCE_INST 2 @ update rPC, load rINST GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction #else mov r0, rINST, lsr #8 @ r0<- AA GET_VREG r2, r0 @ r2<- vAA - FETCH_S r1, 1 @ r1<- branch offset, in code units + FETCH_S rINST, 1 @ rINST<- branch offset, in code units ldr lr, [rSELF, #THREAD_FLAGS_OFFSET] cmp r2, #0 @ compare (vA, 0) - movgt r1, #2 @ r1<- inst branch dist for not-taken - adds r1, r1, r1 @ convert to bytes & set flags + movgt rINST, #2 @ rINST<- inst branch dist for not-taken + adds r1, rINST, rINST @ convert to bytes & set flags FETCH_ADVANCE_INST_RB r1 @ update rPC, load rINST bmi MterpCheckSuspendAndContinue GET_INST_OPCODE ip @ extract opcode from rINST @@ -3294,6 +3477,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3326,6 +3512,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3358,6 +3547,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3383,6 +3575,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3409,6 +3604,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3453,6 +3651,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3478,6 +3679,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3503,6 +3707,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3528,6 +3735,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3553,6 +3763,9 @@ artMterpAsmInstructionStart = .L_op_nop cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -7284,6 +7497,9 @@ constvalop_long_to_double: cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -7309,6 +7525,9 @@ constvalop_long_to_double: cmp r0, #0 beq MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -12098,7 +12317,6 @@ artMterpAsmAltInstructionEnd: * has not yet been thrown. Just bail out to the reference interpreter to deal with it. * TUNING: for consistency, we may want to just go ahead and handle these here. */ -#define MTERP_LOGGING 0 common_errDivideByZero: EXPORT_PC #if MTERP_LOGGING @@ -12189,8 +12407,12 @@ MterpException: ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] add rPC, r0, #CODEITEM_INSNS_OFFSET add rPC, rPC, r1, lsl #1 @ generate new dex_pc_ptr - str rPC, [rFP, #OFF_FP_DEX_PC_PTR] + /* Do we need to switch interpreters? */ + bl MterpShouldSwitchInterpreters + cmp r0, #0 + bne MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE ip GOTO_OPCODE ip @@ -12202,14 +12424,33 @@ MterpException: */ MterpCheckSuspendAndContinue: ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh rIBASE + ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) + bne 1f + GET_INST_OPCODE ip @ extract opcode from rINST + GOTO_OPCODE ip @ jump to next instruction +1: EXPORT_PC mov r0, rSELF - ands lr, #(THREAD_SUSPEND_REQUEST | THREAD_CHECKPOINT_REQUEST) - blne MterpSuspendCheck @ (self) + bl MterpSuspendCheck @ (self) + cmp r0, #0 + bne MterpFallback GET_INST_OPCODE ip @ extract opcode from rINST GOTO_OPCODE ip @ jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + mov r0, rSELF + add r1, rFP, #OFF_FP_SHADOWFRAME + mov r2, rINST + bl MterpLogOSR +#endif + mov r0, #1 @ Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ MterpFallback: diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S index e9d28abf8b..e4825f0489 100644 --- a/runtime/interpreter/mterp/out/mterp_arm64.S +++ b/runtime/interpreter/mterp/out/mterp_arm64.S @@ -94,6 +94,9 @@ codes. */ #include "asm_support.h" +#define MTERP_PROFILE_BRANCHES 1 +#define MTERP_LOGGING 0 + /* During bringup, we'll use the shadow frame model instead of xFP */ /* single-purpose registers, given names for clarity */ #define xPC x20 @@ -121,14 +124,6 @@ codes. #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) /* - * - * The reference interpreter performs explicit suspect checks, which is somewhat wasteful. - * Dalvik's interpreter folded suspend checks into the jump table mechanism, and eventually - * mterp should do so as well. - */ -#define MTERP_SUSPEND 0 - -/* * "export" the PC to dex_pc field in the shadow frame, f/b/o future exception objects. Must * be done *before* something throws. * @@ -1087,26 +1082,23 @@ artMterpAsmInstructionStart = .L_op_nop */ /* goto +AA */ /* tuning: use sbfx for 6t2+ targets */ -#if MTERP_SUSPEND - mov w0, wINST, lsl #16 // w0<- AAxx0000 - movs w1, w0, asr #24 // w1<- ssssssAA (sign-extended) - add w2, w1, w1 // w2<- byte offset, set flags - // If backwards branch refresh rIBASE - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - GET_INST_OPCODE ip // extract opcode from wINST - GOTO_OPCODE ip // jump to next instruction -#else - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue lsl w0, wINST, #16 // w0<- AAxx0000 - asr w0, w0, #24 // w0<- ssssssAA (sign-extended) - adds w1, w0, w0 // Convert dalvik offset to byte offset, setting flags + asr wINST, w0, #24 // wINST<- ssssssAA (sign-extended) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST +#endif + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] // Preload flags for MterpCheckSuspendAndContinue + adds w1, wINST, wINST // Convert dalvik offset to byte offset, setting flags FETCH_ADVANCE_INST_RB w1 // load wINST and advance xPC // If backwards branch refresh rIBASE b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction -#endif /* ------------------------------ */ .balign 128 @@ -1119,22 +1111,21 @@ artMterpAsmInstructionStart = .L_op_nop * double to get a byte offset. */ /* goto/16 +AAAA */ -#if MTERP_SUSPEND - FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended) - adds w1, w0, w0 // w1<- byte offset, flags set - FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST - ldrmi xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - GET_INST_OPCODE ip // extract opcode from rINST - GOTO_OPCODE ip // jump to next instruction -#else - FETCH_S w0, 1 // w0<- ssssAAAA (sign-extended) + FETCH_S wINST, 1 // wINST<- ssssAAAA (sign-extended) +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - adds w1, w0, w0 // w1<- byte offset, flags set + adds w1, wINST, wINST // w1<- byte offset, flags set FETCH_ADVANCE_INST_RB w1 // update rPC, load rINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from rINST GOTO_OPCODE ip // jump to next instruction -#endif /* ------------------------------ */ .balign 128 @@ -1152,26 +1143,23 @@ artMterpAsmInstructionStart = .L_op_nop * offset to byte offset. */ /* goto/32 +AAAAAAAA */ -#if MTERP_SUSPEND - FETCH w0, 1 // w0<- aaaa (lo) - FETCH w1, 2 // w1<- AAAA (hi) - orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa - adds w1, w0, w0 // w1<- byte offset - FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST - ldrle xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - GET_INST_OPCODE ip // extract opcode from xINST - GOTO_OPCODE ip // jump to next instruction -#else FETCH w0, 1 // w0<- aaaa (lo) FETCH w1, 2 // w1<- AAAA (hi) + orr wINST, w0, w1, lsl #16 // wINST<- AAAAaaaa +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - orr w0, w0, w1, lsl #16 // w0<- AAAAaaaa - adds w1, w0, w0 // w1<- byte offset + adds w1, wINST, wINST // w1<- byte offset FETCH_ADVANCE_INST_RB w1 // update rPC, load xINST b.le MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from xINST GOTO_OPCODE ip // jump to next instruction -#endif /* ------------------------------ */ .balign 128 @@ -1187,20 +1175,6 @@ artMterpAsmInstructionStart = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND - FETCH w0, 1 // w0<- bbbb (lo) - FETCH w1, 2 // w1<- BBBB (hi) - mov w3, wINST, lsr #8 // w3<- AA - orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb - GET_VREG w1, w3 // w1<- vAA - add w0, rPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 - bl MterpDoPackedSwitch // w0<- code-unit branch offset - adds w1, w0, w0 // w1<- byte offset; clear V - ldrle rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - GET_INST_OPCODE ip // extract opcode from wINST - GOTO_OPCODE ip // jump to next instruction -#else FETCH w0, 1 // w0<- bbbb (lo) FETCH w1, 2 // w1<- BBBB (hi) lsr w3, wINST, #8 // w3<- AA @@ -1208,13 +1182,21 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w1, w3 // w1<- vAA add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 bl MterpDoPackedSwitch // w0<- code-unit branch offset + sbfm xINST, x0, 0, 31 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + mov x2, xINST + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - adds w1, w0, w0 // w1<- byte offset; clear V + adds w1, wINST, wINST // w1<- byte offset; clear V FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST b.le MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction -#endif /* ------------------------------ */ .balign 128 @@ -1231,20 +1213,6 @@ artMterpAsmInstructionStart = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ -#if MTERP_SUSPEND - FETCH w0, 1 // w0<- bbbb (lo) - FETCH w1, 2 // w1<- BBBB (hi) - mov w3, wINST, lsr #8 // w3<- AA - orr w0, w0, w1, lsl #16 // w0<- BBBBbbbb - GET_VREG w1, w3 // w1<- vAA - add w0, rPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 - bl MterpDoSparseSwitch // w0<- code-unit branch offset - adds w1, w0, w0 // w1<- byte offset; clear V - ldrle rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh handler base - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - GET_INST_OPCODE ip // extract opcode from wINST - GOTO_OPCODE ip // jump to next instruction -#else FETCH w0, 1 // w0<- bbbb (lo) FETCH w1, 2 // w1<- BBBB (hi) lsr w3, wINST, #8 // w3<- AA @@ -1252,13 +1220,21 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w1, w3 // w1<- vAA add x0, xPC, w0, lsl #1 // w0<- PC + BBBBbbbb*2 bl MterpDoSparseSwitch // w0<- code-unit branch offset + sbfm xINST, x0, 0, 31 +#if MTERP_PROFILE_BRANCHES + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + mov x2, xINST + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement +#endif ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] - adds w1, w0, w0 // w1<- byte offset; clear V + adds w1, wINST, wINST // w1<- byte offset; clear V FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST b.le MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction -#endif /* ------------------------------ */ @@ -1396,17 +1372,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - moveq w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.eq .L_op_if_eq_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_eq_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1415,11 +1402,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, eq // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, eq // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1440,17 +1427,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - movne w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.ne .L_op_if_ne_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_ne_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1459,11 +1457,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, ne // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, ne // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1484,17 +1482,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - movlt w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.lt .L_op_if_lt_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_lt_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1503,11 +1512,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, lt // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, lt // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1528,17 +1537,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - movge w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.ge .L_op_if_ge_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_ge_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1547,11 +1567,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, ge // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, ge // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1572,17 +1592,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - movgt w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.gt .L_op_if_gt_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_gt_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1591,11 +1622,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, gt // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, gt // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1616,17 +1647,28 @@ artMterpAsmInstructionStart = .L_op_nop * For: if-eq, if-ne, if-lt, if-ge, if-gt, if-le */ /* if-cmp vA, vB, +CCCC */ -#if MTERP_SUSPEND - mov w1, wINST, lsr #12 // w1<- B +#if MTERP_PROFILE_BRANCHES + lsr w1, wINST, #12 // w1<- B ubfx w0, wINST, #8, #4 // w0<- A GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // wINST<- branch offset, in code units cmp w2, w3 // compare (vA, vB) - movle w1, #2 // w1<- BYTE branch dist for not-taken - adds w2, w1, w1 // convert to bytes, check sign + b.le .L_op_if_le_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_le_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 // Sign extend branch offset + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in xINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh rIBASE + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else @@ -1635,11 +1677,11 @@ artMterpAsmInstructionStart = .L_op_nop GET_VREG w3, w1 // w3<- vB GET_VREG w2, w0 // w2<- vA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Offset if branch not taken cmp w2, w3 // compare (vA, vB) - csel w1, w1, w0, le // Branch if true - adds w2, w1, w1 // convert to bytes, check sign + csel wINST, w1, w0, le // Branch if true, stashing result in callee save reg. + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes, check sign FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1660,26 +1702,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - moveq w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.eq .L_op_if_eqz_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_eqz_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, eq // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, eq // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1700,26 +1753,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - movne w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.ne .L_op_if_nez_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_nez_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, ne // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, ne // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1740,26 +1804,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - movlt w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.lt .L_op_if_ltz_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_ltz_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, lt // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, lt // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1780,26 +1855,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - movge w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.ge .L_op_if_gez_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_gez_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, ge // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, ge // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1820,26 +1906,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - movgt w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.gt .L_op_if_gtz_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_gtz_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, gt // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, gt // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -1860,26 +1957,37 @@ artMterpAsmInstructionStart = .L_op_nop * for: if-eqz, if-nez, if-ltz, if-gez, if-gtz, if-lez */ /* if-cmp vAA, +BBBB */ -#if MTERP_SUSPEND - mov w0, wINST, lsr #8 // w0<- AA +#if MTERP_PROFILE_BRANCHES + lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA - FETCH_S w1, 1 // w1<- branch offset, in code units + FETCH_S wINST, 1 // w1<- branch offset, in code units cmp w2, #0 // compare (vA, 0) - movle w1, #2 // w1<- inst branch dist for not-taken - adds w1, w1, w1 // convert to bytes & set flags - FETCH_ADVANCE_INST_RB w1 // update rPC, load wINST - ldrmi rIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh table base + b.le .L_op_if_lez_taken + FETCH_ADVANCE_INST 2 // update rPC, load wINST + GET_INST_OPCODE ip // extract opcode from wINST + GOTO_OPCODE ip // jump to next instruction +.L_op_if_lez_taken: + EXPORT_PC + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpProfileBranch // (self, shadow_frame, offset) + cbnz w0, MterpOnStackReplacement // Note: offset must be in wINST + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags + FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST + b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction #else lsr w0, wINST, #8 // w0<- AA GET_VREG w2, w0 // w2<- vAA FETCH_S w1, 1 // w1<- branch offset, in code units - ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] mov w0, #2 // Branch offset if not taken cmp w2, #0 // compare (vA, 0) - csel w1, w1, w0, le // Branch if true - adds w2, w1, w1 // convert to bytes & set flags + csel wINST, w1, w0, le // Branch if true, stashing result in callee save reg + ldr w7, [xSELF, #THREAD_FLAGS_OFFSET] + adds w2, wINST, wINST // convert to bytes & set flags FETCH_ADVANCE_INST_RB w2 // update rPC, load wINST b.mi MterpCheckSuspendAndContinue GET_INST_OPCODE ip // extract opcode from wINST @@ -2401,6 +2509,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGet32InstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -2457,6 +2566,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGetObjInstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -2488,6 +2598,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGetBooleanInstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + uxtb w0, w0 ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -2519,6 +2630,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGetByteInstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + sxtb w0, w0 ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -2550,6 +2662,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGetCharInstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + uxth w0, w0 ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -2581,6 +2694,7 @@ artMterpAsmInstructionStart = .L_op_nop mov x3, xSELF // w3<- self bl artGetShortInstanceFromCode ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET] + sxth w0, w0 ubfx w2, wINST, #8, #4 // w2<- A PREFETCH_INST 2 cbnz x3, MterpPossibleException // bail out @@ -3158,11 +3272,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeVirtual cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3190,11 +3305,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeSuper cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3222,11 +3338,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeDirect cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3247,11 +3364,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeStatic cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3273,11 +3391,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeInterface cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3320,11 +3439,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeVirtualRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3345,11 +3465,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeSuperRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3370,11 +3491,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeDirectRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3395,11 +3517,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeStaticRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -3420,11 +3543,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeInterfaceRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -6852,11 +6976,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeVirtualQuick cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -6877,11 +7002,12 @@ artMterpAsmInstructionStart = .L_op_nop mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC - // and x3, xINST, 0xFFFF mov x3, xINST bl MterpInvokeVirtualQuickRange cbz w0, MterpException FETCH_ADVANCE_INST 3 + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback GET_INST_OPCODE ip GOTO_OPCODE ip @@ -11565,7 +11691,6 @@ artMterpAsmAltInstructionEnd: * has not yet been thrown. Just bail out to the reference interpreter to deal with it. * TUNING: for consistency, we may want to just go ahead and handle these here. */ -#define MTERP_LOGGING 0 common_errDivideByZero: EXPORT_PC #if MTERP_LOGGING @@ -11654,8 +11779,11 @@ MterpException: ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] add xPC, x0, #CODEITEM_INSNS_OFFSET add xPC, xPC, x1, lsl #1 // generate new dex_pc_ptr - str xPC, [xFP, #OFF_FP_DEX_PC_PTR] + /* Do we need to switch interpreters? */ + bl MterpShouldSwitchInterpreters + cbnz w0, MterpFallback /* resume execution at catch block */ + EXPORT_PC FETCH_INST GET_INST_OPCODE ip GOTO_OPCODE ip @@ -11675,10 +11803,24 @@ check1: EXPORT_PC mov x0, xSELF bl MterpSuspendCheck // (self) + cbnz x0, MterpFallback // Something in the environment changed, switch interpreters GET_INST_OPCODE ip // extract opcode from wINST GOTO_OPCODE ip // jump to next instruction /* + * On-stack replacement has happened, and now we've returned from the compiled method. + */ +MterpOnStackReplacement: +#if MTERP_LOGGING + mov x0, xSELF + add x1, xFP, #OFF_FP_SHADOWFRAME + sbfm x2, xINST, 0, 31 + bl MterpLogOSR +#endif + mov x0, #1 // Signal normal return + b MterpDone + +/* * Bail out to reference interpreter. */ MterpFallback: diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S index 96229ceba0..d365a4f986 100644 --- a/runtime/interpreter/mterp/out/mterp_x86.S +++ b/runtime/interpreter/mterp/out/mterp_x86.S @@ -189,13 +189,21 @@ unspecified registers or condition codes. /* * Refresh handler table. + */ +.macro REFRESH_IBASE + movl rSELF, rIBASE + movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE +.endm + +/* + * Refresh handler table. * IBase handles uses the caller save register so we must restore it after each call. * Also it is used as a result of some 64-bit operations (like imul) and we should * restore it in such cases also. * * TODO: Consider spilling the IBase instead of restoring it from Thread structure. */ -.macro REFRESH_IBASE +.macro RESTORE_IBASE movl rSELF, rIBASE movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE .endm @@ -203,7 +211,7 @@ unspecified registers or condition codes. /* * If rSELF is already loaded then we can use it from known reg. */ -.macro REFRESH_IBASE_FROM_SELF _reg +.macro RESTORE_IBASE_FROM_SELF _reg movl THREAD_CURRENT_IBASE_OFFSET(\_reg), rIBASE .endm @@ -771,8 +779,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -790,8 +798,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -809,8 +817,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstClass) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -828,8 +836,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG1(%esp) call SYMBOL(artLockObjectFromCode) # (object, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpException ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -851,8 +859,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG1(%esp) call SYMBOL(artUnlockObjectFromCode) # (object, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpException ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -874,8 +882,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpCheckCast) # (index, &obj, method, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -903,7 +911,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpInstanceOf) # (index, &obj, method, self) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException andb $0xf, rINSTbl # rINSTbl <- A @@ -943,8 +951,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 34 movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpNewInstance) - REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + RESTORE_IBASE + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -969,8 +977,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpNewArray) - REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + RESTORE_IBASE + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -994,7 +1002,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) call SYMBOL(MterpFilledNewArray) REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -1019,7 +1027,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) call SYMBOL(MterpFilledNewArrayRange) REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -1037,7 +1045,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG1(%esp) call SYMBOL(MterpFillArrayData) # (obj, payload) REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -1923,7 +1931,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG1(%esp) call SYMBOL(artAGetObjectFromMterp) # (array, index) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException SET_VREG_OBJECT %eax, rINST @@ -2090,8 +2098,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 77 movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpAputObject) # (array, index) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2221,7 +2229,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGet32InstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2259,7 +2267,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop andb $0xf, rINSTbl # rINST <- A SET_VREG %eax, rINST SET_VREG_HIGH %edx, rINST - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2285,7 +2293,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGetObjInstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2320,7 +2328,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGetBooleanInstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2355,7 +2363,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGetByteInstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2390,7 +2398,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGetCharInstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2425,7 +2433,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artGetShortInstanceFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf, rINSTbl # rINST <- A @@ -2461,9 +2469,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet32InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2485,9 +2493,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet64InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2503,9 +2511,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpIputObject) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2533,9 +2541,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet8InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2564,9 +2572,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet8InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2595,9 +2603,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet16InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2626,9 +2634,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet16InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2652,7 +2660,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGet32StaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 0 @@ -2685,7 +2693,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop jnz MterpException SET_VREG %eax, rINST # fp[A]<- low part SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2709,7 +2717,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGetObjStaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 1 @@ -2741,7 +2749,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGetBooleanStaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 0 @@ -2773,7 +2781,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGetByteStaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 0 @@ -2805,7 +2813,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGetCharStaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 0 @@ -2837,7 +2845,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl %ecx, OUT_ARG2(%esp) # self call SYMBOL(artGetShortStaticFromCode) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if 0 @@ -2869,9 +2877,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet32StaticFromCode) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2894,9 +2902,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet64IndirectStaticFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2912,9 +2920,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpSputObject) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -2939,9 +2947,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet8StaticFromCode) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2967,9 +2975,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet8StaticFromCode) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -2995,9 +3003,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet16StaticFromCode) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -3023,9 +3031,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet16StaticFromCode) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -3049,9 +3057,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 110 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeVirtual) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 /* @@ -3082,9 +3090,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 111 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeSuper) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 /* @@ -3115,9 +3123,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 112 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeDirect) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3141,9 +3149,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 113 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeStatic) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3168,9 +3176,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 114 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeInterface) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 /* @@ -3215,9 +3223,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 116 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeVirtualRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3241,9 +3249,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 117 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeSuperRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3267,9 +3275,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 118 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeDirectRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3293,9 +3301,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 119 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeStaticRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -3319,9 +3327,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 120 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeInterfaceRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -4047,10 +4055,10 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop je common_errDivideByZero movl %eax, %edx orl %ecx, %edx - test $0xFFFFFF00, %edx # If both arguments are less + testl $0xFFFFFF00, %edx # If both arguments are less # than 8-bit and +ve jz .Lop_div_int_8 # Do 8-bit divide - test $0xFFFF0000, %edx # If both arguments are less + testl $0xFFFF0000, %edx # If both arguments are less # than 16-bit and +ve jz .Lop_div_int_16 # Do 16-bit divide cmpl $-1, %ecx @@ -4101,10 +4109,10 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop je common_errDivideByZero movl %eax, %edx orl %ecx, %edx - test $0xFFFFFF00, %edx # If both arguments are less + testl $0xFFFFFF00, %edx # If both arguments are less # than 8-bit and +ve jz .Lop_rem_int_8 # Do 8-bit divide - test $0xFFFF0000, %edx # If both arguments are less + testl $0xFFFF0000, %edx # If both arguments are less # than 16-bit and +ve jz .Lop_rem_int_16 # Do 16-bit divide cmpl $-1, %ecx @@ -4785,9 +4793,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop sarl $4, rINST # rINST <- B GET_VREG %eax, rINST # eax <- vB andb $0xf, %cl # ecx <- A - mov rIBASE, LOCAL0(%esp) + movl rIBASE, rINST imull (rFP,%ecx,4), %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + movl rINST, rIBASE SET_VREG %eax, %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -5514,11 +5522,11 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop movzbl rINSTbl, %eax # eax <- 000000BA sarl $4, %eax # eax <- B GET_VREG %eax, %eax # eax <- vB - movswl 2(rPC), %ecx # ecx <- ssssCCCC + movl rIBASE, %ecx + movswl 2(rPC), rIBASE # rIBASE <- ssssCCCC andb $0xf, rINSTbl # rINST <- A - mov rIBASE, LOCAL0(%esp) - imull %ecx, %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + imull rIBASE, %eax # trashes rIBASE/edx + movl %ecx, rIBASE SET_VREG %eax, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -5721,11 +5729,11 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop /* File: x86/op_mul_int_lit8.S */ /* mul/lit8 vAA, vBB, #+CC */ movzbl 2(rPC), %eax # eax <- BB - movsbl 3(rPC), %ecx # ecx <- ssssssCC + movl rIBASE, %ecx GET_VREG %eax, %eax # eax <- rBB - mov rIBASE, LOCAL0(%esp) - imull %ecx, %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + movsbl 3(rPC), rIBASE # rIBASE <- ssssssCC + imull rIBASE, %eax # trashes rIBASE/edx + movl %ecx, rIBASE SET_VREG %eax, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -5985,7 +5993,7 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop EXPORT_PC call SYMBOL(artIGetObjectFromMterp) # (obj, offset) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $0xf,rINSTbl # rINST <- A @@ -6037,9 +6045,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 232 movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpIputObjectQuick) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 /* ------------------------------ */ @@ -6062,9 +6070,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 233 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeVirtualQuick) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -6088,9 +6096,9 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop REFRESH_INST 234 movl rINST, OUT_ARG3(%esp) call SYMBOL(MterpInvokeVirtualQuickRange) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 @@ -12912,7 +12920,7 @@ MterpException: lea OFF_FP_SHADOWFRAME(rFP), %ecx movl %ecx, OUT_ARG1(%esp) call SYMBOL(MterpHandleException) - testl %eax, %eax + testb %al, %al jz MterpExceptionReturn REFRESH_IBASE movl OFF_FP_CODE_ITEM(rFP), %eax diff --git a/runtime/interpreter/mterp/x86/bindiv.S b/runtime/interpreter/mterp/x86/bindiv.S index bb5b319c49..e87ba45546 100644 --- a/runtime/interpreter/mterp/x86/bindiv.S +++ b/runtime/interpreter/mterp/x86/bindiv.S @@ -13,10 +13,10 @@ je common_errDivideByZero movl %eax, %edx orl %ecx, %edx - test $$0xFFFFFF00, %edx # If both arguments are less + testl $$0xFFFFFF00, %edx # If both arguments are less # than 8-bit and +ve jz .L${opcode}_8 # Do 8-bit divide - test $$0xFFFF0000, %edx # If both arguments are less + testl $$0xFFFF0000, %edx # If both arguments are less # than 16-bit and +ve jz .L${opcode}_16 # Do 16-bit divide cmpl $$-1, %ecx diff --git a/runtime/interpreter/mterp/x86/footer.S b/runtime/interpreter/mterp/x86/footer.S index 385e78499f..a1532fa710 100644 --- a/runtime/interpreter/mterp/x86/footer.S +++ b/runtime/interpreter/mterp/x86/footer.S @@ -114,7 +114,7 @@ MterpException: lea OFF_FP_SHADOWFRAME(rFP), %ecx movl %ecx, OUT_ARG1(%esp) call SYMBOL(MterpHandleException) - testl %eax, %eax + testb %al, %al jz MterpExceptionReturn REFRESH_IBASE movl OFF_FP_CODE_ITEM(rFP), %eax diff --git a/runtime/interpreter/mterp/x86/header.S b/runtime/interpreter/mterp/x86/header.S index 0977b901e2..3fbbbf955e 100644 --- a/runtime/interpreter/mterp/x86/header.S +++ b/runtime/interpreter/mterp/x86/header.S @@ -182,13 +182,21 @@ unspecified registers or condition codes. /* * Refresh handler table. + */ +.macro REFRESH_IBASE + movl rSELF, rIBASE + movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE +.endm + +/* + * Refresh handler table. * IBase handles uses the caller save register so we must restore it after each call. * Also it is used as a result of some 64-bit operations (like imul) and we should * restore it in such cases also. * * TODO: Consider spilling the IBase instead of restoring it from Thread structure. */ -.macro REFRESH_IBASE +.macro RESTORE_IBASE movl rSELF, rIBASE movl THREAD_CURRENT_IBASE_OFFSET(rIBASE), rIBASE .endm @@ -196,7 +204,7 @@ unspecified registers or condition codes. /* * If rSELF is already loaded then we can use it from known reg. */ -.macro REFRESH_IBASE_FROM_SELF _reg +.macro RESTORE_IBASE_FROM_SELF _reg movl THREAD_CURRENT_IBASE_OFFSET(\_reg), rIBASE .endm diff --git a/runtime/interpreter/mterp/x86/invoke.S b/runtime/interpreter/mterp/x86/invoke.S index 054fbfdf69..bbd88cf40b 100644 --- a/runtime/interpreter/mterp/x86/invoke.S +++ b/runtime/interpreter/mterp/x86/invoke.S @@ -14,7 +14,7 @@ REFRESH_INST ${opnum} movl rINST, OUT_ARG3(%esp) call SYMBOL($helper) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 diff --git a/runtime/interpreter/mterp/x86/op_aget_object.S b/runtime/interpreter/mterp/x86/op_aget_object.S index cbfb50cb09..35ec053854 100644 --- a/runtime/interpreter/mterp/x86/op_aget_object.S +++ b/runtime/interpreter/mterp/x86/op_aget_object.S @@ -13,7 +13,7 @@ movl %ecx, OUT_ARG1(%esp) call SYMBOL(artAGetObjectFromMterp) # (array, index) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException SET_VREG_OBJECT %eax, rINST diff --git a/runtime/interpreter/mterp/x86/op_aput_object.S b/runtime/interpreter/mterp/x86/op_aput_object.S index 9cfc2213d2..980b26a401 100644 --- a/runtime/interpreter/mterp/x86/op_aput_object.S +++ b/runtime/interpreter/mterp/x86/op_aput_object.S @@ -9,7 +9,7 @@ REFRESH_INST ${opnum} movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpAputObject) # (array, index) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_check_cast.S b/runtime/interpreter/mterp/x86/op_check_cast.S index ae2ff9ea21..d090aa3785 100644 --- a/runtime/interpreter/mterp/x86/op_check_cast.S +++ b/runtime/interpreter/mterp/x86/op_check_cast.S @@ -12,7 +12,7 @@ movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpCheckCast) # (index, &obj, method, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_const_class.S b/runtime/interpreter/mterp/x86/op_const_class.S index 343e110f71..60be789214 100644 --- a/runtime/interpreter/mterp/x86/op_const_class.S +++ b/runtime/interpreter/mterp/x86/op_const_class.S @@ -8,7 +8,7 @@ movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstClass) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_const_string.S b/runtime/interpreter/mterp/x86/op_const_string.S index bbac69ced4..ff93b232d6 100644 --- a/runtime/interpreter/mterp/x86/op_const_string.S +++ b/runtime/interpreter/mterp/x86/op_const_string.S @@ -8,7 +8,7 @@ movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_const_string_jumbo.S b/runtime/interpreter/mterp/x86/op_const_string_jumbo.S index 4236807dd3..e7f952a306 100644 --- a/runtime/interpreter/mterp/x86/op_const_string_jumbo.S +++ b/runtime/interpreter/mterp/x86/op_const_string_jumbo.S @@ -8,7 +8,7 @@ movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpConstString) # (index, tgt_reg, shadow_frame, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 diff --git a/runtime/interpreter/mterp/x86/op_fill_array_data.S b/runtime/interpreter/mterp/x86/op_fill_array_data.S index 004aed9872..5855284901 100644 --- a/runtime/interpreter/mterp/x86/op_fill_array_data.S +++ b/runtime/interpreter/mterp/x86/op_fill_array_data.S @@ -7,6 +7,6 @@ movl %ecx, OUT_ARG1(%esp) call SYMBOL(MterpFillArrayData) # (obj, payload) REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 diff --git a/runtime/interpreter/mterp/x86/op_filled_new_array.S b/runtime/interpreter/mterp/x86/op_filled_new_array.S index a2bac29bc1..35b2fe8dfc 100644 --- a/runtime/interpreter/mterp/x86/op_filled_new_array.S +++ b/runtime/interpreter/mterp/x86/op_filled_new_array.S @@ -15,6 +15,6 @@ movl %ecx, OUT_ARG2(%esp) call SYMBOL($helper) REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 3 diff --git a/runtime/interpreter/mterp/x86/op_iget.S b/runtime/interpreter/mterp/x86/op_iget.S index 99326105c0..e3304ba6a7 100644 --- a/runtime/interpreter/mterp/x86/op_iget.S +++ b/runtime/interpreter/mterp/x86/op_iget.S @@ -17,7 +17,7 @@ movl %ecx, OUT_ARG3(%esp) # self call SYMBOL($helper) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $$0xf, rINSTbl # rINST <- A diff --git a/runtime/interpreter/mterp/x86/op_iget_object_quick.S b/runtime/interpreter/mterp/x86/op_iget_object_quick.S index fe166948c9..b1551a0179 100644 --- a/runtime/interpreter/mterp/x86/op_iget_object_quick.S +++ b/runtime/interpreter/mterp/x86/op_iget_object_quick.S @@ -9,7 +9,7 @@ EXPORT_PC call SYMBOL(artIGetObjectFromMterp) # (obj, offset) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException # bail out andb $$0xf,rINSTbl # rINST <- A diff --git a/runtime/interpreter/mterp/x86/op_iget_wide.S b/runtime/interpreter/mterp/x86/op_iget_wide.S index 92126b4473..a5d7e6937d 100644 --- a/runtime/interpreter/mterp/x86/op_iget_wide.S +++ b/runtime/interpreter/mterp/x86/op_iget_wide.S @@ -21,5 +21,5 @@ andb $$0xf, rINSTbl # rINST <- A SET_VREG %eax, rINST SET_VREG_HIGH %edx, rINST - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_instance_of.S b/runtime/interpreter/mterp/x86/op_instance_of.S index fd5bf44c78..e6fe5b2cec 100644 --- a/runtime/interpreter/mterp/x86/op_instance_of.S +++ b/runtime/interpreter/mterp/x86/op_instance_of.S @@ -18,7 +18,7 @@ movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpInstanceOf) # (index, &obj, method, self) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException andb $$0xf, rINSTbl # rINSTbl <- A diff --git a/runtime/interpreter/mterp/x86/op_iput.S b/runtime/interpreter/mterp/x86/op_iput.S index 13cfe5ca69..c847e2dc88 100644 --- a/runtime/interpreter/mterp/x86/op_iput.S +++ b/runtime/interpreter/mterp/x86/op_iput.S @@ -19,7 +19,7 @@ movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL($handler) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_iput_object.S b/runtime/interpreter/mterp/x86/op_iput_object.S index f63075c503..e0136970b0 100644 --- a/runtime/interpreter/mterp/x86/op_iput_object.S +++ b/runtime/interpreter/mterp/x86/op_iput_object.S @@ -7,7 +7,7 @@ movl rSELF, %eax movl %eax, OUT_ARG3(%esp) call SYMBOL(MterpIputObject) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_iput_object_quick.S b/runtime/interpreter/mterp/x86/op_iput_object_quick.S index d54b1b772f..cb779295b7 100644 --- a/runtime/interpreter/mterp/x86/op_iput_object_quick.S +++ b/runtime/interpreter/mterp/x86/op_iput_object_quick.S @@ -5,7 +5,7 @@ REFRESH_INST ${opnum} movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpIputObjectQuick) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_iput_wide.S b/runtime/interpreter/mterp/x86/op_iput_wide.S index 573e14d663..122eecf43f 100644 --- a/runtime/interpreter/mterp/x86/op_iput_wide.S +++ b/runtime/interpreter/mterp/x86/op_iput_wide.S @@ -13,7 +13,7 @@ movl OFF_FP_METHOD(rFP), %eax movl %eax, OUT_ARG3(%esp) # referrer call SYMBOL(artSet64InstanceFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpPossibleException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_monitor_enter.S b/runtime/interpreter/mterp/x86/op_monitor_enter.S index 9e885bde93..b35c68488a 100644 --- a/runtime/interpreter/mterp/x86/op_monitor_enter.S +++ b/runtime/interpreter/mterp/x86/op_monitor_enter.S @@ -8,7 +8,7 @@ movl rSELF, %eax movl %eax, OUT_ARG1(%esp) call SYMBOL(artLockObjectFromCode) # (object, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpException ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 diff --git a/runtime/interpreter/mterp/x86/op_monitor_exit.S b/runtime/interpreter/mterp/x86/op_monitor_exit.S index 090480056a..2d17d5e7c5 100644 --- a/runtime/interpreter/mterp/x86/op_monitor_exit.S +++ b/runtime/interpreter/mterp/x86/op_monitor_exit.S @@ -12,7 +12,7 @@ movl rSELF, %eax movl %eax, OUT_ARG1(%esp) call SYMBOL(artUnlockObjectFromCode) # (object, self) - REFRESH_IBASE - testl %eax, %eax + RESTORE_IBASE + testb %al, %al jnz MterpException ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 diff --git a/runtime/interpreter/mterp/x86/op_mul_int_2addr.S b/runtime/interpreter/mterp/x86/op_mul_int_2addr.S index f92a28e46a..da699ae19b 100644 --- a/runtime/interpreter/mterp/x86/op_mul_int_2addr.S +++ b/runtime/interpreter/mterp/x86/op_mul_int_2addr.S @@ -3,8 +3,8 @@ sarl $$4, rINST # rINST <- B GET_VREG %eax, rINST # eax <- vB andb $$0xf, %cl # ecx <- A - mov rIBASE, LOCAL0(%esp) + movl rIBASE, rINST imull (rFP,%ecx,4), %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + movl rINST, rIBASE SET_VREG %eax, %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 diff --git a/runtime/interpreter/mterp/x86/op_mul_int_lit16.S b/runtime/interpreter/mterp/x86/op_mul_int_lit16.S index 31ab613805..056f491bef 100644 --- a/runtime/interpreter/mterp/x86/op_mul_int_lit16.S +++ b/runtime/interpreter/mterp/x86/op_mul_int_lit16.S @@ -3,10 +3,10 @@ movzbl rINSTbl, %eax # eax <- 000000BA sarl $$4, %eax # eax <- B GET_VREG %eax, %eax # eax <- vB - movswl 2(rPC), %ecx # ecx <- ssssCCCC + movl rIBASE, %ecx + movswl 2(rPC), rIBASE # rIBASE <- ssssCCCC andb $$0xf, rINSTbl # rINST <- A - mov rIBASE, LOCAL0(%esp) - imull %ecx, %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + imull rIBASE, %eax # trashes rIBASE/edx + movl %ecx, rIBASE SET_VREG %eax, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_mul_int_lit8.S b/runtime/interpreter/mterp/x86/op_mul_int_lit8.S index 6637aa7384..59b384426c 100644 --- a/runtime/interpreter/mterp/x86/op_mul_int_lit8.S +++ b/runtime/interpreter/mterp/x86/op_mul_int_lit8.S @@ -1,9 +1,9 @@ /* mul/lit8 vAA, vBB, #+CC */ movzbl 2(rPC), %eax # eax <- BB - movsbl 3(rPC), %ecx # ecx <- ssssssCC + movl rIBASE, %ecx GET_VREG %eax, %eax # eax <- rBB - mov rIBASE, LOCAL0(%esp) - imull %ecx, %eax # trashes rIBASE/edx - mov LOCAL0(%esp), rIBASE + movsbl 3(rPC), rIBASE # rIBASE <- ssssssCC + imull rIBASE, %eax # trashes rIBASE/edx + movl %ecx, rIBASE SET_VREG %eax, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_new_array.S b/runtime/interpreter/mterp/x86/op_new_array.S index 24904774e1..16226e989c 100644 --- a/runtime/interpreter/mterp/x86/op_new_array.S +++ b/runtime/interpreter/mterp/x86/op_new_array.S @@ -15,7 +15,7 @@ movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpNewArray) - REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + RESTORE_IBASE + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_new_instance.S b/runtime/interpreter/mterp/x86/op_new_instance.S index 712a5ebe96..f976accb1e 100644 --- a/runtime/interpreter/mterp/x86/op_new_instance.S +++ b/runtime/interpreter/mterp/x86/op_new_instance.S @@ -10,7 +10,7 @@ REFRESH_INST ${opnum} movl rINST, OUT_ARG2(%esp) call SYMBOL(MterpNewInstance) - REFRESH_IBASE - testl %eax, %eax # 0 means an exception is thrown + RESTORE_IBASE + testb %al, %al # 0 means an exception is thrown jz MterpPossibleException ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_sget.S b/runtime/interpreter/mterp/x86/op_sget.S index ec964581af..0e9a3d82da 100644 --- a/runtime/interpreter/mterp/x86/op_sget.S +++ b/runtime/interpreter/mterp/x86/op_sget.S @@ -15,7 +15,7 @@ movl %ecx, OUT_ARG2(%esp) # self call SYMBOL($helper) movl rSELF, %ecx - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx) jnz MterpException .if $is_object diff --git a/runtime/interpreter/mterp/x86/op_sget_wide.S b/runtime/interpreter/mterp/x86/op_sget_wide.S index 833f266dd5..2b603034c6 100644 --- a/runtime/interpreter/mterp/x86/op_sget_wide.S +++ b/runtime/interpreter/mterp/x86/op_sget_wide.S @@ -17,5 +17,5 @@ jnz MterpException SET_VREG %eax, rINST # fp[A]<- low part SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part - REFRESH_IBASE_FROM_SELF %ecx + RESTORE_IBASE_FROM_SELF %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_sput.S b/runtime/interpreter/mterp/x86/op_sput.S index a199281088..0b5de0953d 100644 --- a/runtime/interpreter/mterp/x86/op_sput.S +++ b/runtime/interpreter/mterp/x86/op_sput.S @@ -16,7 +16,7 @@ movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL($helper) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_sput_object.S b/runtime/interpreter/mterp/x86/op_sput_object.S index e3e57fc87b..0db517723b 100644 --- a/runtime/interpreter/mterp/x86/op_sput_object.S +++ b/runtime/interpreter/mterp/x86/op_sput_object.S @@ -7,7 +7,7 @@ movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) call SYMBOL(MterpSputObject) - testl %eax, %eax + testb %al, %al jz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/interpreter/mterp/x86/op_sput_wide.S b/runtime/interpreter/mterp/x86/op_sput_wide.S index 7544838d52..19cff0db5a 100644 --- a/runtime/interpreter/mterp/x86/op_sput_wide.S +++ b/runtime/interpreter/mterp/x86/op_sput_wide.S @@ -14,7 +14,7 @@ movl rSELF, %ecx movl %ecx, OUT_ARG3(%esp) # self call SYMBOL(artSet64IndirectStaticFromMterp) - testl %eax, %eax + testb %al, %al jnz MterpException - REFRESH_IBASE + RESTORE_IBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 8d3da37762..bdc7ee2428 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -113,8 +113,7 @@ bool Jit::LoadCompiler(std::string* error_msg) { *error_msg = oss.str(); return false; } - jit_load_ = reinterpret_cast<void* (*)(CompilerCallbacks**, bool*)>( - dlsym(jit_library_handle_, "jit_load")); + jit_load_ = reinterpret_cast<void* (*)(bool*)>(dlsym(jit_library_handle_, "jit_load")); if (jit_load_ == nullptr) { dlclose(jit_library_handle_); *error_msg = "JIT couldn't find jit_load entry point"; @@ -141,23 +140,15 @@ bool Jit::LoadCompiler(std::string* error_msg) { *error_msg = "JIT couldn't find jit_types_loaded entry point"; return false; } - CompilerCallbacks* callbacks = nullptr; bool will_generate_debug_symbols = false; VLOG(jit) << "Calling JitLoad interpreter_only=" << Runtime::Current()->GetInstrumentation()->InterpretOnly(); - jit_compiler_handle_ = (jit_load_)(&callbacks, &will_generate_debug_symbols); + jit_compiler_handle_ = (jit_load_)(&will_generate_debug_symbols); if (jit_compiler_handle_ == nullptr) { dlclose(jit_library_handle_); *error_msg = "JIT couldn't load compiler"; return false; } - if (callbacks == nullptr) { - dlclose(jit_library_handle_); - *error_msg = "JIT compiler callbacks were not set"; - jit_compiler_handle_ = nullptr; - return false; - } - compiler_callbacks_ = callbacks; generate_debug_info_ = will_generate_debug_symbols; return true; } diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h index 042da92b3b..109ca3dbd1 100644 --- a/runtime/jit/jit.h +++ b/runtime/jit/jit.h @@ -32,7 +32,6 @@ namespace art { class ArtMethod; -class CompilerCallbacks; struct RuntimeArgumentMap; namespace jit { @@ -55,9 +54,6 @@ class Jit { size_t warmup_threshold, size_t osr_threshold); void CreateThreadPool(); - CompilerCallbacks* GetCompilerCallbacks() { - return compiler_callbacks_; - } const JitCodeCache* GetCodeCache() const { return code_cache_.get(); } @@ -108,7 +104,7 @@ class Jit { // JIT compiler void* jit_library_handle_; void* jit_compiler_handle_; - void* (*jit_load_)(CompilerCallbacks**, bool*); + void* (*jit_load_)(bool*); void (*jit_unload_)(void*); bool (*jit_compile_method_)(void*, ArtMethod*, Thread*, bool); void (*jit_types_loaded_)(void*, mirror::Class**, size_t count); @@ -119,7 +115,6 @@ class Jit { std::unique_ptr<jit::JitInstrumentationCache> instrumentation_cache_; std::unique_ptr<jit::JitCodeCache> code_cache_; - CompilerCallbacks* compiler_callbacks_; // Owned by the jit compiler. bool save_profiling_info_; bool generate_debug_info_; diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index f9d916a92e..d64aa432fc 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -394,6 +394,7 @@ bool ParsedOptions::ProcessSpecialOptions(const RuntimeOptions& options, // Intended for local changes only. static void MaybeOverrideVerbosity() { // gLogVerbosity.class_linker = true; // TODO: don't check this in! + // gLogVerbosity.collector = true; // TODO: don't check this in! // gLogVerbosity.compiler = true; // TODO: don't check this in! // gLogVerbosity.deopt = true; // TODO: don't check this in! // gLogVerbosity.gc = true; // TODO: don't check this in! diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 2aeb7921ce..861bd85283 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1887,7 +1887,6 @@ void Runtime::CreateJit() { std::string error_msg; jit_.reset(jit::Jit::Create(jit_options_.get(), &error_msg)); if (jit_.get() != nullptr) { - compiler_callbacks_ = jit_->GetCompilerCallbacks(); jit_->CreateInstrumentationCache(jit_options_->GetCompileThreshold(), jit_options_->GetWarmupThreshold(), jit_options_->GetOsrThreshold()); diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh index e4af9fa0d7..fda630fe5d 100755 --- a/tools/run-jdwp-tests.sh +++ b/tools/run-jdwp-tests.sh @@ -133,7 +133,7 @@ vogar $vm_command \ --vm-arg -Djpda.settings.transportAddress=127.0.0.1:55107 \ --vm-arg -Djpda.settings.debuggeeJavaPath="$art_debugee $image $debuggee_args" \ --classpath $test_jack \ - --toolchain jack --language JN \ + --toolchain jack \ --vm-arg -Xcompiler-option --vm-arg --debuggable \ $test |