diff options
author | 2019-06-26 15:05:43 +0100 | |
---|---|---|
committer | 2019-07-03 14:21:47 +0000 | |
commit | 50bc8fb89c79874e731f245abda3b9e48a541cfe (patch) | |
tree | c4dd3d8291ceac4b1d9b7dbca9886842c33967f2 | |
parent | 8c344524e5251535e49cbe8e68ab5dc1cd7d1591 (diff) |
Remove ShadowFrame::dex_pc_ (but keep dex_pc_ptr_)
They store the same information which is redundant and error prone.
Test: ./art/test.py --interpreter
Change-Id: I379c20973b90645e3c1016c253d9a6db9a2417dc
-rw-r--r-- | oatdump/oatdump_app_test.cc | 16 | ||||
-rw-r--r-- | oatdump/oatdump_image_test.cc | 8 | ||||
-rw-r--r-- | oatdump/oatdump_test.cc | 28 | ||||
-rw-r--r-- | oatdump/oatdump_test.h | 6 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl-inl.h | 1 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm/main.S | 31 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm64/main.S | 23 | ||||
-rw-r--r-- | runtime/interpreter/mterp/mterp.cc | 10 | ||||
-rw-r--r-- | runtime/interpreter/mterp/mterp.h | 4 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86/main.S | 21 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86_64/main.S | 20 | ||||
-rw-r--r-- | runtime/interpreter/shadow_frame.h | 24 | ||||
-rw-r--r-- | tools/cpp-define-generator/shadow_frame.def | 4 |
13 files changed, 54 insertions, 142 deletions
diff --git a/oatdump/oatdump_app_test.cc b/oatdump/oatdump_app_test.cc index 4490647d2c..bbd0e3d34c 100644 --- a/oatdump/oatdump_app_test.cc +++ b/oatdump/oatdump_app_test.cc @@ -19,27 +19,27 @@ namespace art { TEST_F(OatDumpTest, TestAppWithBootImage) { - ASSERT_TRUE(GenerateAppOdexFile(kDynamic, {"--runtime-arg", "-Xmx64M"})); - ASSERT_TRUE(Exec(kDynamic, kModeOatWithBootImage, {}, kListAndCode)); + ASSERT_TRUE(GenerateAppOdexFile(kDynamicLinking, {"--runtime-arg", "-Xmx64M"})); + ASSERT_TRUE(Exec(kDynamicLinking, kModeOatWithBootImage, {}, kListAndCode)); } TEST_F(OatDumpTest, TestAppWithBootImageStatic) { TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); - ASSERT_TRUE(GenerateAppOdexFile(kStatic, {"--runtime-arg", "-Xmx64M"})); - ASSERT_TRUE(Exec(kStatic, kModeOatWithBootImage, {}, kListAndCode)); + ASSERT_TRUE(GenerateAppOdexFile(kStaticLinking, {"--runtime-arg", "-Xmx64M"})); + ASSERT_TRUE(Exec(kStaticLinking, kModeOatWithBootImage, {}, kListAndCode)); } TEST_F(OatDumpTest, TestAppImageWithBootImage) { TEST_DISABLED_WITHOUT_BAKER_READ_BARRIERS(); // GC bug, b/126305867 const std::string app_image_arg = "--app-image-file=" + GetAppImageName(); - ASSERT_TRUE(GenerateAppOdexFile(kDynamic, {"--runtime-arg", "-Xmx64M", app_image_arg})); - ASSERT_TRUE(Exec(kDynamic, kModeAppImage, {}, kListAndCode)); + ASSERT_TRUE(GenerateAppOdexFile(kDynamicLinking, {"--runtime-arg", "-Xmx64M", app_image_arg})); + ASSERT_TRUE(Exec(kDynamicLinking, kModeAppImage, {}, kListAndCode)); } TEST_F(OatDumpTest, TestAppImageWithBootImageStatic) { TEST_DISABLED_WITHOUT_BAKER_READ_BARRIERS(); // GC bug, b/126305867 TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); const std::string app_image_arg = "--app-image-file=" + GetAppImageName(); - ASSERT_TRUE(GenerateAppOdexFile(kStatic, {"--runtime-arg", "-Xmx64M", app_image_arg})); - ASSERT_TRUE(Exec(kStatic, kModeAppImage, {}, kListAndCode)); + ASSERT_TRUE(GenerateAppOdexFile(kStaticLinking, {"--runtime-arg", "-Xmx64M", app_image_arg})); + ASSERT_TRUE(Exec(kStaticLinking, kModeAppImage, {}, kListAndCode)); } } // namespace art diff --git a/oatdump/oatdump_image_test.cc b/oatdump/oatdump_image_test.cc index 0a076f065e..6f6b83bc53 100644 --- a/oatdump/oatdump_image_test.cc +++ b/oatdump/oatdump_image_test.cc @@ -28,25 +28,25 @@ namespace art { TEST_F(OatDumpTest, TestImage) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeArt, {}, kListAndCode)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeArt, {}, kListAndCode)); } TEST_F(OatDumpTest, TestImageStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeArt, {}, kListAndCode)); + ASSERT_TRUE(Exec(kStaticLinking, kModeArt, {}, kListAndCode)); } TEST_F(OatDumpTest, TestOatImage) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeCoreOat, {}, kListAndCode)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeCoreOat, {}, kListAndCode)); } TEST_F(OatDumpTest, TestOatImageStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeCoreOat, {}, kListAndCode)); + ASSERT_TRUE(Exec(kStaticLinking, kModeCoreOat, {}, kListAndCode)); } } // namespace art diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc index 506fde776b..87f9ac69ca 100644 --- a/oatdump/oatdump_test.cc +++ b/oatdump/oatdump_test.cc @@ -30,61 +30,61 @@ namespace art { TEST_F(OatDumpTest, TestNoDumpVmap) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeArt, {"--no-dump:vmap"}, kListAndCode)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeArt, {"--no-dump:vmap"}, kListAndCode)); } TEST_F(OatDumpTest, TestNoDumpVmapStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeArt, {"--no-dump:vmap"}, kListAndCode)); + ASSERT_TRUE(Exec(kStaticLinking, kModeArt, {"--no-dump:vmap"}, kListAndCode)); } TEST_F(OatDumpTest, TestNoDisassemble) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeArt, {"--no-disassemble"}, kListAndCode)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeArt, {"--no-disassemble"}, kListAndCode)); } TEST_F(OatDumpTest, TestNoDisassembleStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeArt, {"--no-disassemble"}, kListAndCode)); + ASSERT_TRUE(Exec(kStaticLinking, kModeArt, {"--no-disassemble"}, kListAndCode)); } TEST_F(OatDumpTest, TestListClasses) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeArt, {"--list-classes"}, kListOnly)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeArt, {"--list-classes"}, kListOnly)); } TEST_F(OatDumpTest, TestListClassesStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeArt, {"--list-classes"}, kListOnly)); + ASSERT_TRUE(Exec(kStaticLinking, kModeArt, {"--list-classes"}, kListOnly)); } TEST_F(OatDumpTest, TestListMethods) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeArt, {"--list-methods"}, kListOnly)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeArt, {"--list-methods"}, kListOnly)); } TEST_F(OatDumpTest, TestListMethodsStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeArt, {"--list-methods"}, kListOnly)); + ASSERT_TRUE(Exec(kStaticLinking, kModeArt, {"--list-methods"}, kListOnly)); } TEST_F(OatDumpTest, TestSymbolize) { TEST_DISABLED_FOR_ARM_AND_MIPS(); std::string error_msg; - ASSERT_TRUE(Exec(kDynamic, kModeSymbolize, {}, kListOnly)); + ASSERT_TRUE(Exec(kDynamicLinking, kModeSymbolize, {}, kListOnly)); } TEST_F(OatDumpTest, TestSymbolizeStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(Exec(kStatic, kModeSymbolize, {}, kListOnly)); + ASSERT_TRUE(Exec(kStaticLinking, kModeSymbolize, {}, kListOnly)); } TEST_F(OatDumpTest, TestExportDex) { @@ -92,8 +92,8 @@ TEST_F(OatDumpTest, TestExportDex) { // Test is failing on target, b/77469384. TEST_DISABLED_FOR_TARGET(); std::string error_msg; - ASSERT_TRUE(GenerateAppOdexFile(kDynamic, {"--runtime-arg", "-Xmx64M"})); - ASSERT_TRUE(Exec(kDynamic, kModeOat, {"--export-dex-to=" + tmp_dir_}, kListOnly)); + ASSERT_TRUE(GenerateAppOdexFile(kDynamicLinking, {"--runtime-arg", "-Xmx64M"})); + ASSERT_TRUE(Exec(kDynamicLinking, kModeOat, {"--export-dex-to=" + tmp_dir_}, kListOnly)); const std::string dex_location = tmp_dir_+ "/" + android::base::Basename(GetTestDexFileName(GetAppBaseName().c_str())) + "_export.dex"; @@ -109,8 +109,8 @@ TEST_F(OatDumpTest, TestExportDexStatic) { TEST_DISABLED_FOR_ARM_AND_MIPS(); TEST_DISABLED_FOR_NON_STATIC_HOST_BUILDS(); std::string error_msg; - ASSERT_TRUE(GenerateAppOdexFile(kStatic, {"--runtime-arg", "-Xmx64M"})); - ASSERT_TRUE(Exec(kStatic, kModeOat, {"--export-dex-to=" + tmp_dir_}, kListOnly)); + ASSERT_TRUE(GenerateAppOdexFile(kStaticLinking, {"--runtime-arg", "-Xmx64M"})); + ASSERT_TRUE(Exec(kStaticLinking, kModeOat, {"--export-dex-to=" + tmp_dir_}, kListOnly)); } } // namespace art diff --git a/oatdump/oatdump_test.h b/oatdump/oatdump_test.h index 359b060f1f..997321f1b3 100644 --- a/oatdump/oatdump_test.h +++ b/oatdump/oatdump_test.h @@ -66,8 +66,8 @@ class OatDumpTest : public CommonRuntimeTest { // Linking flavor. enum Flavor { - kDynamic, // oatdump(d), dex2oat(d) - kStatic, // oatdump(d)s, dex2oat(d)s + kDynamicLinking, // oatdump(d), dex2oat(d) + kStaticLinking, // oatdump(d)s, dex2oat(d)s }; // Returns path to the oatdump/dex2oat/dexdump binary. @@ -83,7 +83,7 @@ class OatDumpTest : public CommonRuntimeTest { } std::string GetExecutableFilePath(Flavor flavor, const char* name) { - return GetExecutableFilePath(name, kIsDebugBuild, flavor == kStatic); + return GetExecutableFilePath(name, kIsDebugBuild, flavor == kStaticLinking); } enum Mode { diff --git a/runtime/interpreter/interpreter_switch_impl-inl.h b/runtime/interpreter/interpreter_switch_impl-inl.h index fc3005d72c..d22771dea8 100644 --- a/runtime/interpreter/interpreter_switch_impl-inl.h +++ b/runtime/interpreter/interpreter_switch_impl-inl.h @@ -1917,6 +1917,7 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) self->VerifyStack(); uint32_t dex_pc = shadow_frame.GetDexPC(); + DCHECK_LT(dex_pc, shadow_frame.GetMethod()->DexInstructionData().InsnsSizeInCodeUnits()); const auto* const instrumentation = Runtime::Current()->GetInstrumentation(); const uint16_t* const insns = accessor.Insns(); const Instruction* next = Instruction::At(insns + dex_pc); diff --git a/runtime/interpreter/mterp/arm/main.S b/runtime/interpreter/mterp/arm/main.S index 12b3dab003..95bc864ad9 100644 --- a/runtime/interpreter/mterp/arm/main.S +++ b/runtime/interpreter/mterp/arm/main.S @@ -109,12 +109,10 @@ unspecified registers or condition codes. */ #define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET) #define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET) -#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET) #define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET) #define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET) #define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET) #define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET) -#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET) #define OFF_FP_SHADOWFRAME OFF_FP(0) /* @@ -122,25 +120,11 @@ unspecified registers or condition codes. * be done *before* something throws. * * It's okay to do this more than once. - * - * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped - * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction - * offset into the code_items_[] array. For effiency, we will "export" the - * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC - * to convert to a dex pc when needed. */ .macro EXPORT_PC str rPC, [rFP, #OFF_FP_DEX_PC_PTR] .endm -.macro EXPORT_DEX_PC tmp - ldr \tmp, [rFP, #OFF_FP_DEX_INSTRUCTIONS] - str rPC, [rFP, #OFF_FP_DEX_PC_PTR] - sub \tmp, rPC, \tmp - asr \tmp, #1 - str \tmp, [rFP, #OFF_FP_DEX_PC] -.endm - /* * Fetch the next instruction from rPC into rINST. Does not advance rPC. */ @@ -398,18 +382,13 @@ ENTRY ExecuteMterpImpl /* Remember the return register */ str r3, [r2, #SHADOWFRAME_RESULT_REGISTER_OFFSET] - /* Remember the dex instruction pointer */ - str r1, [r2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET] - /* set up "named" registers */ mov rSELF, r0 ldr r0, [r2, #SHADOWFRAME_NUMBER_OF_VREGS_OFFSET] - add rFP, r2, #SHADOWFRAME_VREGS_OFFSET @ point to vregs. - VREG_INDEX_TO_ADDR rREFS, r0 @ point to reference array in shadow frame - ldr r0, [r2, #SHADOWFRAME_DEX_PC_OFFSET] @ Get starting dex_pc. - add rPC, r1, r0, lsl #1 @ Create direct pointer to 1st dex opcode + add rFP, r2, #SHADOWFRAME_VREGS_OFFSET @ pointer to vregs. + VREG_INDEX_TO_ADDR rREFS, r0 @ pointer to reference array in shadow frame + ldr rPC, [r2, #SHADOWFRAME_DEX_PC_PTR_OFFSET] @ pointer to current dex instruction. CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) - EXPORT_PC /* Starting ibase */ ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @@ -551,10 +530,8 @@ MterpException: bl MterpHandleException @ (self, shadow_frame) cmp r0, #0 beq MterpExceptionReturn @ no local catch, back to caller. - ldr r0, [rFP, #OFF_FP_DEX_INSTRUCTIONS] - ldr r1, [rFP, #OFF_FP_DEX_PC] ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] - add rPC, r0, r1, lsl #1 @ generate new dex_pc_ptr + ldr rPC, [rFP, #OFF_FP_DEX_PC_PTR] @ reload dex pc pointer. /* Do we need to switch interpreters? */ ldr r0, [rSELF, #THREAD_USE_MTERP_OFFSET] cmp r0, #0 diff --git a/runtime/interpreter/mterp/arm64/main.S b/runtime/interpreter/mterp/arm64/main.S index fd745f1bd1..e16b51cb08 100644 --- a/runtime/interpreter/mterp/arm64/main.S +++ b/runtime/interpreter/mterp/arm64/main.S @@ -115,12 +115,10 @@ codes. */ #define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET) #define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET) -#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET) #define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET) #define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET) #define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET) #define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET) -#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET) #define OFF_FP_SHADOWFRAME OFF_FP(0) /* @@ -128,12 +126,6 @@ codes. * be done *before* something throws. * * It's okay to do this more than once. - * - * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped - * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction - * offset into the code_items_[] array. For effiency, we will "export" the - * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC - * to convert to a dex pc when needed. */ .macro EXPORT_PC str xPC, [xFP, #OFF_FP_DEX_PC_PTR] @@ -411,18 +403,13 @@ ENTRY ExecuteMterpImpl /* Remember the return register */ str x3, [x2, #SHADOWFRAME_RESULT_REGISTER_OFFSET] - /* Remember the dex instruction pointer */ - str x1, [x2, #SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET] - /* set up "named" registers */ mov xSELF, x0 ldr w0, [x2, #SHADOWFRAME_NUMBER_OF_VREGS_OFFSET] - add xFP, x2, #SHADOWFRAME_VREGS_OFFSET // point to vregs. - add xREFS, xFP, w0, uxtw #2 // point to reference array in shadow frame - ldr w0, [x2, #SHADOWFRAME_DEX_PC_OFFSET] // Get starting dex_pc. - add xPC, x1, w0, uxtw #1 // Create direct pointer to 1st dex opcode + add xFP, x2, #SHADOWFRAME_VREGS_OFFSET // pointer to vregs. + add xREFS, xFP, w0, uxtw #2 // pointer to reference array in shadow frame + ldr xPC, [x2, #SHADOWFRAME_DEX_PC_PTR_OFFSET] // pointer to current dex instruction. CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) - EXPORT_PC /* Starting ibase */ ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] @@ -561,10 +548,8 @@ MterpException: add x1, xFP, #OFF_FP_SHADOWFRAME bl MterpHandleException // (self, shadow_frame) cbz w0, MterpExceptionReturn // no local catch, back to caller. - ldr x0, [xFP, #OFF_FP_DEX_INSTRUCTIONS] - ldr w1, [xFP, #OFF_FP_DEX_PC] ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] - add xPC, x0, x1, lsl #1 // generate new dex_pc_ptr + ldr xPC, [xFP, #OFF_FP_DEX_PC_PTR] // reload dex pc pointer. /* Do we need to switch interpreters? */ ldr w0, [xSELF, #THREAD_USE_MTERP_OFFSET] cbz w0, MterpFallback diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index 80ebf21b40..57ebface31 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -554,14 +554,10 @@ extern "C" void MterpCheckBefore(Thread* self, ShadowFrame* shadow_frame, uint16 } DCHECK(!Runtime::Current()->IsActiveTransaction()); const Instruction* inst = Instruction::At(dex_pc_ptr); - uint16_t inst_data = inst->Fetch16(0); - if (inst->Opcode(inst_data) == Instruction::MOVE_EXCEPTION) { - self->AssertPendingException(); - } else { - self->AssertNoPendingException(); - } + DCHECK_EQ(self->IsExceptionPending(), inst->Opcode() == Instruction::MOVE_EXCEPTION); + uint32_t dex_pc = dex_pc_ptr - shadow_frame->GetDexInstructions(); + DCHECK_LT(dex_pc, shadow_frame->GetMethod()->DexInstructionData().InsnsSizeInCodeUnits()); if (kTraceExecutionEnabled) { - uint32_t dex_pc = dex_pc_ptr - shadow_frame->GetDexInstructions(); TraceExecution(*shadow_frame, inst, dex_pc); } if (kTestExportPC) { diff --git a/runtime/interpreter/mterp/mterp.h b/runtime/interpreter/mterp/mterp.h index af52758bbc..d8fe358885 100644 --- a/runtime/interpreter/mterp/mterp.h +++ b/runtime/interpreter/mterp/mterp.h @@ -40,8 +40,8 @@ bool CanUseMterp(); // handler for a recent opcode failed to export the Dalvik PC prior to a possible exit from // the mterp environment. constexpr uintptr_t kExportPCPoison = 0xdead00ff; -// Set true to enable poison testing of ExportPC. Uses Alt interpreter. -constexpr bool kTestExportPC = false; +// Set true to enable poison testing of ExportPC. +constexpr bool kTestExportPC = true; constexpr size_t kMterpHandlerSize = 128; diff --git a/runtime/interpreter/mterp/x86/main.S b/runtime/interpreter/mterp/x86/main.S index 8df75d2f66..03cbf49a06 100644 --- a/runtime/interpreter/mterp/x86/main.S +++ b/runtime/interpreter/mterp/x86/main.S @@ -131,12 +131,10 @@ unspecified registers or condition codes. */ #define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET) #define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET) -#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET) #define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET) #define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET) #define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET) #define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET) -#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET) #define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET) #define OFF_FP_SHADOWFRAME OFF_FP(0) @@ -182,12 +180,6 @@ unspecified registers or condition codes. * be done *before* something throws. * * It's okay to do this more than once. - * - * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped - * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction - * offset into the code_items_[] array. For effiency, we will "export" the - * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC - * to convert to a dex pc when needed. */ .macro EXPORT_PC movl rPC, OFF_FP_DEX_PC_PTR(rFP) @@ -393,18 +385,12 @@ ENTRY ExecuteMterpImpl movl IN_ARG3(%esp), %eax movl %eax, SHADOWFRAME_RESULT_REGISTER_OFFSET(%edx) - /* Remember the code_item */ - movl IN_ARG1(%esp), %ecx - movl %ecx, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(%edx) - /* set up "named" registers */ movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(%edx), %eax leal SHADOWFRAME_VREGS_OFFSET(%edx), rFP leal (rFP, %eax, 4), rREFS - movl SHADOWFRAME_DEX_PC_OFFSET(%edx), %eax - lea (%ecx, %eax, 2), rPC + movl SHADOWFRAME_DEX_PC_PTR_OFFSET(%edx), rPC CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) - EXPORT_PC /* Set up for backwards branches & osr profiling */ movl OFF_FP_METHOD(rFP), %eax @@ -570,10 +556,7 @@ MterpException: call SYMBOL(MterpHandleException) testb %al, %al jz MterpExceptionReturn - movl OFF_FP_DEX_INSTRUCTIONS(rFP), %eax - movl OFF_FP_DEX_PC(rFP), %ecx - lea (%eax, %ecx, 2), rPC - movl rPC, OFF_FP_DEX_PC_PTR(rFP) + movl OFF_FP_DEX_PC_PTR(rFP), rPC /* Do we need to switch interpreters? */ movl rSELF, %eax cmpb LITERAL(0), THREAD_USE_MTERP_OFFSET(%eax) diff --git a/runtime/interpreter/mterp/x86_64/main.S b/runtime/interpreter/mterp/x86_64/main.S index 5f1fd2dfbe..11e4d616d6 100644 --- a/runtime/interpreter/mterp/x86_64/main.S +++ b/runtime/interpreter/mterp/x86_64/main.S @@ -127,12 +127,10 @@ unspecified registers or condition codes. */ #define OFF_FP(a) (a - SHADOWFRAME_VREGS_OFFSET) #define OFF_FP_NUMBER_OF_VREGS OFF_FP(SHADOWFRAME_NUMBER_OF_VREGS_OFFSET) -#define OFF_FP_DEX_PC OFF_FP(SHADOWFRAME_DEX_PC_OFFSET) #define OFF_FP_LINK OFF_FP(SHADOWFRAME_LINK_OFFSET) #define OFF_FP_METHOD OFF_FP(SHADOWFRAME_METHOD_OFFSET) #define OFF_FP_RESULT_REGISTER OFF_FP(SHADOWFRAME_RESULT_REGISTER_OFFSET) #define OFF_FP_DEX_PC_PTR OFF_FP(SHADOWFRAME_DEX_PC_PTR_OFFSET) -#define OFF_FP_DEX_INSTRUCTIONS OFF_FP(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET) #define OFF_FP_COUNTDOWN_OFFSET OFF_FP(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET) #define OFF_FP_SHADOWFRAME (-SHADOWFRAME_VREGS_OFFSET) @@ -183,12 +181,6 @@ unspecified registers or condition codes. * be done *before* something throws. * * It's okay to do this more than once. - * - * NOTE: the fast interpreter keeps track of dex pc as a direct pointer to the mapped - * dex byte codes. However, the rest of the runtime expects dex pc to be an instruction - * offset into the code_items_[] array. For effiency, we will "export" the - * current dex pc as a direct pointer using the EXPORT_PC macro, and rely on GetDexPC - * to convert to a dex pc when needed. */ .macro EXPORT_PC movq rPC, OFF_FP_DEX_PC_PTR(rFP) @@ -380,17 +372,12 @@ ENTRY ExecuteMterpImpl /* Remember the return register */ movq IN_ARG3, SHADOWFRAME_RESULT_REGISTER_OFFSET(IN_ARG2) - /* Remember the code_item */ - movq IN_ARG1, SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET(IN_ARG2) - /* set up "named" registers */ movl SHADOWFRAME_NUMBER_OF_VREGS_OFFSET(IN_ARG2), %eax leaq SHADOWFRAME_VREGS_OFFSET(IN_ARG2), rFP leaq (rFP, %rax, 4), rREFS - movl SHADOWFRAME_DEX_PC_OFFSET(IN_ARG2), %eax - leaq (IN_ARG1, %rax, 2), rPC + movq SHADOWFRAME_DEX_PC_PTR_OFFSET(IN_ARG2), rPC CFI_DEFINE_DEX_PC_WITH_OFFSET(CFI_TMP, CFI_DEX, 0) - EXPORT_PC /* Starting ibase */ movq IN_ARG0, rSELF @@ -536,10 +523,7 @@ MterpException: call SYMBOL(MterpHandleException) testb %al, %al jz MterpExceptionReturn - movq OFF_FP_DEX_INSTRUCTIONS(rFP), %rax - mov OFF_FP_DEX_PC(rFP), %ecx - leaq (%rax, %rcx, 2), rPC - movq rPC, OFF_FP_DEX_PC_PTR(rFP) + movq OFF_FP_DEX_PC_PTR(rFP), rPC /* Do we need to switch interpreters? */ movq rSELF, %rax cmpb LITERAL(0), THREAD_USE_MTERP_OFFSET(%rax) diff --git a/runtime/interpreter/shadow_frame.h b/runtime/interpreter/shadow_frame.h index 8cb2b33a07..b0fa4a3be1 100644 --- a/runtime/interpreter/shadow_frame.h +++ b/runtime/interpreter/shadow_frame.h @@ -21,8 +21,10 @@ #include <cstring> #include <string> +#include "art_method.h" #include "base/locks.h" #include "base/macros.h" +#include "dex/code_item_accessors-inl.h" #include "lock_count_data.h" #include "read_barrier.h" #include "stack_reference.h" @@ -102,7 +104,7 @@ class ShadowFrame { } uint32_t GetDexPC() const { - return (dex_pc_ptr_ == nullptr) ? dex_pc_ : dex_pc_ptr_ - dex_instructions_; + return (dex_pc_ptr_ == nullptr) ? dex::kDexNoIndex : (dex_pc_ptr_ - dex_instructions_); } int16_t GetCachedHotnessCountdown() const { @@ -122,8 +124,7 @@ class ShadowFrame { } void SetDexPC(uint32_t dex_pc) { - dex_pc_ = dex_pc; - dex_pc_ptr_ = nullptr; + dex_pc_ptr_ = (dex_pc == dex::kDexNoIndex) ? nullptr : (dex_instructions_ + dex_pc); } ShadowFrame* GetLink() const { @@ -280,10 +281,6 @@ class ShadowFrame { return OFFSETOF_MEMBER(ShadowFrame, method_); } - static constexpr size_t DexPCOffset() { - return OFFSETOF_MEMBER(ShadowFrame, dex_pc_); - } - static constexpr size_t NumberOfVRegsOffset() { return OFFSETOF_MEMBER(ShadowFrame, number_of_vregs_); } @@ -300,10 +297,6 @@ class ShadowFrame { return OFFSETOF_MEMBER(ShadowFrame, dex_pc_ptr_); } - static constexpr size_t DexInstructionsOffset() { - return OFFSETOF_MEMBER(ShadowFrame, dex_instructions_); - } - static constexpr size_t CachedHotnessCountdownOffset() { return OFFSETOF_MEMBER(ShadowFrame, cached_hotness_countdown_); } @@ -389,10 +382,9 @@ class ShadowFrame { : link_(link), method_(method), result_register_(nullptr), - dex_pc_ptr_(nullptr), - dex_instructions_(nullptr), + dex_instructions_(method == nullptr ? nullptr : method->DexInstructionData().Insns()), + dex_pc_ptr_(dex_instructions_ + dex_pc), number_of_vregs_(num_vregs), - dex_pc_(dex_pc), cached_hotness_countdown_(0), hotness_countdown_(0), frame_flags_(0) { @@ -425,12 +417,10 @@ class ShadowFrame { ShadowFrame* link_; ArtMethod* method_; JValue* result_register_; + const uint16_t* dex_instructions_; // Dex instruction base of the code item. const uint16_t* dex_pc_ptr_; - // Dex instruction base of the code item. - const uint16_t* dex_instructions_; LockCountData lock_count_data_; // This may contain GC roots when lock counting is active. const uint32_t number_of_vregs_; - uint32_t dex_pc_; int16_t cached_hotness_countdown_; int16_t hotness_countdown_; diff --git a/tools/cpp-define-generator/shadow_frame.def b/tools/cpp-define-generator/shadow_frame.def index 10a309cbdb..5bf3befea0 100644 --- a/tools/cpp-define-generator/shadow_frame.def +++ b/tools/cpp-define-generator/shadow_frame.def @@ -20,10 +20,6 @@ ASM_DEFINE(SHADOWFRAME_CACHED_HOTNESS_COUNTDOWN_OFFSET, art::ShadowFrame::CachedHotnessCountdownOffset()) -ASM_DEFINE(SHADOWFRAME_DEX_INSTRUCTIONS_OFFSET, - art::ShadowFrame::DexInstructionsOffset()) -ASM_DEFINE(SHADOWFRAME_DEX_PC_OFFSET, - art::ShadowFrame::DexPCOffset()) ASM_DEFINE(SHADOWFRAME_DEX_PC_PTR_OFFSET, art::ShadowFrame::DexPCPtrOffset()) ASM_DEFINE(SHADOWFRAME_HOTNESS_COUNTDOWN_OFFSET, |