Delete ArtMethod gc_map_ field
Moved the gc_map field from OatMethod to OatQuickMethodHeader.
Deleted the ArtMethod gc_map_ field.
Bug: 17643507
Change-Id: Ifa0470c3e4c2f8a319744464d94c6838b76b3d48
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 5e4623d..b59ab13 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -142,22 +142,12 @@
CommonCompilerTest::CommonCompilerTest() {}
CommonCompilerTest::~CommonCompilerTest() {}
-OatFile::OatMethod CommonCompilerTest::CreateOatMethod(const void* code, const uint8_t* gc_map) {
+OatFile::OatMethod CommonCompilerTest::CreateOatMethod(const void* code) {
CHECK(code != nullptr);
- const byte* base;
- uint32_t code_offset, gc_map_offset;
- if (gc_map == nullptr) {
- base = reinterpret_cast<const byte*>(code); // Base of data points at code.
- base -= kPointerSize; // Move backward so that code_offset != 0.
- code_offset = kPointerSize;
- gc_map_offset = 0;
- } else {
- // TODO: 64bit support.
- base = nullptr; // Base of data in oat file, ie 0.
- code_offset = PointerToLowMemUInt32(code);
- gc_map_offset = PointerToLowMemUInt32(gc_map);
- }
- return OatFile::OatMethod(base, code_offset, gc_map_offset);
+ const byte* base = reinterpret_cast<const byte*>(code); // Base of data points at code.
+ base -= kPointerSize; // Move backward so that code_offset != 0.
+ uint32_t code_offset = kPointerSize;
+ return OatFile::OatMethod(base, code_offset);
}
void CommonCompilerTest::MakeExecutable(mirror::ArtMethod* method) {
@@ -183,14 +173,18 @@
const std::vector<uint8_t>& mapping_table = compiled_method->GetMappingTable();
uint32_t mapping_table_offset = mapping_table.empty() ? 0u
: sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size();
- OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset,
+ const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
+ uint32_t gc_map_offset = gc_map.empty() ? 0u
+ : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table.size() + gc_map.size();
+ OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
compiled_method->GetFrameSizeInBytes(),
compiled_method->GetCoreSpillMask(),
compiled_method->GetFpSpillMask(), code_size);
header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
- size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size();
+ size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table.size() +
+ gc_map.size();
size_t code_offset = compiled_method->AlignCode(size - code_size);
size_t padding = code_offset - (size - code_size);
chunk->reserve(padding + size);
@@ -198,6 +192,7 @@
memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
+ chunk->insert(chunk->begin(), gc_map.begin(), gc_map.end());
chunk->insert(chunk->begin(), padding, 0);
chunk->insert(chunk->end(), code->begin(), code->end());
CHECK_EQ(padding + size, chunk->size());
@@ -210,7 +205,7 @@
const void* method_code = CompiledMethod::CodePointer(code_ptr,
compiled_method->GetInstructionSet());
LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
- OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+ OatFile::OatMethod oat_method = CreateOatMethod(method_code);
oat_method.LinkMethod(method);
method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
} else {
@@ -222,13 +217,13 @@
#else
const void* method_code = GetQuickToInterpreterBridge();
#endif
- OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+ OatFile::OatMethod oat_method = CreateOatMethod(method_code);
oat_method.LinkMethod(method);
method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
} else {
const void* method_code = reinterpret_cast<void*>(art_quick_generic_jni_trampoline);
- OatFile::OatMethod oat_method = CreateOatMethod(method_code, nullptr);
+ OatFile::OatMethod oat_method = CreateOatMethod(method_code);
oat_method.LinkMethod(method);
method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
}
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index df06b71..dd25dff 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -42,7 +42,7 @@
~CommonCompilerTest();
// Create an OatMethod based on pointers (for unit tests).
- OatFile::OatMethod CreateOatMethod(const void* code, const uint8_t* gc_map);
+ OatFile::OatMethod CreateOatMethod(const void* code);
void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 193be15..dedbf8d 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1139,7 +1139,6 @@
copy->SetEntryPointFromJniPtrSize<kVerifyNone>(orig->GetEntryPointFromJni(), target_ptr_size_);
copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
orig->GetEntryPointFromQuickCompiledCode(), target_ptr_size_);
- copy->SetNativeGcMapPtrSize<kVerifyNone>(orig->GetNativeGcMap(), target_ptr_size_);
// The resolution method has a special trampoline to call.
Runtime* runtime = Runtime::Current();
@@ -1208,11 +1207,6 @@
// Note this is not the code_ pointer, that is handled above.
copy->SetEntryPointFromJniPtrSize<kVerifyNone>(GetOatAddress(jni_dlsym_lookup_offset_),
target_ptr_size_);
- } else {
- // Normal (non-abstract non-native) methods have various tables to relocate.
- uint32_t native_gc_map_offset = orig->GetOatNativeGcMapOffset();
- const uint8_t* native_gc_map = GetOatAddress(native_gc_map_offset);
- copy->SetNativeGcMapPtrSize<kVerifyNone>(native_gc_map, target_ptr_size_);
}
// Interpreter entrypoint:
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 5bf19ed..a32fac1 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -143,15 +143,18 @@
}
static uint32_t GetOffset(OatClass* oat_class, size_t method_offsets_index) ALWAYS_INLINE {
- return oat_class->method_offsets_[method_offsets_index].gc_map_offset_;
+ uint32_t offset = oat_class->method_headers_[method_offsets_index].gc_map_offset_;
+ return offset == 0u ? 0u :
+ (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset;
}
static void SetOffset(OatClass* oat_class, size_t method_offsets_index, uint32_t offset)
ALWAYS_INLINE {
- oat_class->method_offsets_[method_offsets_index].gc_map_offset_ = offset;
+ oat_class->method_headers_[method_offsets_index].gc_map_offset_ =
+ (oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset;
}
- static const char* Name() ALWAYS_INLINE {
+ static const char* Name() {
return "GC map";
}
};
@@ -173,7 +176,7 @@
(oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset;
}
- static const char* Name() ALWAYS_INLINE {
+ static const char* Name() {
return "mapping table";
}
};
@@ -195,7 +198,7 @@
(oat_class->method_offsets_[method_offsets_index].code_offset_ & ~1) - offset;
}
- static const char* Name() ALWAYS_INLINE {
+ static const char* Name() {
return "vmap table";
}
};
@@ -374,6 +377,7 @@
OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_];
uint32_t mapping_table_offset = method_header->mapping_table_offset_;
uint32_t vmap_table_offset = method_header->vmap_table_offset_;
+ uint32_t gc_map_offset = method_header->gc_map_offset_;
// The code offset was 0 when the mapping/vmap table offset was set, so it's set
// to 0-offset and we need to adjust it by code_offset.
uint32_t code_offset = quick_code_offset - thumb_offset;
@@ -385,12 +389,16 @@
vmap_table_offset += code_offset;
DCHECK_LT(vmap_table_offset, code_offset);
}
+ if (gc_map_offset != 0u) {
+ gc_map_offset += code_offset;
+ DCHECK_LT(gc_map_offset, code_offset);
+ }
uint32_t frame_size_in_bytes = compiled_method->GetFrameSizeInBytes();
uint32_t core_spill_mask = compiled_method->GetCoreSpillMask();
uint32_t fp_spill_mask = compiled_method->GetFpSpillMask();
*method_header = OatQuickMethodHeader(mapping_table_offset, vmap_table_offset,
- frame_size_in_bytes, core_spill_mask, fp_spill_mask,
- code_size);
+ gc_map_offset, frame_size_in_bytes, core_spill_mask,
+ fp_spill_mask, code_size);
// Update checksum if this wasn't a duplicate.
if (!deduped) {
@@ -533,7 +541,7 @@
OatClass* oat_class = writer_->oat_classes_[oat_class_index_];
CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
- OatMethodOffsets offsets(0u, 0u);
+ OatMethodOffsets offsets(0u);
if (compiled_method != nullptr) {
DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size());
offsets = oat_class->method_offsets_[method_offsets_index_];
@@ -544,7 +552,7 @@
InvokeType invoke_type = it.GetMethodInvokeType(dex_file_->GetClassDef(class_def_index_));
// Unchecked as we hold mutator_lock_ on entry.
ScopedObjectAccessUnchecked soa(Thread::Current());
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<1> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->FindDexCache(*dex_file_)));
mirror::ArtMethod* method = linker->ResolveMethod(*dex_file_, it.GetMemberIndex(), dex_cache,
NullHandle<mirror::ClassLoader>(),
@@ -553,7 +561,6 @@
CHECK(method != NULL) << PrettyMethod(it.GetMemberIndex(), *dex_file_, true);
// Portable code offsets are set by ElfWriterMclinker::FixupCompiledCodeOffset after linking.
method->SetQuickOatCodeOffset(offsets.code_offset_);
- method->SetOatNativeGcMapOffset(offsets.gc_map_offset_);
return true;
}
@@ -605,7 +612,8 @@
offset_ + sizeof(OatQuickMethodHeader) + compiled_method->CodeDelta())
<< PrettyMethod(it.GetMemberIndex(), *dex_file_);
if (method_offsets.code_offset_ >= offset_) {
- const OatQuickMethodHeader& method_header = oat_class->method_headers_[method_offsets_index_];
+ const OatQuickMethodHeader& method_header =
+ oat_class->method_headers_[method_offsets_index_];
if (!out->WriteFully(&method_header, sizeof(method_header))) {
ReportWriteFailure("method header", it);
return false;
@@ -642,7 +650,7 @@
class OatWriter::WriteMapMethodVisitor : public OatDexMethodVisitor {
public:
WriteMapMethodVisitor(OatWriter* writer, OutputStream* out, const size_t file_offset,
- size_t relative_offset)
+ size_t relative_offset)
: OatDexMethodVisitor(writer, relative_offset),
out_(out),
file_offset_(file_offset) {
@@ -664,7 +672,8 @@
size_t map_size = map->size() * sizeof((*map)[0]);
DCHECK((map_size == 0u && map_offset == 0u) ||
(map_size != 0u && map_offset != 0u && map_offset <= offset_))
- << PrettyMethod(it.GetMemberIndex(), *dex_file_);
+ << map_size << " " << map_offset << " " << offset_ << " "
+ << PrettyMethod(it.GetMemberIndex(), *dex_file_) << " for " << DataAccess::Name();
if (map_size != 0u && map_offset == offset_) {
if (UNLIKELY(!out->WriteFully(&(*map)[0], map_size))) {
ReportWriteFailure(it);
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index d638b29..4734a9c 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -355,7 +355,7 @@
offsets_.insert(code_offset);
offsets_.insert(oat_method.GetMappingTableOffset());
offsets_.insert(oat_method.GetVmapTableOffset());
- offsets_.insert(oat_method.GetNativeGcMapOffset());
+ offsets_.insert(oat_method.GetGcMapOffset());
}
bool DumpOatDexFile(std::ostream& os, const OatFile::OatDexFile& oat_dex_file) {
@@ -500,9 +500,9 @@
*indent2_os << "gc_map: ";
if (options_->absolute_addresses_) {
- *indent2_os << StringPrintf("%p ", oat_method.GetNativeGcMap());
+ *indent2_os << StringPrintf("%p ", oat_method.GetGcMap());
}
- uint32_t gc_map_offset = oat_method.GetNativeGcMapOffset();
+ uint32_t gc_map_offset = oat_method.GetGcMapOffset();
*indent2_os << StringPrintf("(offset=0x%08x)\n", gc_map_offset);
if (gc_map_offset > oat_file_.Size()) {
*indent2_os << StringPrintf("WARNING: "
@@ -744,7 +744,7 @@
}
void DumpGcMap(std::ostream& os, const OatFile::OatMethod& oat_method,
const DexFile::CodeItem* code_item) {
- const uint8_t* gc_map_raw = oat_method.GetNativeGcMap();
+ const uint8_t* gc_map_raw = oat_method.GetGcMap();
if (gc_map_raw == nullptr) {
return; // No GC map.
}
@@ -822,7 +822,7 @@
void DumpGcMapAtNativePcOffset(std::ostream& os, const OatFile::OatMethod& oat_method,
const DexFile::CodeItem* code_item, size_t native_pc_offset) {
- const uint8_t* gc_map_raw = oat_method.GetNativeGcMap();
+ const uint8_t* gc_map_raw = oat_method.GetGcMap();
if (gc_map_raw != nullptr) {
NativePcOffsetToReferenceMap map(gc_map_raw);
if (map.HasEntry(native_pc_offset)) {
@@ -1314,8 +1314,7 @@
mirror::ArtMethod* method = obj->AsArtMethod();
if (method->IsNative()) {
// TODO: portable dumping.
- DCHECK(method->GetNativeGcMapPtrSize(image_pointer_size) == nullptr)
- << PrettyMethod(method);
+ DCHECK(method->GetNativeGcMap(image_pointer_size) == nullptr) << PrettyMethod(method);
DCHECK(method->GetMappingTable(image_pointer_size) == nullptr) << PrettyMethod(method);
bool first_occurrence;
const void* quick_oat_code = state->GetQuickOatCodeBegin(method);
@@ -1331,8 +1330,7 @@
} else if (method->IsAbstract() || method->IsCalleeSaveMethod() ||
method->IsResolutionMethod() || method->IsImtConflictMethod() ||
method->IsImtUnimplementedMethod() || method->IsClassInitializer()) {
- DCHECK(method->GetNativeGcMapPtrSize(image_pointer_size) == nullptr)
- << PrettyMethod(method);
+ DCHECK(method->GetNativeGcMap(image_pointer_size) == nullptr) << PrettyMethod(method);
DCHECK(method->GetMappingTable(image_pointer_size) == nullptr) << PrettyMethod(method);
} else {
const DexFile::CodeItem* code_item = method->GetCodeItem();
@@ -1340,8 +1338,8 @@
state->stats_.dex_instruction_bytes += dex_instruction_bytes;
bool first_occurrence;
- size_t gc_map_bytes = state->ComputeOatSize(
- method->GetNativeGcMapPtrSize(image_pointer_size), &first_occurrence);
+ size_t gc_map_bytes =
+ state->ComputeOatSize(method->GetNativeGcMap(image_pointer_size), &first_occurrence);
if (first_occurrence) {
state->stats_.gc_map_bytes += gc_map_bytes;
}
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 610ff06..b046ea1 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -558,12 +558,6 @@
copy->SetEntryPointFromJniPtrSize(reinterpret_cast<void*>(native_method + delta_),
pointer_size);
}
-
- uintptr_t native_gc_map = reinterpret_cast<uintptr_t>(
- object->GetNativeGcMapPtrSize(pointer_size));
- if (native_gc_map != 0) {
- copy->SetNativeGcMapPtrSize(reinterpret_cast<uint8_t*>(native_gc_map + delta_), pointer_size);
- }
}
bool PatchOat::Patch(File* input_oat, off_t delta, File* output_oat, TimingLogger* timings,
diff --git a/runtime/entrypoints/portable/portable_thread_entrypoints.cc b/runtime/entrypoints/portable/portable_thread_entrypoints.cc
index 23e1c36..46dfa3a 100644
--- a/runtime/entrypoints/portable/portable_thread_entrypoints.cc
+++ b/runtime/entrypoints/portable/portable_thread_entrypoints.cc
@@ -35,7 +35,7 @@
uint32_t dex_pc = cur_frame->GetDexPC();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, method, dex_pc);
- const uint8_t* gc_map = method->GetNativeGcMap();
+ const uint8_t* gc_map = method->GetNativeGcMap(sizeof(void*));
verifier::DexPcToReferenceMap dex_gc_map(gc_map);
const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc);
for (size_t reg = 0; reg < num_regs; ++reg) {
diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc
index 99633a3..fd3b65e 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -76,7 +76,8 @@
const std::vector<uint8_t>& fake_mapping_data = fake_mapping_data_.GetData();
uint32_t vmap_table_offset = sizeof(OatQuickMethodHeader) + fake_vmap_table_data.size();
uint32_t mapping_table_offset = vmap_table_offset + fake_mapping_data.size();
- OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset,
+ uint32_t gc_map_offset = mapping_table_offset + fake_gc_map_.size();
+ OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
4 * kPointerSize, 0u, 0u, code_size);
fake_header_code_and_maps_.resize(sizeof(method_header));
memcpy(&fake_header_code_and_maps_[0], &method_header, sizeof(method_header));
@@ -84,6 +85,8 @@
fake_vmap_table_data.begin(), fake_vmap_table_data.end());
fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
fake_mapping_data.begin(), fake_mapping_data.end());
+ fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
+ fake_gc_map_.begin(), fake_gc_map_.end());
fake_header_code_and_maps_.insert(fake_header_code_and_maps_.end(),
fake_code_.begin(), fake_code_.end());
@@ -95,12 +98,10 @@
method_f_ = my_klass_->FindVirtualMethod("f", "()I");
ASSERT_TRUE(method_f_ != NULL);
method_f_->SetEntryPointFromQuickCompiledCode(code_ptr);
- method_f_->SetNativeGcMap(&fake_gc_map_[0]);
method_g_ = my_klass_->FindVirtualMethod("g", "(I)V");
ASSERT_TRUE(method_g_ != NULL);
method_g_->SetEntryPointFromQuickCompiledCode(code_ptr);
- method_g_->SetNativeGcMap(&fake_gc_map_[0]);
}
const DexFile* dex_;
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 8844f1c..e70a48e 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -290,14 +290,23 @@
return reinterpret_cast<const uint8_t*>(code_pointer) - offset;
}
-inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
+inline const uint8_t* ArtMethod::GetNativeGcMap(size_t pointer_size) {
+ const void* code_pointer = GetQuickOatCodePointer(pointer_size);
+ if (code_pointer == nullptr) {
+ return nullptr;
+ }
+ return GetNativeGcMap(code_pointer, pointer_size);
}
-inline uint32_t ArtMethod::GetOatNativeGcMapOffset() {
- DCHECK(!Runtime::Current()->IsStarted());
- return PointerToLowMemUInt32(GetNativeGcMap());
+inline const uint8_t* ArtMethod::GetNativeGcMap(const void* code_pointer, size_t pointer_size) {
+ DCHECK(code_pointer != nullptr);
+ DCHECK_EQ(code_pointer, GetQuickOatCodePointer(pointer_size));
+ uint32_t offset =
+ reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].gc_map_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code_pointer) - offset;
}
inline bool ArtMethod::IsRuntimeMethod() {
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 0c07448..1fa42c6 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -384,29 +384,15 @@
const uint8_t* GetVmapTable(const void* code_pointer, size_t pointer_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const uint8_t* GetNativeGcMap() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CheckObjectSizeEqualsMirrorSize();
- return GetNativeGcMapPtrSize(sizeof(void*));
- }
- ALWAYS_INLINE const uint8_t* GetNativeGcMapPtrSize(size_t pointer_size)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetFieldPtrWithSize<uint8_t*>(GcMapOffset(pointer_size), pointer_size);
- }
- template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- void SetNativeGcMap(const uint8_t* data) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CheckObjectSizeEqualsMirrorSize();
- SetNativeGcMapPtrSize(data, sizeof(void*));
- }
- template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- ALWAYS_INLINE void SetNativeGcMapPtrSize(const uint8_t* data, size_t pointer_size)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- SetFieldPtrWithSize<false, true, kVerifyFlags>(GcMapOffset(pointer_size), data,
- pointer_size);
- }
+ // Callers should wrap the uint8_t* in a GcMap instance for convenient access.
+ const uint8_t* GetNativeGcMap(size_t pointer_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const uint8_t* GetNativeGcMap(const void* code_pointer, size_t pointer_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// When building the oat need a convenient place to stuff the offset of the native GC map.
- void SetOatNativeGcMapOffset(uint32_t gc_map_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint32_t GetOatNativeGcMapOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // void SetOatNativeGcMapOffset(uint32_t gc_map_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // uint32_t GetOatNativeGcMapOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template <bool kCheckFrameSize = true>
uint32_t GetFrameSizeInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -455,11 +441,6 @@
PtrSizedFields, entry_point_from_quick_compiled_code_) / sizeof(void*) * pointer_size);
}
- static MemberOffset GcMapOffset(size_t pointer_size) {
- return MemberOffset(PtrSizedFieldsOffset() + OFFSETOF_MEMBER(
- PtrSizedFields, gc_map_) / sizeof(void*) * pointer_size);
- }
-
void* GetEntryPointFromJni() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CheckObjectSizeEqualsMirrorSize();
return GetEntryPointFromJniPtrSize(sizeof(void*));
@@ -624,11 +605,6 @@
// portable compiled code or the interpreter.
void* entry_point_from_quick_compiled_code_;
- // Pointer to a data structure created by the compiler and used by the garbage collector to
- // determine which registers hold live references to objects within the heap. Keyed by native PC
- // offsets for the quick compiler and dex PCs for the portable.
- void* gc_map_;
-
// Method dispatch from portable compiled code invokes this pointer which may cause bridging
// into quick compiled code or the interpreter. Last to simplify entrypoint logic.
#if defined(ART_USE_PORTABLE_COMPILER)
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 4819396..a8fd250 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -23,7 +23,7 @@
namespace art {
const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '4', '3', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '4', '4', '\0' };
static size_t ComputeOatHeaderSize(const SafeMap<std::string, std::string>* variable_data) {
size_t estimate = 0U;
@@ -491,35 +491,19 @@
key_value_store_size_ = data_ptr - reinterpret_cast<char*>(&key_value_store_);
}
-OatMethodOffsets::OatMethodOffsets()
- : code_offset_(0),
- gc_map_offset_(0)
-{}
-
-OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
- uint32_t gc_map_offset
- )
- : code_offset_(code_offset),
- gc_map_offset_(gc_map_offset)
-{}
+OatMethodOffsets::OatMethodOffsets(uint32_t code_offset) : code_offset_(code_offset) {
+}
OatMethodOffsets::~OatMethodOffsets() {}
-OatQuickMethodHeader::OatQuickMethodHeader()
- : mapping_table_offset_(0),
- vmap_table_offset_(0),
- frame_info_(0, 0, 0),
- code_size_(0)
-{}
-
OatQuickMethodHeader::OatQuickMethodHeader(
- uint32_t mapping_table_offset, uint32_t vmap_table_offset, uint32_t frame_size_in_bytes,
- uint32_t core_spill_mask, uint32_t fp_spill_mask, uint32_t code_size)
- : mapping_table_offset_(mapping_table_offset),
- vmap_table_offset_(vmap_table_offset),
- frame_info_(frame_size_in_bytes, core_spill_mask, fp_spill_mask),
- code_size_(code_size)
-{}
+ uint32_t mapping_table_offset, uint32_t vmap_table_offset, uint32_t gc_map_offset,
+ uint32_t frame_size_in_bytes, uint32_t core_spill_mask, uint32_t fp_spill_mask,
+ uint32_t code_size)
+ : mapping_table_offset_(mapping_table_offset), vmap_table_offset_(vmap_table_offset),
+ gc_map_offset_(gc_map_offset),
+ frame_info_(frame_size_in_bytes, core_spill_mask, fp_spill_mask), code_size_(code_size) {
+}
OatQuickMethodHeader::~OatQuickMethodHeader() {}
diff --git a/runtime/oat.h b/runtime/oat.h
index a5cb4bc..0534b1d 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -162,25 +162,20 @@
class PACKED(4) OatMethodOffsets {
public:
- OatMethodOffsets();
-
- OatMethodOffsets(uint32_t code_offset,
- uint32_t gc_map_offset);
+ OatMethodOffsets(uint32_t code_offset = 0);
~OatMethodOffsets();
uint32_t code_offset_;
- uint32_t gc_map_offset_;
};
// OatQuickMethodHeader precedes the raw code chunk generated by the Quick compiler.
class PACKED(4) OatQuickMethodHeader {
public:
- OatQuickMethodHeader();
-
- explicit OatQuickMethodHeader(uint32_t mapping_table_offset, uint32_t vmap_table_offset,
- uint32_t frame_size_in_bytes, uint32_t core_spill_mask,
- uint32_t fp_spill_mask, uint32_t code_size);
+ OatQuickMethodHeader(uint32_t mapping_table_offset = 0U, uint32_t vmap_table_offset = 0U,
+ uint32_t gc_map_offset = 0U, uint32_t frame_size_in_bytes = 0U,
+ uint32_t core_spill_mask = 0U, uint32_t fp_spill_mask = 0U,
+ uint32_t code_size = 0U);
~OatQuickMethodHeader();
@@ -188,6 +183,8 @@
uint32_t mapping_table_offset_;
// The offset in bytes from the start of the vmap table to the end of the header.
uint32_t vmap_table_offset_;
+ // The offset in bytes from the start of the gc map to the end of the header.
+ uint32_t gc_map_offset_;
// The stack frame information.
QuickMethodFrameInfo frame_info_;
// The code size in bytes.
diff --git a/runtime/oat_file-inl.h b/runtime/oat_file-inl.h
index 9570bb5..a0cec03 100644
--- a/runtime/oat_file-inl.h
+++ b/runtime/oat_file-inl.h
@@ -78,6 +78,31 @@
return reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].frame_info_.FpSpillMask();
}
+const uint8_t* OatFile::OatMethod::GetGcMap() const {
+ const void* code = mirror::ArtMethod::EntryPointToCodePointer(GetQuickCode());
+ if (code == nullptr) {
+ return nullptr;
+ }
+ uint32_t offset = reinterpret_cast<const OatQuickMethodHeader*>(code)[-1].gc_map_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
+uint32_t OatFile::OatMethod::GetGcMapOffset() const {
+ const uint8_t* gc_map = GetGcMap();
+ return static_cast<uint32_t>(gc_map != nullptr ? gc_map - begin_ : 0u);
+}
+
+uint32_t OatFile::OatMethod::GetGcMapOffsetOffset() const {
+ const OatQuickMethodHeader* method_header = GetOatQuickMethodHeader();
+ if (method_header == nullptr) {
+ return 0u;
+ }
+ return reinterpret_cast<const byte*>(&method_header->gc_map_offset_) - begin_;
+}
+
inline uint32_t OatFile::OatMethod::GetMappingTableOffset() const {
const uint8_t* mapping_table = GetMappingTable();
return static_cast<uint32_t>(mapping_table != nullptr ? mapping_table - begin_ : 0u);
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 9ba860c..9c06ebe 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -572,27 +572,22 @@
const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
const OatMethodOffsets* oat_method_offsets = GetOatMethodOffsets(method_index);
if (oat_method_offsets == nullptr) {
- return OatMethod(nullptr, 0, 0);
+ return OatMethod(nullptr, 0);
}
if (oat_file_->IsExecutable() ||
Runtime::Current() == nullptr || // This case applies for oatdump.
Runtime::Current()->IsCompiler()) {
- return OatMethod(
- oat_file_->Begin(),
- oat_method_offsets->code_offset_,
- oat_method_offsets->gc_map_offset_);
+ return OatMethod(oat_file_->Begin(), oat_method_offsets->code_offset_);
} else {
// We aren't allowed to use the compiled code. We just force it down the interpreted version.
- return OatMethod(oat_file_->Begin(), 0, 0);
+ return OatMethod(oat_file_->Begin(), 0);
}
}
OatFile::OatMethod::OatMethod(const byte* base,
- const uint32_t code_offset,
- const uint32_t gc_map_offset)
+ const uint32_t code_offset)
: begin_(base),
- code_offset_(code_offset),
- native_gc_map_offset_(gc_map_offset) {
+ code_offset_(code_offset) {
}
OatFile::OatMethod::~OatMethod() {}
@@ -603,7 +598,6 @@
method->SetEntryPointFromPortableCompiledCode(GetPortableCode());
#endif
method->SetEntryPointFromQuickCompiledCode(GetQuickCode());
- method->SetNativeGcMap(GetNativeGcMap());
}
bool OatFile::IsPic() const {
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 488988e..5d92a05 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -96,9 +96,6 @@
uint32_t GetCodeOffset() const {
return code_offset_;
}
- uint32_t GetNativeGcMapOffset() const {
- return native_gc_map_offset_;
- }
const void* GetPortableCode() const {
// TODO: encode whether code is portable/quick in flags within OatMethod.
@@ -134,10 +131,6 @@
const OatQuickMethodHeader* GetOatQuickMethodHeader() const;
uint32_t GetOatQuickMethodHeaderOffset() const;
- const uint8_t* GetNativeGcMap() const {
- return GetOatPointer<const uint8_t*>(native_gc_map_offset_);
- }
-
size_t GetFrameSizeInBytes() const;
uint32_t GetCoreSpillMask() const;
uint32_t GetFpSpillMask() const;
@@ -150,12 +143,14 @@
uint32_t GetVmapTableOffset() const;
uint32_t GetVmapTableOffsetOffset() const;
+ const uint8_t* GetGcMap() const;
+ uint32_t GetGcMapOffset() const;
+ uint32_t GetGcMapOffsetOffset() const;
+
~OatMethod();
// Create an OatMethod with offsets relative to the given base address
- OatMethod(const byte* base,
- const uint32_t code_offset,
- const uint32_t gc_map_offset);
+ OatMethod(const byte* base, const uint32_t code_offset);
OatMethod() {}
@@ -171,7 +166,6 @@
const byte* begin_;
uint32_t code_offset_;
- uint32_t native_gc_map_offset_;
friend class OatClass;
};
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 74119bb..a3eb9fb 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2074,7 +2074,7 @@
} else {
// Java method.
// Portable path use DexGcMap and store in Method.native_gc_map_.
- const uint8_t* gc_map = m->GetNativeGcMap();
+ const uint8_t* gc_map = m->GetNativeGcMap(sizeof(void*));
CHECK(gc_map != nullptr) << PrettyMethod(m);
verifier::DexPcToReferenceMap dex_gc_map(gc_map);
uint32_t dex_pc = shadow_frame->GetDexPC();
@@ -2108,7 +2108,7 @@
// Process register map (which native and runtime methods don't have)
if (!m->IsNative() && !m->IsRuntimeMethod() && !m->IsProxyMethod()) {
- const uint8_t* native_gc_map = m->GetNativeGcMap();
+ const uint8_t* native_gc_map = m->GetNativeGcMap(sizeof(void*));
CHECK(native_gc_map != nullptr) << PrettyMethod(m);
const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be nullptr or how would we compile its instructions?
diff --git a/test/004-ReferenceMap/stack_walk_refmap_jni.cc b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
index 7929554..1bd3843 100644
--- a/test/004-ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
@@ -57,7 +57,7 @@
}
LOG(INFO) << "At " << PrettyMethod(m, false);
- NativePcOffsetToReferenceMap map(m->GetNativeGcMap());
+ NativePcOffsetToReferenceMap map(m->GetNativeGcMap(sizeof(void*)));
if (m->IsCalleeSaveMethod()) {
LOG(WARNING) << "no PC for " << PrettyMethod(m);
diff --git a/test/004-StackWalk/stack_walk_jni.cc b/test/004-StackWalk/stack_walk_jni.cc
index 30a0d59..2d55cc8 100644
--- a/test/004-StackWalk/stack_walk_jni.cc
+++ b/test/004-StackWalk/stack_walk_jni.cc
@@ -59,7 +59,7 @@
}
const uint8_t* reg_bitmap = NULL;
if (!IsShadowFrame()) {
- NativePcOffsetToReferenceMap map(m->GetNativeGcMap());
+ NativePcOffsetToReferenceMap map(m->GetNativeGcMap(sizeof(void*)));
reg_bitmap = map.FindBitMap(GetNativePcOffset());
}
StringPiece m_name(m->GetName());