summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-04-28 09:09:06 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-04-28 09:09:07 +0000
commit990d46f3333dce06a640ced697ee069330a73d7c (patch)
tree7caf896723665029823c73e2bec87e6db97ec428 /runtime
parentbf25f7e3a007ecfe4b2bcfa0a9abcb784ff54e26 (diff)
parent8a630577ed2d9e9571c3434c505e5de223b23c07 (diff)
downloadart-990d46f3333dce06a640ced697ee069330a73d7c.zip
art-990d46f3333dce06a640ced697ee069330a73d7c.tar.gz
art-990d46f3333dce06a640ced697ee069330a73d7c.tar.bz2
Merge "Move mapping table and vmap table offsets to OatMethodHeader."
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker.cc4
-rw-r--r--runtime/class_linker.h5
-rw-r--r--runtime/class_linker_test.cc2
-rw-r--r--runtime/entrypoints/entrypoint_utils.h4
-rw-r--r--runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc1
-rw-r--r--runtime/exception_test.cc32
-rw-r--r--runtime/instrumentation.cc12
-rw-r--r--runtime/mirror/art_method-inl.h33
-rw-r--r--runtime/mirror/art_method.cc38
-rw-r--r--runtime/mirror/art_method.h51
-rw-r--r--runtime/oat.cc19
-rw-r--r--runtime/oat.h15
-rw-r--r--runtime/oat_file-inl.h60
-rw-r--r--runtime/oat_file.cc27
-rw-r--r--runtime/oat_file.h21
15 files changed, 181 insertions, 143 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 58b82f0..338133c 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -185,7 +185,8 @@ ClassLinker::ClassLinker(InternTable* intern_table)
quick_resolution_trampoline_(nullptr),
portable_imt_conflict_trampoline_(nullptr),
quick_imt_conflict_trampoline_(nullptr),
- quick_generic_jni_trampoline_(nullptr) {
+ quick_generic_jni_trampoline_(nullptr),
+ quick_to_interpreter_bridge_trampoline_(nullptr) {
CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
memset(find_array_class_cache_, 0, kFindArrayCacheSize * sizeof(mirror::Class*));
}
@@ -1002,6 +1003,7 @@ void ClassLinker::InitFromImage() {
portable_imt_conflict_trampoline_ = oat_file.GetOatHeader().GetPortableImtConflictTrampoline();
quick_imt_conflict_trampoline_ = oat_file.GetOatHeader().GetQuickImtConflictTrampoline();
quick_generic_jni_trampoline_ = oat_file.GetOatHeader().GetQuickGenericJniTrampoline();
+ quick_to_interpreter_bridge_trampoline_ = oat_file.GetOatHeader().GetQuickToInterpreterBridge();
mirror::Object* dex_caches_object = space->GetImageHeader().GetImageRoot(ImageHeader::kDexCaches);
mirror::ObjectArray<mirror::DexCache>* dex_caches =
dex_caches_object->AsObjectArray<mirror::DexCache>();
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index a14d1d1..9771318 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -369,6 +369,10 @@ class ClassLinker {
return quick_imt_conflict_trampoline_;
}
+ const void* GetQuickToInterpreterBridgeTrampoline() const {
+ return quick_to_interpreter_bridge_trampoline_;
+ }
+
InternTable* GetInternTable() const {
return intern_table_;
}
@@ -658,6 +662,7 @@ class ClassLinker {
const void* portable_imt_conflict_trampoline_;
const void* quick_imt_conflict_trampoline_;
const void* quick_generic_jni_trampoline_;
+ const void* quick_to_interpreter_bridge_trampoline_;
friend class ImageWriter; // for GetClassRoots
FRIEND_TEST(ClassLinkerTest, ClassRootDescriptors);
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 5b72a44..1218357 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -485,8 +485,6 @@ struct ArtMethodOffsets : public CheckOffsets<mirror::ArtMethod> {
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_portable_compiled_code_), "entryPointFromPortableCompiledCode"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, entry_point_from_quick_compiled_code_), "entryPointFromQuickCompiledCode"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, gc_map_), "gcMap"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, quick_mapping_table_), "quickMappingTable"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, quick_vmap_table_), "quickVmapTable"));
// alphabetical 32-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, access_flags_), "accessFlags"));
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 8b48b36..05912bf 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -761,6 +761,10 @@ static inline const void* GetQuickGenericJniTrampoline(ClassLinker* class_linker
return class_linker->GetQuickGenericJniTrampoline();
}
+static inline const void* GetQuickToInterpreterBridgeTrampoline(ClassLinker* class_linker) {
+ return class_linker->GetQuickToInterpreterBridgeTrampoline();
+}
+
extern "C" void art_portable_proxy_invoke_handler();
static inline const void* GetPortableProxyInvokeHandler() {
return reinterpret_cast<void*>(art_portable_proxy_invoke_handler);
diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
index 633f580..60c5377 100644
--- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
@@ -32,6 +32,7 @@ extern "C" const void* artInstrumentationMethodEntryFromCode(mirror::ArtMethod*
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
const void* result = instrumentation->GetQuickCodeFor(method);
+ DCHECK(result != GetQuickToInterpreterBridgeTrampoline(Runtime::Current()->GetClassLinker()));
bool interpreter_entry = (result == GetQuickToInterpreterBridge());
instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? NULL : this_object,
method, lr, interpreter_entry);
diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc
index 208eb74..97a8367 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -49,10 +49,6 @@ class ExceptionTest : public CommonRuntimeTest {
dex_ = my_klass_->GetDexCache()->GetDexFile();
uint32_t code_size = 12;
- fake_code_.push_back((code_size >> 24) & 0xFF);
- fake_code_.push_back((code_size >> 16) & 0xFF);
- fake_code_.push_back((code_size >> 8) & 0xFF);
- fake_code_.push_back((code_size >> 0) & 0xFF);
for (size_t i = 0 ; i < code_size; i++) {
fake_code_.push_back(0x70 | i);
}
@@ -74,20 +70,35 @@ class ExceptionTest : public CommonRuntimeTest {
fake_gc_map_.push_back(0); // 0 entries.
fake_gc_map_.push_back(0);
+ const std::vector<uint8_t>& fake_vmap_table_data = fake_vmap_table_data_.GetData();
+ const std::vector<uint8_t>& fake_mapping_data = fake_mapping_data_.GetData();
+ uint32_t vmap_table_offset = sizeof(OatMethodHeader) + fake_vmap_table_data.size();
+ uint32_t mapping_table_offset = vmap_table_offset + fake_mapping_data.size();
+ OatMethodHeader method_header(vmap_table_offset, mapping_table_offset, code_size);
+ fake_header_code_and_maps_.resize(sizeof(method_header));
+ memcpy(&fake_header_code_and_maps_[0], &method_header, sizeof(method_header));
+ fake_header_code_and_maps_.insert(fake_header_code_and_maps_.begin(),
+ 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_.end(),
+ fake_code_.begin(), fake_code_.end());
+
+ // NOTE: Don't align the code (it will not be executed) but check that the Thumb2
+ // adjustment will be a NOP, see ArtMethod::EntryPointToCodePointer().
+ CHECK_EQ(mapping_table_offset & 1u, 0u);
+ const uint8_t* code_ptr = &fake_header_code_and_maps_[mapping_table_offset];
+
method_f_ = my_klass_->FindVirtualMethod("f", "()I");
ASSERT_TRUE(method_f_ != NULL);
method_f_->SetFrameSizeInBytes(4 * kPointerSize);
- method_f_->SetEntryPointFromQuickCompiledCode(&fake_code_[sizeof(code_size)]);
- method_f_->SetMappingTable(&fake_mapping_data_.GetData()[0]);
- method_f_->SetVmapTable(&fake_vmap_table_data_.GetData()[0]);
+ 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_->SetFrameSizeInBytes(4 * kPointerSize);
- method_g_->SetEntryPointFromQuickCompiledCode(&fake_code_[sizeof(code_size)]);
- method_g_->SetMappingTable(&fake_mapping_data_.GetData()[0]);
- method_g_->SetVmapTable(&fake_vmap_table_data_.GetData()[0]);
+ method_g_->SetEntryPointFromQuickCompiledCode(code_ptr);
method_g_->SetNativeGcMap(&fake_gc_map_[0]);
}
@@ -97,6 +108,7 @@ class ExceptionTest : public CommonRuntimeTest {
Leb128EncodingVector fake_mapping_data_;
Leb128EncodingVector fake_vmap_table_data_;
std::vector<uint8_t> fake_gc_map_;
+ std::vector<uint8_t> fake_header_code_and_maps_;
mirror::ArtMethod* method_f_;
mirror::ArtMethod* method_g_;
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 2cd7f49..77d29dd 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -94,6 +94,7 @@ static void UpdateEntrypoints(mirror::ArtMethod* method, const void* quick_code,
}
if (!method->IsResolutionMethod()) {
if (quick_code == GetQuickToInterpreterBridge() ||
+ quick_code == GetQuickToInterpreterBridgeTrampoline(Runtime::Current()->GetClassLinker()) ||
(quick_code == GetQuickResolutionTrampoline(Runtime::Current()->GetClassLinker()) &&
Runtime::Current()->GetInstrumentation()->IsForcedInterpretOnly()
&& !method->IsNative() && !method->IsProxyMethod())) {
@@ -147,6 +148,7 @@ void Instrumentation::InstallStubsForMethod(mirror::ArtMethod* method) {
// Do not overwrite interpreter to prevent from posting method entry/exit events twice.
new_portable_code = class_linker->GetPortableOatCodeFor(method, &have_portable_code);
new_quick_code = class_linker->GetQuickOatCodeFor(method);
+ DCHECK(new_quick_code != GetQuickToInterpreterBridgeTrampoline(class_linker));
if (entry_exit_stubs_installed_ && new_quick_code != GetQuickToInterpreterBridge()) {
DCHECK(new_portable_code != GetPortableToInterpreterBridge());
new_portable_code = GetPortableToInterpreterBridge();
@@ -562,7 +564,8 @@ void Instrumentation::UpdateMethodsCode(mirror::ArtMethod* method, const void* q
new_quick_code = GetQuickToInterpreterBridge();
new_have_portable_code = false;
} else if (quick_code == GetQuickResolutionTrampoline(Runtime::Current()->GetClassLinker()) ||
- quick_code == GetQuickToInterpreterBridge()) {
+ quick_code == GetQuickToInterpreterBridgeTrampoline(Runtime::Current()->GetClassLinker()) ||
+ quick_code == GetQuickToInterpreterBridge()) {
DCHECK((portable_code == GetPortableResolutionTrampoline(Runtime::Current()->GetClassLinker())) ||
(portable_code == GetPortableToInterpreterBridge()));
new_portable_code = portable_code;
@@ -709,9 +712,10 @@ const void* Instrumentation::GetQuickCodeFor(mirror::ArtMethod* method) const {
Runtime* runtime = Runtime::Current();
if (LIKELY(!instrumentation_stubs_installed_)) {
const void* code = method->GetEntryPointFromQuickCompiledCode();
- DCHECK(code != NULL);
- if (LIKELY(code != GetQuickResolutionTrampoline(runtime->GetClassLinker()) &&
- code != GetQuickToInterpreterBridge())) {
+ DCHECK(code != nullptr);
+ if (LIKELY(code != GetQuickResolutionTrampoline(runtime->GetClassLinker())) &&
+ LIKELY(code != GetQuickToInterpreterBridgeTrampoline(runtime->GetClassLinker())) &&
+ LIKELY(code != GetQuickToInterpreterBridge())) {
return code;
}
}
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 5d62b88..6e1f062 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -78,13 +78,11 @@ inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() {
inline uint32_t ArtMethod::GetCodeSize() {
DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
- uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
- if (code == 0) {
- return 0;
+ const void* code = EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode());
+ if (code == nullptr) {
+ return 0u;
}
- // TODO: make this Thumb2 specific
- code &= ~0x1;
- return reinterpret_cast<OatMethodHeader*>(code)[-1].code_size_;
+ return reinterpret_cast<const OatMethodHeader*>(code)[-1].code_size_;
}
inline bool ArtMethod::CheckIncompatibleClassChange(InvokeType type) {
@@ -124,7 +122,8 @@ inline void ArtMethod::AssertPcIsWithinQuickCode(uintptr_t pc) {
return;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- if (code == GetQuickResolutionTrampoline(class_linker)) {
+ if (code == GetQuickResolutionTrampoline(class_linker) ||
+ code == GetQuickToInterpreterBridgeTrampoline(class_linker)) {
return;
}
DCHECK(IsWithinQuickCode(pc))
@@ -154,26 +153,6 @@ inline void ArtMethod::SetPortableOatCodeOffset(uint32_t code_offset) {
SetEntryPointFromPortableCompiledCode(reinterpret_cast<void*>(code_offset));
}
-inline uint32_t ArtMethod::GetOatMappingTableOffset() {
- DCHECK(!Runtime::Current()->IsStarted());
- return PointerToLowMemUInt32(GetMappingTable());
-}
-
-inline void ArtMethod::SetOatMappingTableOffset(uint32_t mapping_table_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetMappingTable(reinterpret_cast<const uint8_t*>(mapping_table_offset));
-}
-
-inline uint32_t ArtMethod::GetOatVmapTableOffset() {
- DCHECK(!Runtime::Current()->IsStarted());
- return PointerToLowMemUInt32(GetVmapTable());
-}
-
-inline void ArtMethod::SetOatVmapTableOffset(uint32_t vmap_table_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetVmapTable(reinterpret_cast<uint8_t*>(vmap_table_offset));
-}
-
inline void ArtMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
DCHECK(!Runtime::Current()->IsStarted());
SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index 726004b..90bcbab 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -368,5 +368,43 @@ void ArtMethod::UnregisterNative(Thread* self) {
RegisterNative(self, GetJniDlsymLookupStub(), false);
}
+const void* ArtMethod::GetOatCodePointer() {
+ if (IsPortableCompiled() || IsNative() || IsAbstract() || IsRuntimeMethod() || IsProxyMethod()) {
+ return nullptr;
+ }
+ Runtime* runtime = Runtime::Current();
+ const void* entry_point = runtime->GetInstrumentation()->GetQuickCodeFor(this);
+ // On failure, instead of nullptr we get the quick-to-interpreter-bridge (but not the trampoline).
+ DCHECK(entry_point != GetQuickToInterpreterBridgeTrampoline(runtime->GetClassLinker()));
+ if (entry_point == GetQuickToInterpreterBridge()) {
+ return nullptr;
+ }
+ return EntryPointToCodePointer(entry_point);
+}
+
+const uint8_t* ArtMethod::GetMappingTable() {
+ const void* code = GetOatCodePointer();
+ if (code == nullptr) {
+ return nullptr;
+ }
+ uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].mapping_table_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
+const uint8_t* ArtMethod::GetVmapTable() {
+ const void* code = GetOatCodePointer();
+ if (code == nullptr) {
+ return nullptr;
+ }
+ uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].vmap_table_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index 4462036..b3b9ca7 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -21,6 +21,7 @@
#include "dex_file.h"
#include "invoke_type.h"
#include "modifiers.h"
+#include "oat.h"
#include "object.h"
#include "object_callbacks.h"
@@ -261,7 +262,6 @@ class MANAGED ArtMethod : public Object {
EntryPointFromQuickCompiledCodeOffset(), entry_point_from_quick_compiled_code, false);
}
-
uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -286,37 +286,20 @@ class MANAGED ArtMethod : public Object {
void SetQuickOatCodeOffset(uint32_t code_offset);
void SetPortableOatCodeOffset(uint32_t code_offset);
- // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
- const uint8_t* GetMappingTable() {
- return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_),
- false);
- }
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- void SetMappingTable(const uint8_t* mapping_table) {
- SetFieldPtr<false, true, kVerifyFlags>(
- OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_), mapping_table, false);
+ static const void* EntryPointToCodePointer(const void* entry_point) ALWAYS_INLINE {
+ uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
+ code &= ~0x1; // TODO: Make this Thumb2 specific.
+ return reinterpret_cast<const void*>(code);
}
- uint32_t GetOatMappingTableOffset();
+ // Actual pointer to compiled oat code or nullptr.
+ const void* GetOatCodePointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetOatMappingTableOffset(uint32_t mapping_table_offset);
+ // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
+ const uint8_t* GetMappingTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
- const uint8_t* GetVmapTable() {
- return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_),
- false);
- }
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- void SetVmapTable(const uint8_t* vmap_table) {
- SetFieldPtr<false, true, kVerifyFlags>(
- OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_), vmap_table, false);
- }
-
- uint32_t GetOatVmapTableOffset();
-
- void SetOatVmapTableOffset(uint32_t vmap_table_offset);
+ const uint8_t* GetVmapTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const uint8_t* GetNativeGcMap() {
return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), false);
@@ -471,20 +454,6 @@ class MANAGED ArtMethod : public Object {
// offsets for the quick compiler and dex PCs for the portable.
uint64_t gc_map_;
- // --- Quick compiler meta-data. ---
- // TODO: merge and place in native heap, such as done with the code size.
-
- // Pointer to a data structure created by the quick compiler to map between dex PCs and native
- // PCs, and vice-versa.
- uint64_t quick_mapping_table_;
-
- // When a register is promoted into a register, the spill mask holds which registers hold dex
- // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
- // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
- uint64_t quick_vmap_table_;
-
- // --- End of quick compiler meta-data. ---
-
// Access flags; low 16 bits are defined by spec.
uint32_t access_flags_;
diff --git a/runtime/oat.cc b/runtime/oat.cc
index d01dc72..c1a48e9 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -22,7 +22,7 @@
namespace art {
const uint8_t OatHeader::kOatMagic[] = { 'o', 'a', 't', '\n' };
-const uint8_t OatHeader::kOatVersion[] = { '0', '2', '1', '\0' };
+const uint8_t OatHeader::kOatVersion[] = { '0', '2', '2', '\0' };
OatHeader::OatHeader() {
memset(this, 0, sizeof(*this));
@@ -348,8 +348,6 @@ OatMethodOffsets::OatMethodOffsets()
frame_size_in_bytes_(0),
core_spill_mask_(0),
fp_spill_mask_(0),
- mapping_table_offset_(0),
- vmap_table_offset_(0),
gc_map_offset_(0)
{}
@@ -357,27 +355,28 @@ OatMethodOffsets::OatMethodOffsets(uint32_t code_offset,
uint32_t frame_size_in_bytes,
uint32_t core_spill_mask,
uint32_t fp_spill_mask,
- uint32_t mapping_table_offset,
- uint32_t vmap_table_offset,
uint32_t gc_map_offset
)
: code_offset_(code_offset),
frame_size_in_bytes_(frame_size_in_bytes),
core_spill_mask_(core_spill_mask),
fp_spill_mask_(fp_spill_mask),
- mapping_table_offset_(mapping_table_offset),
- vmap_table_offset_(vmap_table_offset),
gc_map_offset_(gc_map_offset)
{}
OatMethodOffsets::~OatMethodOffsets() {}
OatMethodHeader::OatMethodHeader()
- : code_size_(0)
+ : mapping_table_offset_(0),
+ vmap_table_offset_(0),
+ code_size_(0)
{}
-OatMethodHeader::OatMethodHeader(uint32_t code_size)
- : code_size_(code_size)
+OatMethodHeader::OatMethodHeader(uint32_t vmap_table_offset, uint32_t mapping_table_offset,
+ uint32_t code_size)
+ : mapping_table_offset_(mapping_table_offset),
+ vmap_table_offset_(vmap_table_offset),
+ code_size_(code_size)
{}
OatMethodHeader::~OatMethodHeader() {}
diff --git a/runtime/oat.h b/runtime/oat.h
index 035aba1..e9dfae9 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -119,9 +119,9 @@ class PACKED(4) OatHeader {
DISALLOW_COPY_AND_ASSIGN(OatHeader);
};
-// OatMethodOffsets are currently 7x32-bits=224-bits long, so if we can
+// OatMethodOffsets are currently 5x32-bits=160-bits long, so if we can
// save even one OatMethodOffsets struct, the more complicated encoding
-// using a bitmap pays for itself since few classes will have 224
+// using a bitmap pays for itself since few classes will have 160
// methods.
enum OatClassType {
kOatClassAllCompiled = 0, // OatClass is followed by an OatMethodOffsets for each method.
@@ -140,8 +140,6 @@ class PACKED(4) OatMethodOffsets {
uint32_t frame_size_in_bytes,
uint32_t core_spill_mask,
uint32_t fp_spill_mask,
- uint32_t mapping_table_offset,
- uint32_t vmap_table_offset,
uint32_t gc_map_offset);
~OatMethodOffsets();
@@ -150,8 +148,6 @@ class PACKED(4) OatMethodOffsets {
uint32_t frame_size_in_bytes_;
uint32_t core_spill_mask_;
uint32_t fp_spill_mask_;
- uint32_t mapping_table_offset_;
- uint32_t vmap_table_offset_;
uint32_t gc_map_offset_;
};
@@ -160,10 +156,15 @@ class PACKED(4) OatMethodHeader {
public:
OatMethodHeader();
- explicit OatMethodHeader(uint32_t code_size);
+ explicit OatMethodHeader(uint32_t mapping_table_offset, uint32_t vmap_table_offset,
+ uint32_t code_size);
~OatMethodHeader();
+ // The offset in bytes from the start of the mapping table to the end of the header.
+ 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 code size in bytes.
uint32_t code_size_;
};
diff --git a/runtime/oat_file-inl.h b/runtime/oat_file-inl.h
new file mode 100644
index 0000000..00ae797
--- /dev/null
+++ b/runtime/oat_file-inl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_OAT_FILE_INL_H_
+#define ART_RUNTIME_OAT_FILE_INL_H_
+
+#include "oat_file.h"
+
+namespace art {
+
+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);
+}
+
+inline uint32_t OatFile::OatMethod::GetVmapTableOffset() const {
+ const uint8_t* vmap_table = GetVmapTable();
+ return static_cast<uint32_t>(vmap_table != nullptr ? vmap_table - begin_ : 0u);
+}
+
+inline const uint8_t* OatFile::OatMethod::GetMappingTable() const {
+ const void* code = mirror::ArtMethod::EntryPointToCodePointer(GetQuickCode());
+ if (code == nullptr) {
+ return nullptr;
+ }
+ uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].mapping_table_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
+inline const uint8_t* OatFile::OatMethod::GetVmapTable() const {
+ const void* code = mirror::ArtMethod::EntryPointToCodePointer(GetQuickCode());
+ if (code == nullptr) {
+ return nullptr;
+ }
+ uint32_t offset = reinterpret_cast<const OatMethodHeader*>(code)[-1].vmap_table_offset_;
+ if (UNLIKELY(offset == 0u)) {
+ return nullptr;
+ }
+ return reinterpret_cast<const uint8_t*>(code) - offset;
+}
+
+} // namespace art
+
+#endif // ART_RUNTIME_OAT_FILE_INL_H_
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 0aff8c3..56e1f05 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -464,7 +464,7 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index)
// NOTE: We don't keep the number of methods and cannot do a bounds check for method_index.
if (methods_pointer_ == NULL) {
CHECK_EQ(kOatClassNoneCompiled, type_);
- return OatMethod(NULL, 0, 0, 0, 0, 0, 0, 0);
+ return OatMethod(NULL, 0, 0, 0, 0, 0);
}
size_t methods_pointer_index;
if (bitmap_ == NULL) {
@@ -473,7 +473,7 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index)
} else {
CHECK_EQ(kOatClassSomeCompiled, type_);
if (!BitVector::IsBitSet(bitmap_, method_index)) {
- return OatMethod(NULL, 0, 0, 0, 0, 0, 0, 0);
+ return OatMethod(NULL, 0, 0, 0, 0, 0);
}
size_t num_set_bits = BitVector::NumSetBits(bitmap_, method_index);
methods_pointer_index = num_set_bits;
@@ -485,8 +485,6 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index)
oat_method_offsets.frame_size_in_bytes_,
oat_method_offsets.core_spill_mask_,
oat_method_offsets.fp_spill_mask_,
- oat_method_offsets.mapping_table_offset_,
- oat_method_offsets.vmap_table_offset_,
oat_method_offsets.gc_map_offset_);
}
@@ -495,32 +493,13 @@ OatFile::OatMethod::OatMethod(const byte* base,
const size_t frame_size_in_bytes,
const uint32_t core_spill_mask,
const uint32_t fp_spill_mask,
- const uint32_t mapping_table_offset,
- const uint32_t vmap_table_offset,
const uint32_t gc_map_offset)
: begin_(base),
code_offset_(code_offset),
frame_size_in_bytes_(frame_size_in_bytes),
core_spill_mask_(core_spill_mask),
fp_spill_mask_(fp_spill_mask),
- mapping_table_offset_(mapping_table_offset),
- vmap_table_offset_(vmap_table_offset),
native_gc_map_offset_(gc_map_offset) {
- if (kIsDebugBuild) {
- if (mapping_table_offset_ != 0) { // implies non-native, non-stub code
- if (vmap_table_offset_ == 0) {
- CHECK_EQ(0U, static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) +
- __builtin_popcount(fp_spill_mask_)));
- } else {
- VmapTable vmap_table(reinterpret_cast<const uint8_t*>(begin_ + vmap_table_offset_));
-
- CHECK_EQ(vmap_table.Size(), static_cast<uint32_t>(__builtin_popcount(core_spill_mask_) +
- __builtin_popcount(fp_spill_mask_)));
- }
- } else {
- CHECK_EQ(vmap_table_offset_, 0U);
- }
- }
}
OatFile::OatMethod::~OatMethod() {}
@@ -543,8 +522,6 @@ void OatFile::OatMethod::LinkMethod(mirror::ArtMethod* method) const {
method->SetFrameSizeInBytes(frame_size_in_bytes_);
method->SetCoreSpillMask(core_spill_mask_);
method->SetFpSpillMask(fp_spill_mask_);
- method->SetMappingTable(GetMappingTable());
- method->SetVmapTable(GetVmapTable());
method->SetNativeGcMap(GetNativeGcMap()); // Used by native methods in work around JNI mode.
}
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 10f64cc..5f6cb1e 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -87,12 +87,6 @@ class OatFile {
uint32_t GetFpSpillMask() const {
return fp_spill_mask_;
}
- uint32_t GetMappingTableOffset() const {
- return mapping_table_offset_;
- }
- uint32_t GetVmapTableOffset() const {
- return vmap_table_offset_;
- }
uint32_t GetNativeGcMapOffset() const {
return native_gc_map_offset_;
}
@@ -122,16 +116,15 @@ class OatFile {
}
uint32_t GetQuickCodeSize() const;
- const uint8_t* GetMappingTable() const {
- return GetOatPointer<const uint8_t*>(mapping_table_offset_);
- }
- const uint8_t* GetVmapTable() const {
- return GetOatPointer<const uint8_t*>(vmap_table_offset_);
- }
const uint8_t* GetNativeGcMap() const {
return GetOatPointer<const uint8_t*>(native_gc_map_offset_);
}
+ uint32_t GetMappingTableOffset() const;
+ uint32_t GetVmapTableOffset() const;
+ const uint8_t* GetMappingTable() const;
+ const uint8_t* GetVmapTable() const;
+
~OatMethod();
// Create an OatMethod with offsets relative to the given base address
@@ -140,8 +133,6 @@ class OatFile {
const size_t frame_size_in_bytes,
const uint32_t core_spill_mask,
const uint32_t fp_spill_mask,
- const uint32_t mapping_table_offset,
- const uint32_t vmap_table_offset,
const uint32_t gc_map_offset);
private:
@@ -159,8 +150,6 @@ class OatFile {
size_t frame_size_in_bytes_;
uint32_t core_spill_mask_;
uint32_t fp_spill_mask_;
- uint32_t mapping_table_offset_;
- uint32_t vmap_table_offset_;
uint32_t native_gc_map_offset_;
friend class OatClass;