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
diff --git a/oatdump/oatdump_app_test.cc b/oatdump/oatdump_app_test.cc
index 4490647..bbd0e3d 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 0a076f0..6f6b83b 100644
--- a/oatdump/oatdump_image_test.cc
+++ b/oatdump/oatdump_image_test.cc
@@ -28,25 +28,25 @@
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 506fde7..87f9ac6 100644
--- a/oatdump/oatdump_test.cc
+++ b/oatdump/oatdump_test.cc
@@ -30,61 +30,61 @@
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 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_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 359b060..997321f 100644
--- a/oatdump/oatdump_test.h
+++ b/oatdump/oatdump_test.h
@@ -66,8 +66,8 @@
// 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 @@
}
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 fc3005d..d22771d 100644
--- a/runtime/interpreter/interpreter_switch_impl-inl.h
+++ b/runtime/interpreter/interpreter_switch_impl-inl.h
@@ -1917,6 +1917,7 @@
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 12b3dab..95bc864 100644
--- a/runtime/interpreter/mterp/arm/main.S
+++ b/runtime/interpreter/mterp/arm/main.S
@@ -109,12 +109,10 @@
*/
#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 @@
* 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 @@
/* 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 @@
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 fd745f1..e16b51c 100644
--- a/runtime/interpreter/mterp/arm64/main.S
+++ b/runtime/interpreter/mterp/arm64/main.S
@@ -115,12 +115,10 @@
*/
#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 @@
* 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 @@
/* 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 @@
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 80ebf21..57ebfac 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -554,14 +554,10 @@
}
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 af52758..d8fe358 100644
--- a/runtime/interpreter/mterp/mterp.h
+++ b/runtime/interpreter/mterp/mterp.h
@@ -40,8 +40,8 @@
// 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 8df75d2..03cbf49 100644
--- a/runtime/interpreter/mterp/x86/main.S
+++ b/runtime/interpreter/mterp/x86/main.S
@@ -131,12 +131,10 @@
*/
#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 @@
* 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 @@
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 @@
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 5f1fd2d..11e4d61 100644
--- a/runtime/interpreter/mterp/x86_64/main.S
+++ b/runtime/interpreter/mterp/x86_64/main.S
@@ -127,12 +127,10 @@
*/
#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 @@
* 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 @@
/* 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 @@
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 8cb2b33..b0fa4a3 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 @@
}
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 @@
}
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 @@
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 @@
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 @@
: 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 @@
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 10a309c..5bf3bef 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,