summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/CompilerIR.h13
-rw-r--r--src/compiler/Frontend.cc5
-rw-r--r--src/compiler/codegen/CodegenUtil.cc73
-rw-r--r--src/compiler/codegen/MethodBitcode.cc2
-rw-r--r--src/compiler/codegen/MethodCodegenDriver.cc4
-rw-r--r--src/compiler/codegen/arm/ArmLIR.h1
-rw-r--r--src/compiler/codegen/mips/MipsLIR.h1
-rw-r--r--src/compiler/codegen/x86/X86LIR.h1
-rw-r--r--src/exception_test.cc8
-rw-r--r--src/oatdump.cc7
-rw-r--r--src/object.cc34
-rw-r--r--src/object.h34
-rw-r--r--test/ReferenceMap/stack_walk_refmap_jni.cc36
13 files changed, 157 insertions, 62 deletions
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 56ae4867c3..434320d2e7 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -426,7 +426,18 @@ struct CompilationUnit {
AssemblerStatus assemblerStatus; // Success or fix and retry
int assemblerRetries;
std::vector<uint8_t> codeBuffer;
- std::vector<uint32_t> mappingTable;
+ /*
+ * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
+ * Native PC is on the return address of the safepointed operation. Dex PC is for
+ * the instruction being executed at the safepoint.
+ */
+ std::vector<uint32_t> pc2dexMappingTable;
+ /*
+ * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
+ * immediately preceed the instruction.
+ */
+ std::vector<uint32_t> dex2pcMappingTable;
+ std::vector<uint32_t> combinedMappingTable;
std::vector<uint32_t> coreVmapTable;
std::vector<uint32_t> fpVmapTable;
std::vector<uint8_t> nativeGcMap;
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 31d8aa50a9..09bc054e5e 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -1216,9 +1216,8 @@ CompiledMethod* compileMethod(Compiler& compiler,
}
CompiledMethod* result =
new CompiledMethod(cUnit->instructionSet, cUnit->codeBuffer,
- cUnit->frameSize, cUnit->coreSpillMask,
- cUnit->fpSpillMask, cUnit->mappingTable, vmapTable,
- cUnit->nativeGcMap);
+ cUnit->frameSize, cUnit->coreSpillMask, cUnit->fpSpillMask,
+ cUnit->combinedMappingTable, vmapTable, cUnit->nativeGcMap);
VLOG(compiler) << "Compiled " << PrettyMethod(method_idx, dex_file)
<< " (" << (cUnit->codeBuffer.size() * sizeof(cUnit->codeBuffer[0]))
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index 4e39ffcdf8..22aacc2497 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -341,6 +341,9 @@ void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
case kPseudoSafepointPC:
LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvikOffset << ":";
break;
+ case kPseudoExportedPC:
+ LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvikOffset << ":";
+ break;
case kPseudoCaseLabel:
LOG(INFO) << "LC" << (void*)lir << ": Case target 0x"
<< std::hex << lir->operands[0] << "|" << std::dec <<
@@ -397,6 +400,23 @@ void oatDumpPromotionMap(CompilationUnit *cUnit)
}
}
+/* Dump a mapping table */
+void dumpMappingTable(const char* table_name, const std::string& descriptor,
+ const std::string& name, const std::string& signature,
+ const std::vector<uint32_t>& v) {
+ if (v.size() > 0) {
+ std::string line(StringPrintf("\n %s %s%s_%s_table[%zu] = {", table_name,
+ descriptor.c_str(), name.c_str(), signature.c_str(), v.size()));
+ std::replace(line.begin(), line.end(), ';', '_');
+ LOG(INFO) << line;
+ for (uint32_t i = 0; i < v.size(); i+=2) {
+ line = StringPrintf(" {0x%05x, 0x%04x},", v[i], v[i+1]);
+ LOG(INFO) << line;
+ }
+ LOG(INFO) <<" };\n\n";
+ }
+}
+
/* Dump instructions and constant pool contents */
void oatCodegenDump(CompilationUnit* cUnit)
{
@@ -434,21 +454,9 @@ void oatCodegenDump(CompilationUnit* cUnit)
std::string name(cUnit->dex_file->GetMethodName(method_id));
std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id));
- // Dump mapping table
- if (cUnit->mappingTable.size() > 0) {
- std::string
- line(StringPrintf("\n MappingTable %s%s_%s_mappingTable[%zu] = {",
- descriptor.c_str(), name.c_str(), signature.c_str(),
- cUnit->mappingTable.size()));
- std::replace(line.begin(), line.end(), ';', '_');
- LOG(INFO) << line;
- for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
- line = StringPrintf(" {0x%05x, 0x%04x},",
- cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
- LOG(INFO) << line;
- }
- LOG(INFO) <<" };\n\n";
- }
+ // Dump mapping tables
+ dumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, cUnit->pc2dexMappingTable);
+ dumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, cUnit->dex2pcMappingTable);
}
@@ -465,7 +473,8 @@ LIR* rawLIR(CompilationUnit* cUnit, int dalvikOffset, int opcode, int op0,
insn->operands[4] = op4;
insn->target = target;
oatSetupResourceMasks(insn);
- if ((opcode == kPseudoTargetLabel) || (opcode == kPseudoSafepointPC)) {
+ if ((opcode == kPseudoTargetLabel) || (opcode == kPseudoSafepointPC) ||
+ (opcode == kPseudoExportedPC)) {
// Always make labels scheduling barriers
insn->useMask = insn->defMask = ENCODE_ALL;
}
@@ -755,14 +764,27 @@ int assignLiteralOffsetCommon(LIR* lir, int offset)
return offset;
}
-void createMappingTable(CompilationUnit* cUnit)
+void createMappingTables(CompilationUnit* cUnit)
{
for (LIR* tgtLIR = (LIR *) cUnit->firstLIRInsn; tgtLIR != NULL; tgtLIR = NEXT_LIR(tgtLIR)) {
if (!tgtLIR->flags.isNop && (tgtLIR->opcode == kPseudoSafepointPC)) {
- cUnit->mappingTable.push_back(tgtLIR->offset);
- cUnit->mappingTable.push_back(tgtLIR->dalvikOffset);
+ cUnit->pc2dexMappingTable.push_back(tgtLIR->offset);
+ cUnit->pc2dexMappingTable.push_back(tgtLIR->dalvikOffset);
+ }
+ if (!tgtLIR->flags.isNop && (tgtLIR->opcode == kPseudoExportedPC)) {
+ cUnit->dex2pcMappingTable.push_back(tgtLIR->offset);
+ cUnit->dex2pcMappingTable.push_back(tgtLIR->dalvikOffset);
}
}
+ cUnit->combinedMappingTable.push_back(cUnit->pc2dexMappingTable.size() +
+ cUnit->dex2pcMappingTable.size());
+ cUnit->combinedMappingTable.push_back(cUnit->pc2dexMappingTable.size());
+ cUnit->combinedMappingTable.insert(cUnit->combinedMappingTable.end(),
+ cUnit->pc2dexMappingTable.begin(),
+ cUnit->pc2dexMappingTable.end());
+ cUnit->combinedMappingTable.insert(cUnit->combinedMappingTable.end(),
+ cUnit->dex2pcMappingTable.begin(),
+ cUnit->dex2pcMappingTable.end());
}
class NativePcToReferenceMapBuilder {
@@ -844,7 +866,7 @@ class NativePcToReferenceMapBuilder {
};
static void createNativeGcMap(CompilationUnit* cUnit) {
- const std::vector<uint32_t>& mapping_table = cUnit->mappingTable;
+ const std::vector<uint32_t>& mapping_table = cUnit->pc2dexMappingTable;
uint32_t max_native_offset = 0;
for (size_t i = 0; i < mapping_table.size(); i += 2) {
uint32_t native_offset = mapping_table[i + 0];
@@ -864,13 +886,8 @@ static void createNativeGcMap(CompilationUnit* cUnit) {
uint32_t native_offset = mapping_table[i + 0];
uint32_t dex_pc = mapping_table[i + 1];
const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
- if (references != NULL) {
- native_gc_map_builder.AddEntry(native_offset, references);
- } else {
- // TODO: there is a mapping table entry but no reference bitmap. This happens because of
- // catch block entries. We should check that the dex_pc corresponds with a catch block
- // here.
- }
+ CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc;
+ native_gc_map_builder.AddEntry(native_offset, references);
}
}
@@ -981,7 +998,7 @@ void oatAssembleLIR(CompilationUnit* cUnit)
installFillArrayData(cUnit);
// Create the mapping table and native offset to reference map.
- createMappingTable(cUnit);
+ createMappingTables(cUnit);
createNativeGcMap(cUnit);
}
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index 682de7ad6a..cff4ee5112 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -2891,7 +2891,7 @@ bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
LIR* headLIR = NULL;
if (blockType == kCatchBlock) {
- headLIR = newLIR0(cUnit, kPseudoSafepointPC);
+ headLIR = newLIR0(cUnit, kPseudoExportedPC);
}
// Free temp registers and reset redundant store tracking */
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 7227487db9..3a80d1063c 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -870,9 +870,9 @@ bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
LIR* headLIR = NULL;
- /* If this is a catch block, mark the beginning as a safepoint */
+ /* If this is a catch block, export the start address */
if (bb->catchEntry) {
- headLIR = newLIR0(cUnit, kPseudoSafepointPC);
+ headLIR = newLIR0(cUnit, kPseudoExportedPC);
}
/* Free temp registers and reset redundant store tracking */
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index 36a11f22f9..a40df20b8e 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -291,6 +291,7 @@ enum ArmConditionCode {
* Assemble.cc.
*/
enum ArmOpcode {
+ kPseudoExportedPC = -18,
kPseudoSafepointPC = -17,
kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index c78cd8dc1c..0f6226f963 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -333,6 +333,7 @@ enum MipsShiftEncodings {
* Assemble.cc.
*/
enum MipsOpCode {
+ kPseudoExportedPC = -18,
kPseudoSafepointPC = -17,
kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
diff --git a/src/compiler/codegen/x86/X86LIR.h b/src/compiler/codegen/x86/X86LIR.h
index 43fc63c48f..d3e3da8d6d 100644
--- a/src/compiler/codegen/x86/X86LIR.h
+++ b/src/compiler/codegen/x86/X86LIR.h
@@ -297,6 +297,7 @@ enum X86ConditionCode {
* Assemble.cc.
*/
enum X86OpCode {
+ kPseudoExportedPC = -18,
kPseudoSafepointPC = -17,
kPseudoIntrinsicRetry = -16,
kPseudoSuspendTarget = -15,
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 7303ac6615..b82f8f785c 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -47,7 +47,13 @@ class ExceptionTest : public CommonTest {
fake_code_.push_back(0x70 | i);
}
- fake_mapping_data_.push_back(2); // first element is count of remaining elements
+ fake_mapping_data_.push_back(4); // first element is count
+ fake_mapping_data_.push_back(4); // total (non-length) elements
+ fake_mapping_data_.push_back(2); // count of pc to dex elements
+ // --- pc to dex table
+ fake_mapping_data_.push_back(3); // offset 3
+ fake_mapping_data_.push_back(3); // maps to dex offset 3
+ // --- dex to pc table
fake_mapping_data_.push_back(3); // offset 3
fake_mapping_data_.push_back(3); // maps to dex offset 3
diff --git a/src/oatdump.cc b/src/oatdump.cc
index f08a4984fd..c35d233069 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -423,13 +423,18 @@ class OatDumper {
uint32_t length = *raw_table;
++raw_table;
+ uint32_t pc_to_dex_entries = *raw_table;
+ ++raw_table;
os << "\t\t{";
for (size_t i = 0; i < length; i += 2) {
const uint8_t* native_pc = reinterpret_cast<const uint8_t*>(code) + raw_table[i];
uint32_t dex_pc = raw_table[i + 1];
os << StringPrintf("%p -> 0x%04x", native_pc, dex_pc);
- if (i + 2 < length) {
+ if (i + 2 == pc_to_dex_entries) {
+ // Separate the pc -> dex from dex -> pc sections
+ os << "}\n\t\t{";
+ } else if (i + 2 < length) {
os << ", ";
}
}
diff --git a/src/object.cc b/src/object.cc
index 284f221720..90342ffd3f 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -514,14 +514,37 @@ uintptr_t AbstractMethod::NativePcOffset(const uintptr_t pc) const {
return pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
}
+// Find the lowest-address native safepoint pc for a given dex pc
+uint32_t AbstractMethod::ToFirstNativeSafepointPc(const uintptr_t dex_pc) const {
+#if !defined(ART_USE_LLVM_COMPILER)
+ const uint32_t* mapping_table = GetPcToDexMappingTable();
+ if (mapping_table == NULL) {
+ DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
+ return DexFile::kDexNoIndex; // Special no mapping case
+ }
+ size_t mapping_table_length = GetPcToDexMappingTableLength();
+ for (size_t i = 0; i < mapping_table_length; i += 2) {
+ if (mapping_table[i + 1] == dex_pc) {
+ return mapping_table[i] + reinterpret_cast<uintptr_t>(GetOatCode(this));
+ }
+ }
+ LOG(FATAL) << "Failed to find native offset for dex pc 0x" << std::hex << dex_pc
+ << " in " << PrettyMethod(this);
+ return 0;
+#else
+ // Compiler LLVM doesn't use the machine pc, we just use dex pc instead.
+ return static_cast<uint32_t>(dex_pc);
+#endif
+}
+
uint32_t AbstractMethod::ToDexPc(const uintptr_t pc) const {
#if !defined(ART_USE_LLVM_COMPILER)
- const uint32_t* mapping_table = GetMappingTable();
+ const uint32_t* mapping_table = GetPcToDexMappingTable();
if (mapping_table == NULL) {
DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
return DexFile::kDexNoIndex; // Special no mapping case
}
- size_t mapping_table_length = GetMappingTableLength();
+ size_t mapping_table_length = GetPcToDexMappingTableLength();
uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
for (size_t i = 0; i < mapping_table_length; i += 2) {
if (mapping_table[i] == sought_offset) {
@@ -538,12 +561,12 @@ uint32_t AbstractMethod::ToDexPc(const uintptr_t pc) const {
}
uintptr_t AbstractMethod::ToNativePc(const uint32_t dex_pc) const {
- const uint32_t* mapping_table = GetMappingTable();
+ const uint32_t* mapping_table = GetDexToPcMappingTable();
if (mapping_table == NULL) {
DCHECK_EQ(dex_pc, 0U);
return 0; // Special no mapping/pc == 0 case
}
- size_t mapping_table_length = GetMappingTableLength();
+ size_t mapping_table_length = GetDexToPcMappingTableLength();
for (size_t i = 0; i < mapping_table_length; i += 2) {
uint32_t map_offset = mapping_table[i];
uint32_t map_dex_offset = mapping_table[i + 1];
@@ -551,7 +574,8 @@ uintptr_t AbstractMethod::ToNativePc(const uint32_t dex_pc) const {
return reinterpret_cast<uintptr_t>(GetOatCode(this)) + map_offset;
}
}
- LOG(FATAL) << "Looking up Dex PC not contained in method";
+ LOG(FATAL) << "Looking up Dex PC not contained in method, 0x" << std::hex << dex_pc
+ << " in " << PrettyMethod(this);
return 0;
}
diff --git a/src/object.h b/src/object.h
index 947b77d35b..5fccb04079 100644
--- a/src/object.h
+++ b/src/object.h
@@ -729,14 +729,40 @@ class MANAGED AbstractMethod : public Object {
return map + 1;
}
- uint32_t GetMappingTableLength() const {
+ uint32_t GetPcToDexMappingTableLength() const {
const uint32_t* map = GetMappingTableRaw();
if (map == NULL) {
return 0;
}
- return *map;
+ return map[2];
}
+ const uint32_t* GetPcToDexMappingTable() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return map;
+ }
+ return map + 3;
+ }
+
+
+ uint32_t GetDexToPcMappingTableLength() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return 0;
+ }
+ return map[1] - map[2];
+ }
+
+ const uint32_t* GetDexToPcMappingTable() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return map;
+ }
+ return map + 3 + map[2];
+ }
+
+
const uint32_t* GetMappingTableRaw() const {
return GetFieldPtr<const uint32_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, mapping_table_), false);
}
@@ -922,6 +948,10 @@ class MANAGED AbstractMethod : public Object {
// Converts a dex PC to a native PC.
uintptr_t ToNativePc(const uint32_t dex_pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Converts a dex PC to the first corresponding safepoint PC.
+ uintptr_t ToFirstNativeSafepointPc(const uint32_t dex_pc)
+ const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// Find the catch block for the given exception type and dex_pc
uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/test/ReferenceMap/stack_walk_refmap_jni.cc b/test/ReferenceMap/stack_walk_refmap_jni.cc
index 0b6cd7ebc2..a9dfbac9e2 100644
--- a/test/ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/ReferenceMap/stack_walk_refmap_jni.cc
@@ -75,31 +75,31 @@ struct ReferenceMap2Visitor : public StackVisitor {
// we know the Dex registers with live reference values. Assert that what we
// find is what is expected.
if (m_name.compare("f") == 0) {
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x03U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x03U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8); // v8: this
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x06U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x06U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 1); // v8: this, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x08U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x08U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v8: this, v3: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x0cU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x0cU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v8: this, v3: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x0eU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x0eU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v8: this, v3: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x10U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x10U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 1); // v8: this, v3: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x13U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x13U)));
CHECK(ref_bitmap);
// v2 is added because of the instruction at DexPC 0024. Object merges with 0 is Object. See:
// 0024: move-object v3, v2
@@ -107,49 +107,49 @@ struct ReferenceMap2Visitor : public StackVisitor {
// Detaled dex instructions for ReferenceMap.java are at the end of this function.
CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1); // v8: this, v3: y, v2: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x18U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x18U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v8: this, v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x1aU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x1aU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 5, 2, 1, 0); // v8: this, v5: x[1], v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x1dU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x1dU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 5, 2, 1, 0); // v8: this, v5: x[1], v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x1fU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x1fU)));
CHECK(ref_bitmap);
// v5 is removed from the root set because there is a "merge" operation.
// See 0015: if-nez v2, 001f.
CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v8: this, v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x21U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x21U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 2, 1, 0); // v8: this, v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x25U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x25U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1, 0); // v8: this, v3: y, v2: y, v1: x, v0: ex
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x27U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x27U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v8: this, v4: ex, v2: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x29U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x29U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v8: this, v4: ex, v2: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x2cU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x2cU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 4, 2, 1); // v8: this, v4: ex, v2: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x2fU)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x2fU)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 4, 3, 2, 1); // v8: this, v4: ex, v3: y, v2: y, v1: x
- ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToNativePc(0x32U)));
+ ref_bitmap = map.FindBitMap(m->NativePcOffset(m->ToFirstNativeSafepointPc(0x32U)));
CHECK(ref_bitmap);
CHECK_REGS_CONTAIN_REFS(8, 3, 2, 1, 0); // v8: this, v3: y, v2: y, v1: x, v0: ex
}