Use class def index from java.lang.Class.
Bug: 10244719
This removes the computation of the dex file index, when necessary this is
computed by searching the dex file. Its only necessary in
dalvik.system.DexFile.defineClassNative and DexFile::FindInClassPath, the
latter not showing up significantly in profiling with this change.
(cherry-picked from 8b2c0b9abc3f520495f4387ea040132ba85cae69)
Change-Id: I20c73a3b17d86286428ab0fd21bc13f51f36c85c
diff --git a/runtime/Android.mk b/runtime/Android.mk
index a8d505e..a0ae4bf 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -92,6 +92,7 @@
native/dalvik_system_VMStack.cc \
native/dalvik_system_Zygote.cc \
native/java_lang_Class.cc \
+ native/java_lang_DexCache.cc \
native/java_lang_Object.cc \
native/java_lang_Runtime.cc \
native/java_lang_String.cc \
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 0773a8d..4043f8b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,40 +475,33 @@
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
mirror::Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
- mirror::Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;");
- mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
-
- const DexFile& java_lang_dex = *java_lang_ref_Reference->GetDexCache()->GetDexFile();
+ mirror::Class* java_lang_ref_FinalizerReference =
+ FindSystemClass("Ljava/lang/ref/FinalizerReference;");
mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
FieldHelper fh(pendingNext, this);
CHECK_STREQ(fh.GetName(), "pendingNext");
- CHECK_EQ(java_lang_dex.GetFieldId(pendingNext->GetDexFieldIndex()).type_idx_,
- java_lang_ref_Reference->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
mirror::ArtField* queue = java_lang_ref_Reference->GetInstanceField(1);
fh.ChangeField(queue);
CHECK_STREQ(fh.GetName(), "queue");
- CHECK_EQ(java_lang_dex.GetFieldId(queue->GetDexFieldIndex()).type_idx_,
- java_lang_ref_ReferenceQueue->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;");
mirror::ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2);
fh.ChangeField(queueNext);
CHECK_STREQ(fh.GetName(), "queueNext");
- CHECK_EQ(java_lang_dex.GetFieldId(queueNext->GetDexFieldIndex()).type_idx_,
- java_lang_ref_Reference->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
mirror::ArtField* referent = java_lang_ref_Reference->GetInstanceField(3);
fh.ChangeField(referent);
CHECK_STREQ(fh.GetName(), "referent");
- CHECK_EQ(java_lang_dex.GetFieldId(referent->GetDexFieldIndex()).type_idx_,
- GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
mirror::ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
fh.ChangeField(zombie);
CHECK_STREQ(fh.GetName(), "zombie");
- CHECK_EQ(java_lang_dex.GetFieldId(zombie->GetDexFieldIndex()).type_idx_,
- GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
+ CHECK_STREQ(fh.GetTypeDescriptor(), "Ljava/lang/Object;");
gc::Heap* heap = Runtime::Current()->GetHeap();
heap->SetReferenceOffsets(referent->GetOffset(),
@@ -1231,8 +1224,10 @@
return NULL;
}
mirror::Class* klass = k->AsClass();
- klass->SetPrimitiveType(Primitive::kPrimNot); // default to not being primitive
+ klass->SetPrimitiveType(Primitive::kPrimNot); // Default to not being primitive.
klass->SetClassSize(class_size);
+ klass->SetDexClassDefIndex(DexFile::kDexNoIndex16); // Default to no valid class def index.
+ klass->SetDexTypeIndex(DexFile::kDexNoIndex16); // Default to no valid type index.
return klass;
}
@@ -1496,26 +1491,21 @@
return size;
}
-const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, const char* descriptor) {
- DCHECK(descriptor != NULL);
+const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) {
+ DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
- CHECK(oat_file != NULL) << dex_file.GetLocation() << " " << descriptor;
+ CHECK(oat_file != NULL) << dex_file.GetLocation();
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
- CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << descriptor;
- uint32_t class_def_index;
- bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
- CHECK(found) << dex_file.GetLocation() << " " << descriptor;
- const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_index);
- CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << descriptor;
+ CHECK(oat_dex_file != NULL) << dex_file.GetLocation();
+ const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_idx);
+ CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << class_def_idx;
return oat_class;
}
-static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint32_t method_idx) {
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
- const DexFile::TypeId& type_id = dex_file.GetTypeId(method_id.class_idx_);
- const DexFile::ClassDef* class_def = dex_file.FindClassDef(dex_file.GetTypeDescriptor(type_id));
- CHECK(class_def != NULL);
- const byte* class_data = dex_file.GetClassData(*class_def);
+static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint16_t class_def_idx,
+ uint32_t method_idx) {
+ const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_idx);
+ const byte* class_data = dex_file.GetClassData(class_def);
CHECK(class_data != NULL);
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -1569,11 +1559,13 @@
}
CHECK(found) << "Didn't find oat method index for virtual method: " << PrettyMethod(method);
}
- ClassHelper kh(declaring_class);
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(kh.GetDexFile(), kh.GetDescriptor()));
+ UniquePtr<const OatFile::OatClass>
+ oat_class(GetOatClass(*declaring_class->GetDexCache()->GetDexFile(),
+ declaring_class->GetDexClassDefIndex()));
CHECK(oat_class.get() != NULL);
DCHECK_EQ(oat_method_index,
GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
+ method->GetDeclaringClass()->GetDexClassDefIndex(),
method->GetDexMethodIndex()));
return oat_class->GetOatMethod(oat_method_index);
@@ -1597,12 +1589,11 @@
return result;
}
-const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx) {
- const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
- const char* descriptor = dex_file.GetTypeDescriptor(dex_file.GetTypeId(method_id.class_idx_));
- uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, method_idx);
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, descriptor));
- CHECK(oat_class.get() != NULL);
+const void* ClassLinker::GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
+ uint32_t method_idx) {
+ UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, class_def_idx));
+ CHECK(oat_class.get() != nullptr);
+ uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
return oat_class->GetOatMethod(oat_method_idx).GetCode();
}
@@ -1639,7 +1630,7 @@
// OAT file unavailable
return;
}
- UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, kh.GetDescriptor()));
+ UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
CHECK(oat_class.get() != NULL);
ClassDataItemIterator it(dex_file, class_data);
// Skip fields
@@ -1731,6 +1722,7 @@
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
klass->SetStatus(mirror::Class::kStatusIdx, NULL);
+ klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
klass->SetDexTypeIndex(dex_class_def.class_idx_);
// Load fields fields.
@@ -1778,7 +1770,7 @@
UniquePtr<const OatFile::OatClass> oat_class;
if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) {
- oat_class.reset(GetOatClass(dex_file, descriptor));
+ oat_class.reset(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
}
// Load methods.
@@ -1873,7 +1865,8 @@
if (klass->GetClassLoader() != NULL) { // All non-boot finalizer methods are flagged
klass->SetFinalizable();
} else {
- StringPiece klass_descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
+ ClassHelper kh(klass.get());
+ StringPiece klass_descriptor(kh.GetDescriptor());
// The Enum class declares a "final" finalize() method to prevent subclasses from
// introducing a finalizer. We don't want to set the finalizable flag for Enum or its
// subclasses, so we exclude it here.
@@ -2339,12 +2332,16 @@
const DexFile* dex_file = dex_cache->GetDexFile();
// First search using the class def map, but don't bother for non-class types.
if (descriptor[0] == 'L') {
- const DexFile::ClassDef* class_def = dex_file->FindClassDef(descriptor);
- if (class_def != NULL) {
- mirror::Class* klass = dex_cache->GetResolvedType(class_def->class_idx_);
- if (klass != NULL) {
- self->EndAssertNoThreadSuspension(old_no_suspend_cause);
- return klass;
+ const DexFile::StringId* descriptor_string_id = dex_file->FindStringId(descriptor);
+ if (descriptor_string_id != NULL) {
+ const DexFile::TypeId* type_id =
+ dex_file->FindTypeId(dex_file->GetIndexForStringId(*descriptor_string_id));
+ if (type_id != NULL) {
+ mirror::Class* klass = dex_cache->GetResolvedType(dex_file->GetIndexForTypeId(*type_id));
+ if (klass != NULL) {
+ self->EndAssertNoThreadSuspension(old_no_suspend_cause);
+ return klass;
+ }
}
}
}
@@ -2455,8 +2452,9 @@
verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
std::string error_msg;
if (!preverified) {
- verifier_failure = verifier::MethodVerifier::VerifyClass(klass, error_msg,
- Runtime::Current()->IsCompiler());
+ verifier_failure = verifier::MethodVerifier::VerifyClass(klass,
+ Runtime::Current()->IsCompiler(),
+ &error_msg);
}
if (preverified || verifier_failure != verifier::MethodVerifier::kHardFailure) {
if (!preverified && verifier_failure != verifier::MethodVerifier::kNoFailure) {
@@ -2527,7 +2525,6 @@
}
}
-
const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
// Make this work with gtests, which do not set up the image properly.
// TODO: we should clean up gtests to set up the image path properly.
@@ -2539,9 +2536,7 @@
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
const char* descriptor = ClassHelper(klass).GetDescriptor();
- uint32_t class_def_index;
- bool found = dex_file.FindClassDefIndex(descriptor, class_def_index);
- CHECK(found) << dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
+ uint16_t class_def_index = klass->GetDexClassDefIndex();
UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index));
CHECK(oat_class.get() != NULL)
<< dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
@@ -2654,8 +2649,6 @@
klass->SetStatus(mirror::Class::kStatusIdx, self);
- klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
-
// Instance fields are inherited, but we add a couple of static fields...
{
mirror::ObjectArray<mirror::ArtField>* sfields = AllocArtFieldArray(self, 2);
@@ -3262,10 +3255,8 @@
bool ClassLinker::LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const DexFile& dex_file) {
CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus());
- StringPiece descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
- const DexFile::ClassDef* class_def = dex_file.FindClassDef(descriptor);
- CHECK(class_def != NULL);
- uint16_t super_class_idx = class_def->superclass_idx_;
+ const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());
+ uint16_t super_class_idx = class_def.superclass_idx_;
if (super_class_idx != DexFile::kDexNoIndex16) {
mirror::Class* super_class = ResolveType(dex_file, super_class_idx, klass.get());
if (super_class == NULL) {
@@ -3281,7 +3272,7 @@
}
klass->SetSuperClass(super_class);
}
- const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(*class_def);
+ const DexFile::TypeList* interfaces = dex_file.GetInterfacesList(class_def);
if (interfaces != NULL) {
for (size_t i = 0; i < interfaces->Size(); i++) {
uint16_t idx = interfaces->GetTypeItem(i).type_idx_;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 20efbb4..3ffcf14 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -329,7 +329,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get the oat code for a method from a method index.
- const void* GetOatCodeFor(const DexFile& dex_file, uint32_t method_idx)
+ const void* GetOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
pid_t GetClassesLockOwner(); // For SignalCatcher.
@@ -424,7 +424,7 @@
void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the associated oat class for a dex_file and descriptor
- const OatFile::OatClass* GetOatClass(const DexFile& dex_file, const char* descriptor)
+ const OatFile::OatClass* GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 995434c..bbc2877 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -507,6 +507,7 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, access_flags_), "accessFlags"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, class_size_), "classSize"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, clinit_thread_id_), "clinitThreadId"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_), "dexClassDefIndex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_), "dexTypeIndex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_instance_fields_), "numReferenceInstanceFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_static_fields_), "numReferenceStaticFields"));
@@ -569,10 +570,6 @@
struct ClassClassOffsets : public CheckOffsets<mirror::ClassClass> {
ClassClassOffsets() : CheckOffsets<mirror::ClassClass>(true, "Ljava/lang/Class;") {
- // padding 32-bit
- CHECK_EQ(OFFSETOF_MEMBER(mirror::ClassClass, padding_) + 4,
- OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_));
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ClassClass, serialVersionUID_), "serialVersionUID"));
};
@@ -584,11 +581,11 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, ASCII_), "ASCII"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
- // padding 32-bit
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, serialVersionUID_), "serialVersionUID"));
+
+ // alphabetical 32-bit
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
};
};
@@ -605,6 +602,7 @@
struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> {
DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
// alphabetical references
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_), "dex"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, initialized_static_storage_), "initializedStaticStorage"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, location_), "location"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_), "resolvedFields"));
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 4fd9a60..e81c456 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -48,7 +48,7 @@
const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' };
-DexFile::ClassPathEntry DexFile::FindInClassPath(const StringPiece& descriptor,
+DexFile::ClassPathEntry DexFile::FindInClassPath(const char* descriptor,
const ClassPath& class_path) {
for (size_t i = 0; i != class_path.size(); ++i) {
const DexFile* dex_file = class_path[i];
@@ -251,56 +251,11 @@
// the global reference table is otherwise empty!
}
-class ScopedJniMonitorLock {
- public:
- ScopedJniMonitorLock(JNIEnv* env, jobject locked) : env_(env), locked_(locked) {
- env->MonitorEnter(locked_);
- }
- ~ScopedJniMonitorLock() {
- env_->MonitorExit(locked_);
- }
- private:
- JNIEnv* const env_;
- const jobject locked_;
-};
-
-jobject DexFile::GetDexObject(JNIEnv* env) const {
- {
- ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
- if (dex_object_ != NULL) {
- return dex_object_;
- }
- }
- void* address = const_cast<void*>(reinterpret_cast<const void*>(begin_));
- jobject byte_buffer = env->NewDirectByteBuffer(address, size_);
- if (byte_buffer == NULL) {
- return NULL;
- }
-
- ScopedJniMonitorLock lock(env, WellKnownClasses::com_android_dex_Dex);
- // Re-test to see if someone beat us to the creation when we had the lock released.
- if (dex_object_ != NULL) {
- return dex_object_;
- }
- jvalue args[1];
- args[0].l = byte_buffer;
- jobject local = env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
- WellKnownClasses::com_android_dex_Dex_create,
- args);
- if (local == NULL) {
- return NULL;
- }
-
- dex_object_ = env->NewGlobalRef(local);
- return dex_object_;
-}
-
bool DexFile::Init() {
InitMembers();
if (!CheckMagicAndVersion()) {
return false;
}
- InitIndex();
return true;
}
@@ -351,28 +306,36 @@
return atoi(version);
}
-void DexFile::InitIndex() {
- CHECK_EQ(index_.size(), 0U) << GetLocation();
- for (size_t i = 0; i < NumClassDefs(); ++i) {
+const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const {
+ size_t num_class_defs = NumClassDefs();
+ if (num_class_defs == 0) {
+ return NULL;
+ }
+ const StringId* string_id = FindStringId(descriptor);
+ if (string_id == NULL) {
+ return NULL;
+ }
+ const TypeId* type_id = FindTypeId(GetIndexForStringId(*string_id));
+ if (type_id == NULL) {
+ return NULL;
+ }
+ uint16_t type_idx = GetIndexForTypeId(*type_id);
+ for (size_t i = 0; i < num_class_defs; ++i) {
const ClassDef& class_def = GetClassDef(i);
- const char* descriptor = GetClassDescriptor(class_def);
- index_.Put(descriptor, i);
+ if (class_def.class_idx_ == type_idx) {
+ return &class_def;
+ }
}
+ return NULL;
}
-bool DexFile::FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const {
- Index::const_iterator it = index_.find(descriptor);
- if (it == index_.end()) {
- return false;
- }
- idx = it->second;
- return true;
-}
-
-const DexFile::ClassDef* DexFile::FindClassDef(const StringPiece& descriptor) const {
- uint32_t idx;
- if (FindClassDefIndex(descriptor, idx)) {
- return &GetClassDef(idx);
+const DexFile::ClassDef* DexFile::FindClassDef(uint16_t type_idx) const {
+ size_t num_class_defs = NumClassDefs();
+ for (size_t i = 0; i < num_class_defs; ++i) {
+ const ClassDef& class_def = GetClassDef(i);
+ if (class_def.class_idx_ == type_idx) {
+ return &class_def;
+ }
}
return NULL;
}
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 26635ae..7be5cb8 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -339,7 +339,7 @@
typedef std::vector<const DexFile*> ClassPath;
// Search a collection of DexFiles for a descriptor
- static ClassPathEntry FindInClassPath(const StringPiece& descriptor,
+ static ClassPathEntry FindInClassPath(const char* descriptor,
const ClassPath& class_path);
// Returns the checksum of a file for comparison with GetLocationChecksum().
@@ -376,10 +376,6 @@
return location_checksum_;
}
- // Returns a com.android.dex.Dex object corresponding to the mapped-in dex file.
- // Used by managed code to implement annotations.
- jobject GetDexObject(JNIEnv* env) const;
-
const Header& GetHeader() const {
DCHECK(header_ != NULL) << GetLocation();
return *header_;
@@ -584,12 +580,12 @@
}
// Returns the ClassDef at the specified index.
- const ClassDef& GetClassDef(uint32_t idx) const {
+ const ClassDef& GetClassDef(uint16_t idx) const {
DCHECK_LT(idx, NumClassDefs()) << GetLocation();
return class_defs_[idx];
}
- uint32_t GetIndexForClassDef(const ClassDef& class_def) const {
+ uint16_t GetIndexForClassDef(const ClassDef& class_def) const {
CHECK_GE(&class_def, class_defs_) << GetLocation();
CHECK_LT(&class_def, class_defs_ + header_->class_defs_size_) << GetLocation();
return &class_def - class_defs_;
@@ -601,10 +597,10 @@
}
// Looks up a class definition by its class descriptor.
- const ClassDef* FindClassDef(const StringPiece& descriptor) const;
+ const ClassDef* FindClassDef(const char* descriptor) const;
- // Looks up a class definition index by its class descriptor.
- bool FindClassDefIndex(const StringPiece& descriptor, uint32_t& idx) const;
+ // Looks up a class definition by its type index.
+ const ClassDef* FindClassDef(uint16_t type_idx) const;
const TypeList* GetInterfacesList(const ClassDef& class_def) const {
if (class_def.interfaces_off_ == 0) {
@@ -809,6 +805,14 @@
bool DisableWrite() const;
+ const byte* Begin() const {
+ return begin_;
+ }
+
+ size_t Size() const {
+ return size_;
+ }
+
private:
// Opens a .dex file
static const DexFile* OpenFile(const std::string& filename,
@@ -840,7 +844,6 @@
location_(location),
location_checksum_(location_checksum),
mem_map_(mem_map),
- dex_object_(NULL),
modification_lock("DEX modification lock"),
header_(0),
string_ids_(0),
@@ -853,23 +856,12 @@
CHECK_GT(size_, 0U) << GetLocation();
}
- const byte* Begin() const {
- return begin_;
- }
-
- size_t Size() const {
- return size_;
- }
-
// Top-level initializer that calls other Init methods.
bool Init();
// Caches pointers into to the various file sections.
void InitMembers();
- // Builds the index of descriptors to class definitions.
- void InitIndex();
-
// Returns true if the header magic and version numbers are of the expected values.
bool CheckMagicAndVersion() const;
@@ -877,10 +869,6 @@
DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
void* context, const byte* stream, LocalInfo* local_in_reg) const;
- // The index of descriptors to class definition indexes (as opposed to type id indexes)
- typedef SafeMap<const StringPiece, uint32_t> Index;
- Index index_;
-
// The base address of the memory mapping.
const byte* const begin_;
@@ -898,10 +886,6 @@
// Manages the underlying memory allocation.
UniquePtr<MemMap> mem_map_;
- // A cached com.android.dex.Dex instance, possibly NULL. Use GetDexObject.
- // TODO: this is mutable as it shouldn't be here. We should move it to the dex cache or similar.
- mutable jobject dex_object_;
-
// The DEX-to-DEX compiler uses this lock to ensure thread safety when
// enabling write access to a read-only DEX file.
// TODO: move to Locks::dex_file_modification_lock.
diff --git a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
index 1d8022f..07c1c01 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -32,7 +32,7 @@
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* method;
- if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex16)) {
+ if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
if (UNLIKELY(method == NULL)) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 224b2ba..ccf3e59 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -178,7 +178,7 @@
}
inline bool ArtMethod::IsRuntimeMethod() const {
- return GetDexMethodIndex() == DexFile::kDexNoIndex16;
+ return GetDexMethodIndex() == DexFile::kDexNoIndex;
}
inline bool ArtMethod::IsCalleeSaveMethod() const {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 5e8b827..add7e1b 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -128,7 +128,10 @@
}
void Class::SetClassSize(size_t new_class_size) {
- DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+ if (kIsDebugBuild && (new_class_size < GetClassSize())) {
+ DumpClass(LOG(ERROR), kDumpClassFullDetail);
+ CHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+ }
SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
}
@@ -300,22 +303,8 @@
return true;
}
// Compare the package part of the descriptor string.
- if (LIKELY(!klass1->IsProxyClass() && !klass2->IsProxyClass())) {
- ClassHelper kh(klass1);
- const DexFile* dex_file1 = &kh.GetDexFile();
- const DexFile::TypeId* type_id1 = &dex_file1->GetTypeId(klass1->GetDexTypeIndex());
- const char* descriptor1 = dex_file1->GetTypeDescriptor(*type_id1);
- kh.ChangeClass(klass2);
- const DexFile* dex_file2 = &kh.GetDexFile();
- const DexFile::TypeId* type_id2 = &dex_file2->GetTypeId(klass2->GetDexTypeIndex());
- const char* descriptor2 = dex_file2->GetTypeDescriptor(*type_id2);
- return IsInSamePackage(descriptor1, descriptor2);
- }
- ClassHelper kh(klass1);
- std::string descriptor1(kh.GetDescriptor());
- kh.ChangeClass(klass2);
- std::string descriptor2(kh.GetDescriptor());
- return IsInSamePackage(descriptor1, descriptor2);
+ return IsInSamePackage(ClassHelper(klass1).GetDescriptor(),
+ ClassHelper(klass2).GetDescriptor());
}
bool Class::IsClassClass() const {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 99f3850..d97b603 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -726,6 +726,14 @@
return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), false);
}
+ uint16_t GetDexClassDefIndex() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), false);
+ }
+
+ void SetDexClassDefIndex(uint16_t class_def_idx) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_class_def_idx_), class_def_idx, false);
+ }
+
uint16_t GetDexTypeIndex() const {
return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), false);
}
@@ -807,7 +815,7 @@
// If class verify fails, we must return same error on subsequent tries.
Class* verify_error_class_;
- // virtual methods defined in this class; invoked through vtable
+ // Virtual methods defined in this class; invoked through vtable.
ObjectArray<ArtMethod>* virtual_methods_;
// Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
@@ -816,24 +824,28 @@
// virtual_ methods_ for miranda methods.
ObjectArray<ArtMethod>* vtable_;
- // access flags; low 16 bits are defined by VM spec
+ // Access flags; low 16 bits are defined by VM spec.
uint32_t access_flags_;
// Total size of the Class instance; used when allocating storage on gc heap.
// See also object_size_.
size_t class_size_;
- // tid used to check for recursive <clinit> invocation
+ // Tid used to check for recursive <clinit> invocation.
pid_t clinit_thread_id_;
- // type index from dex file
+ // ClassDef index in dex file, -1 if no class definition such as an array.
// TODO: really 16bits
- uint32_t dex_type_idx_;
+ int32_t dex_class_def_idx_;
- // number of instance fields that are object refs
+ // Type index in dex file.
+ // TODO: really 16bits
+ int32_t dex_type_idx_;
+
+ // Number of instance fields that are object refs.
size_t num_reference_instance_fields_;
- // number of static fields that are object refs
+ // Number of static fields that are object refs,
size_t num_reference_static_fields_;
// Total object size; used when allocating storage on gc heap.
@@ -841,7 +853,7 @@
// See also class_size_.
size_t object_size_;
- // primitive type value, or Primitive::kPrimNot (0); set for generated prim classes
+ // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes.
Primitive::Type primitive_type_;
// Bitmap of offsets of ifields.
@@ -850,7 +862,7 @@
// Bitmap of offsets of sfields.
uint32_t reference_static_offsets_;
- // state of class initialization
+ // State of class initialization.
Status status_;
// TODO: ?
@@ -873,7 +885,6 @@
class MANAGED ClassClass : public Class {
private:
- int32_t padding_;
int64_t serialVersionUID_;
friend struct art::ClassClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 6cfab9e..0522f13 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -164,6 +164,7 @@
}
private:
+ Object* dex_;
ObjectArray<StaticStorageBase>* initialized_static_storage_;
String* location_;
ObjectArray<ArtField>* resolved_fields_;
diff --git a/runtime/mirror/proxy.h b/runtime/mirror/proxy.h
index 7c5bc39..18a84dc 100644
--- a/runtime/mirror/proxy.h
+++ b/runtime/mirror/proxy.h
@@ -25,6 +25,8 @@
namespace mirror {
+// All proxy objects have a class which is a synthesized proxy class. The synthesized proxy class
+// has the static fields used to implement reflection on proxy objects.
class MANAGED SynthesizedProxyClass : public Class {
public:
ObjectArray<Class>* GetInterfaces() {
@@ -41,6 +43,7 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(SynthesizedProxyClass);
};
+// C++ mirror of java.lang.reflect.Proxy.
class MANAGED Proxy : public Object {
private:
Object* h_;
diff --git a/runtime/mirror/string.h b/runtime/mirror/string.h
index bf545ea..81fe42f 100644
--- a/runtime/mirror/string.h
+++ b/runtime/mirror/string.h
@@ -155,8 +155,8 @@
private:
CharArray* ASCII_;
Object* CASE_INSENSITIVE_ORDER_;
- uint32_t REPLACEMENT_CHAR_;
int64_t serialVersionUID_;
+ uint32_t REPLACEMENT_CHAR_;
friend struct art::StringClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
};
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 2f4e427..d2a6c0e 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -150,7 +150,7 @@
return NULL;
}
const std::string descriptor(DotToDescriptor(class_name.c_str()));
- const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor);
+ const DexFile::ClassDef* dex_class_def = dex_file->FindClassDef(descriptor.c_str());
if (dex_class_def == NULL) {
VLOG(class_linker) << "Failed to find dex_class_def";
return NULL;
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index a729699..d3011cb 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -78,35 +78,6 @@
return soa.AddLocalReference<jclass>(c);
}
-static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
- ScopedObjectAccess soa(env);
- mirror::Class* c = DecodeClass(soa, javaClass);
- if (c->IsPrimitive() || c->IsArrayClass() || c->IsProxyClass()) {
- return 0; // primitive, array and proxy classes don't have class definitions
- }
- const DexFile::ClassDef* class_def = ClassHelper(c).GetClassDef();
- if (class_def == NULL) {
- return 0; // not found
- } else {
- return class_def->annotations_off_;
- }
-}
-
-static jobject Class_getDex(JNIEnv* env, jobject javaClass) {
- ScopedObjectAccess soa(env);
- mirror::Class* c = DecodeClass(soa, javaClass);
-
- mirror::DexCache* dex_cache = c->GetDexCache();
- if (dex_cache == NULL) {
- return NULL;
- }
- const DexFile* dex_file = dex_cache->GetDexFile();
- if (dex_file == NULL) {
- return NULL;
- }
- return dex_file->GetDexObject(env);
-}
-
static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
mirror::Class* c = DecodeClass(soa, javaThis);
@@ -122,8 +93,6 @@
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Class, classForName, "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
- NATIVE_METHOD(Class, getAnnotationDirectoryOffset, "()I"),
- NATIVE_METHOD(Class, getDex, "()Lcom/android/dex/Dex;"),
NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
NATIVE_METHOD(Class, getProxyInterfaces, "()[Ljava/lang/Class;"),
};
diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc
new file mode 100644
index 0000000..f8eeb29
--- /dev/null
+++ b/runtime/native/java_lang_DexCache.cc
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#include "dex_file.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object-inl.h"
+#include "scoped_thread_state_change.h"
+#include "well_known_classes.h"
+
+namespace art {
+
+static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) {
+ ScopedObjectAccess soa(env);
+ mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache);
+ // Should only be called while holding the lock on the dex cache.
+ DCHECK_EQ(dex_cache->GetThinLockId(), soa.Self()->GetThinLockId());
+ const DexFile* dex_file = dex_cache->GetDexFile();
+ if (dex_file == NULL) {
+ return NULL;
+ }
+ void* address = const_cast<void*>(reinterpret_cast<const void*>(dex_file->Begin()));
+ jobject byte_buffer = env->NewDirectByteBuffer(address, dex_file->Size());
+ if (byte_buffer == NULL) {
+ DCHECK(soa.Self()->IsExceptionPending());
+ return NULL;
+ }
+
+ jvalue args[1];
+ args[0].l = byte_buffer;
+ return env->CallStaticObjectMethodA(WellKnownClasses::com_android_dex_Dex,
+ WellKnownClasses::com_android_dex_Dex_create,
+ args);
+}
+
+static JNINativeMethod gMethods[] = {
+ NATIVE_METHOD(DexCache, getDexNative, "()Lcom/android/dex/Dex;"),
+};
+
+void register_java_lang_DexCache(JNIEnv* env) {
+ REGISTER_NATIVE_METHODS("java/lang/DexCache");
+}
+
+} // namespace art
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index afa823d..4c97017 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -365,7 +365,7 @@
dex_file_location_checksum_);
}
-const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint32_t class_def_index) const {
+const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 325ebb2..bbd2615 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -183,7 +183,7 @@
}
// Returns the OatClass for the class specified by the given DexFile class_def_index.
- const OatClass* GetOatClass(uint32_t class_def_index) const;
+ const OatClass* GetOatClass(uint16_t class_def_index) const;
~OatDexFile();
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 2910243..6ee3016 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -68,8 +68,7 @@
public:
ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : class_def_(NULL),
- class_linker_(l),
+ : class_linker_(l),
dex_cache_(NULL),
dex_file_(NULL),
interface_type_list_(NULL),
@@ -92,7 +91,6 @@
}
klass_ = new_c;
interface_type_list_ = NULL;
- class_def_ = NULL;
}
// The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
@@ -108,7 +106,7 @@
return descriptor_.c_str();
} else {
const DexFile& dex_file = GetDexFile();
- const DexFile::TypeId& type_id = dex_file.GetTypeId(klass_->GetDexTypeIndex());
+ const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
return dex_file.GetTypeDescriptor(type_id);
}
}
@@ -124,14 +122,13 @@
return descriptor_.c_str();
}
- const DexFile::ClassDef* GetClassDef()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::ClassDef* result = class_def_;
- if (result == NULL) {
- result = GetDexFile().FindClassDef(GetDescriptor());
- class_def_ = result;
+ const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(klass_ != nullptr);
+ uint16_t class_def_idx = klass_->GetDexClassDefIndex();
+ if (class_def_idx == DexFile::kDexNoIndex16) {
+ return nullptr;
}
- return result;
+ return &GetDexFile().GetClassDef(class_def_idx);
}
uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -187,7 +184,7 @@
const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string descriptor(GetDescriptor());
const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
+ const DexFile::ClassDef* dex_class_def = GetClassDef();
CHECK(dex_class_def != NULL);
return dex_file.GetSourceFile(*dex_class_def);
}
@@ -242,7 +239,6 @@
return result;
}
- const DexFile::ClassDef* class_def_;
ClassLinker* class_linker_;
mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
@@ -327,12 +323,15 @@
// If you need it longer, copy it into a std::string.
const char* GetDeclaringClassDescriptor()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint16_t type_idx = field_->GetDeclaringClass()->GetDexTypeIndex();
- if (type_idx != DexFile::kDexNoIndex16) {
+ uint32_t field_index = field_->GetDexFieldIndex();
+ if (!field_->GetDeclaringClass()->IsProxyClass()) {
const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+ return dex_file.GetFieldDeclaringClassDescriptor(field_id);
} else {
- // Most likely a proxy class.
+ DCHECK(field_->IsStatic());
+ DCHECK_LT(field_index, 2U);
+ // 0 == Class[] interfaces; 1 == Class[][] throws;
ClassHelper kh(field_->GetDeclaringClass());
declaring_class_descriptor_ = kh.GetDescriptor();
return declaring_class_descriptor_.c_str();
@@ -418,7 +417,7 @@
const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex16) {
+ if (dex_method_idx != DexFile::kDexNoIndex) {
return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
} else {
Runtime* runtime = Runtime::Current();
@@ -464,21 +463,19 @@
const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
- if (dex_method_idx != DexFile::kDexNoIndex16) {
+ if (dex_method_idx != DexFile::kDexNoIndex) {
return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
} else {
return "<no signature>";
}
}
- const DexFile::ProtoId& GetPrototype()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
}
- const DexFile::TypeList* GetParameterTypeList()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile::ProtoId& proto = GetPrototype();
return GetDexFile().GetProtoParameters(proto);
}
@@ -491,8 +488,7 @@
return GetClassFromTypeIdx(return_type_idx);
}
- const char* GetReturnTypeDescriptor()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
@@ -500,8 +496,7 @@
return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
}
- int32_t GetLineNumFromDexPC(uint32_t dex_pc)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (dex_pc == DexFile::kDexNoIndex) {
return method_->IsNative() ? -2 : -1;
} else {
@@ -510,35 +505,29 @@
}
}
- const char* GetDeclaringClassDescriptor()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Class* klass = method_->GetDeclaringClass();
- DCHECK(!klass->IsProxyClass());
- uint16_t type_idx = klass->GetDexTypeIndex();
+ const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
- return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
+ uint32_t dex_method_idx = method_->GetDexMethodIndex();
+ if (dex_method_idx != DexFile::kDexNoIndex) {
+ return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
+ } else {
+ return "<runtime method>";
+ }
}
- const char* GetDeclaringClassSourceFile()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const char* descriptor = GetDeclaringClassDescriptor();
- const DexFile& dex_file = GetDexFile();
- const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
- CHECK(dex_class_def != NULL);
- return dex_file.GetSourceFile(*dex_class_def);
+ const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
}
- uint32_t GetClassDefIndex()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const char* descriptor = GetDeclaringClassDescriptor();
- const DexFile& dex_file = GetDexFile();
- uint32_t index;
- CHECK(dex_file.FindClassDefIndex(descriptor, index));
- return index;
+ uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return method_->GetDeclaringClass()->GetDexClassDefIndex();
}
- mirror::ClassLoader* GetClassLoader()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetDexFile().GetClassDef(GetClassDefIndex());
+ }
+
+ mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return method_->GetDeclaringClass()->GetClassLoader();
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 657735a..09d1447 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1001,6 +1001,7 @@
REGISTER(register_dalvik_system_VMStack);
REGISTER(register_dalvik_system_Zygote);
REGISTER(register_java_lang_Class);
+ REGISTER(register_java_lang_DexCache);
REGISTER(register_java_lang_Object);
REGISTER(register_java_lang_Runtime);
REGISTER(register_java_lang_String);
@@ -1164,7 +1165,7 @@
method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for resolution method saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+ method->SetDexMethodIndex(DexFile::kDexNoIndex);
// When compiling, the code pointer will get set later when the image is loaded.
Runtime* r = Runtime::Current();
ClassLinker* cl = r->GetClassLinker();
@@ -1180,7 +1181,7 @@
method(self, down_cast<mirror::ArtMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for callee saves
- method->SetDexMethodIndex(DexFile::kDexNoIndex16);
+ method->SetDexMethodIndex(DexFile::kDexNoIndex);
method->SetEntryPointFromCompiledCode(NULL);
if ((instruction_set == kThumb2) || (instruction_set == kArm)) {
uint32_t ref_spills = (1 << art::arm::R5) | (1 << art::arm::R6) | (1 << art::arm::R7) |
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 558ceb4..23cafe8 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1807,7 +1807,7 @@
uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, m, new_dex_pc);
verifier::MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), code_item,
+ &mh.GetClassDef(), code_item,
m->GetDexMethodIndex(), m, m->GetAccessFlags(), false, true);
verifier.Verify();
std::vector<int32_t> kinds = verifier.DescribeVRegs(dex_pc);
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index fa00c61..9811926 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -74,50 +74,51 @@
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* klass,
- std::string& error,
- bool allow_soft_failures) {
+ bool allow_soft_failures,
+ std::string* error) {
if (klass->IsVerified()) {
return kNoFailure;
}
mirror::Class* super = klass->GetSuperClass();
if (super == NULL && StringPiece(ClassHelper(klass).GetDescriptor()) != "Ljava/lang/Object;") {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that has no super class";
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that has no super class";
return kHardFailure;
}
if (super != NULL && super->IsFinal()) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that attempts to sub-class final class ";
- error += PrettyDescriptor(super);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that attempts to sub-class final class ";
+ *error += PrettyDescriptor(super);
return kHardFailure;
}
ClassHelper kh(klass);
const DexFile& dex_file = kh.GetDexFile();
- uint32_t class_def_idx;
- if (!dex_file.FindClassDefIndex(kh.GetDescriptor(), class_def_idx)) {
- error = "Verifier rejected class ";
- error += PrettyDescriptor(klass);
- error += " that isn't present in dex file ";
- error += dex_file.GetLocation();
+ const DexFile::ClassDef* class_def = kh.GetClassDef();
+ if (class_def == NULL) {
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(klass);
+ *error += " that isn't present in dex file ";
+ *error += dex_file.GetLocation();
return kHardFailure;
}
return VerifyClass(&dex_file,
kh.GetDexCache(),
klass->GetClassLoader(),
- class_def_idx, error,
- allow_soft_failures);
+ class_def,
+ allow_soft_failures,
+ error);
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
- std::string& error,
- bool allow_soft_failures) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
- const byte* class_data = dex_file->GetClassData(class_def);
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures,
+ std::string* error) {
+ DCHECK(class_def != nullptr);
+ const byte* class_data = dex_file->GetClassData(*class_def);
if (class_data == NULL) {
// empty class, probably a marker interface
return kNoFailure;
@@ -139,7 +140,7 @@
continue;
}
previous_direct_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -151,7 +152,7 @@
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -160,12 +161,12 @@
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -181,7 +182,7 @@
continue;
}
previous_virtual_method_idx = method_idx;
- InvokeType type = it.GetMethodInvokeType(class_def);
+ InvokeType type = it.GetMethodInvokeType(*class_def);
mirror::ArtMethod* method =
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
@@ -193,7 +194,7 @@
dex_file,
dex_cache,
class_loader,
- class_def_idx,
+ class_def,
it.GetMethodCodeItem(),
method,
it.GetMemberAccessFlags(),
@@ -202,12 +203,12 @@
if (result == kHardFailure) {
hard_fail = true;
if (error_count > 0) {
- error += "\n";
+ *error += "\n";
}
- error = "Verifier rejected class ";
- error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
- error += " due to bad method ";
- error += PrettyMethod(method_idx, *dex_file);
+ *error = "Verifier rejected class ";
+ *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
+ *error += " due to bad method ";
+ *error += PrettyMethod(method_idx, *dex_file);
}
++error_count;
}
@@ -224,7 +225,7 @@
const DexFile* dex_file,
mirror::DexCache* dex_cache,
mirror::ClassLoader* class_loader,
- uint32_t class_def_idx,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags,
@@ -232,7 +233,7 @@
MethodVerifier::FailureKind result = kNoFailure;
uint64_t start_ns = NanoTime();
- MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def_idx, code_item, method_idx,
+ MethodVerifier verifier_(dex_file, dex_cache, class_loader, class_def, code_item, method_idx,
method, method_access_flags, true, allow_soft_failures);
if (verifier_.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
@@ -267,11 +268,12 @@
void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method,
uint32_t method_access_flags) {
- MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
+ MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def, code_item,
dex_method_idx, method, method_access_flags, true, true);
verifier.Verify();
verifier.DumpFailures(os);
@@ -280,7 +282,8 @@
}
MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t dex_method_idx, mirror::ArtMethod* method,
uint32_t method_access_flags, bool can_load_classes,
@@ -293,7 +296,7 @@
dex_file_(dex_file),
dex_cache_(dex_cache),
class_loader_(class_loader),
- class_def_idx_(class_def_idx),
+ class_def_(class_def),
code_item_(code_item),
declaring_class_(NULL),
interesting_dex_pc_(-1),
@@ -306,13 +309,14 @@
allow_soft_failures_(allow_soft_failures),
has_check_casts_(false),
has_virtual_or_interface_invokes_(false) {
+ DCHECK(class_def != NULL);
}
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>& monitor_enter_dex_pcs) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = &monitor_enter_dex_pcs;
@@ -334,7 +338,7 @@
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -362,7 +366,7 @@
uint32_t dex_pc) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
- mh.GetClassDefIndex(), mh.GetCodeItem(), m->GetDexMethodIndex(),
+ &mh.GetClassDef(), mh.GetCodeItem(), m->GetDexMethodIndex(),
m, m->GetAccessFlags(), false, true);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -448,7 +452,7 @@
// marked as rejected to prevent it from being compiled.
case VERIFY_ERROR_BAD_CLASS_HARD: {
if (Runtime::Current()->IsCompiler()) {
- ClassReference ref(dex_file_, class_def_idx_);
+ ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
AddRejectedClass(ref);
}
have_pending_hard_failure_ = true;
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 70442fb..073a2f7 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -145,17 +145,19 @@
};
/* Verify a class. Returns "kNoFailure" on success. */
- static FailureKind VerifyClass(const mirror::Class* klass, std::string& error,
- bool allow_soft_failures)
+ static FailureKind VerifyClass(const mirror::Class* klass, bool allow_soft_failures,
+ std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
- std::string& error, bool allow_soft_failures)
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def,
+ bool allow_soft_failures, std::string* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader,
- uint32_t class_def_idx, const DexFile::CodeItem* code_item,
+ const DexFile::ClassDef* class_def,
+ const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -222,7 +224,7 @@
}
MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader, const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
uint32_t method_idx, mirror::ArtMethod* method,
uint32_t access_flags, bool can_load_classes, bool allow_soft_failures)
@@ -262,7 +264,8 @@
*/
static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ mirror::ClassLoader* class_loader,
+ const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
mirror::ArtMethod* method, uint32_t method_access_flags,
bool allow_soft_failures)
@@ -690,7 +693,7 @@
mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
// The class loader for the declaring class of the method.
mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
- const uint32_t class_def_idx_; // The class def index of the declaring class of the method.
+ const DexFile::ClassDef* const class_def_; // The class def of the declaring class of the method.
const DexFile::CodeItem* const code_item_; // The code item containing the code for the method.
const RegType* declaring_class_; // Lazily computed reg type of the method's declaring class.
// Instruction widths and flags, one entry per code unit.
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 611b7c0..a56abba 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -34,7 +34,8 @@
// Verify the class
std::string error_msg;
- ASSERT_TRUE(MethodVerifier::VerifyClass(klass, error_msg, true) == MethodVerifier::kNoFailure) << error_msg;
+ ASSERT_TRUE(MethodVerifier::VerifyClass(klass, true, &error_msg) == MethodVerifier::kNoFailure)
+ << error_msg;
}
void VerifyDexFile(const DexFile* dex)