Finish moving state to managed heap
Change-Id: I8a3b0e353b30268a05d6ed8ea0a6a4bead100660
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c81df8d..8595bfc 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -151,7 +151,7 @@
// Create array interface entries to populate once we can load system classes
array_interfaces_ = AllocObjectArray<Class>(2);
- array_iftable_ = new InterfaceEntry[2];
+ array_iftable_ = AllocObjectArray<InterfaceEntry>(2);
// Create int array type for AllocDexCache (done in AppendToBootClassPath)
Class* int_array_class = AllocClass(java_lang_Class, sizeof(Class));
@@ -195,8 +195,7 @@
// now we can use FindSystemClass
- // Object and String just need more minimal setup, since they do not have
- // extra C++ fields.
+ // Object and String need to be rerun through FindSystemClass to finish init
java_lang_Object->SetStatus(Class::kStatusNotReady);
Class* Object_class = FindSystemClass("Ljava/lang/Object;");
CHECK_EQ(java_lang_Object, Object_class);
@@ -206,8 +205,7 @@
CHECK_EQ(java_lang_String, String_class);
CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(String));
- // Setup the primitive array type classes - can't be done until Object has
- // a vtable
+ // Setup the primitive array type classes - can't be done until Object has a vtable
SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
@@ -245,10 +243,9 @@
array_interfaces_->Set(1, java_io_Serializable);
// We assume that Cloneable/Serializable don't have superinterfaces --
// normally we'd have to crawl up and explicitly list all of the
- // supers as well. These interfaces don't have any methods, so we
- // don't have to worry about the ifviPool either.
- array_iftable_[0].SetInterface(array_interfaces_->Get(0));
- array_iftable_[1].SetInterface(array_interfaces_->Get(1));
+ // supers as well.
+ array_iftable_->Set(0, AllocInterfaceEntry(array_interfaces_->Get(0)));
+ array_iftable_->Set(1, AllocInterfaceEntry(array_interfaces_->Get(1)));
// Sanity check Object[]'s interfaces
CHECK_EQ(java_lang_Cloneable, object_array_class->GetInterface(0));
@@ -549,6 +546,14 @@
return down_cast<CodeAndDirectMethods*>(IntArray::Alloc(CodeAndDirectMethods::LengthAsArray(length)));
}
+InterfaceEntry* ClassLinker::AllocInterfaceEntry(Class* interface) {
+ DCHECK(interface->IsInterface());
+ ObjectArray<Object>* array = AllocObjectArray<Object>(InterfaceEntry::LengthAsArray());
+ InterfaceEntry* interface_entry = down_cast<InterfaceEntry*>(array);
+ interface_entry->SetInterface(interface);
+ return interface_entry;
+}
+
Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
DCHECK_GE(class_size, sizeof(Class));
Class* klass = Heap::AllocObject(java_lang_Class, class_size)->AsClass();
@@ -774,7 +779,7 @@
size_t num_direct_methods = header.direct_methods_size_;
size_t num_virtual_methods = header.virtual_methods_size_;
- klass->SetSourceFile(dex_file.dexGetSourceFile(dex_class_def));
+ klass->SetSourceFile(String::AllocFromModifiedUtf8(dex_file.dexGetSourceFile(dex_class_def)));
// Load class interfaces.
LoadInterfaces(dex_file, dex_class_def, klass);
@@ -1099,8 +1104,7 @@
// Use the single, global copies of "interfaces" and "iftable"
// (remember not to free them for arrays).
new_class->SetInterfaces(array_interfaces_);
- new_class->SetIFTableCount(2);
- new_class->SetIFTable(array_iftable_);
+ new_class->SetIfTable(array_iftable_);
// Inherit access flags from the component type. Arrays can't be
// used as a superclass or interface, so we want to add "final"
@@ -1303,13 +1307,12 @@
}
}
}
- for (size_t i = 0; i < klass->GetIFTableCount(); ++i) {
- const InterfaceEntry* iftable = &klass->GetIFTable()[i];
- Class* interface = iftable->GetInterface();
+ for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
+ InterfaceEntry* interface_entry = klass->GetIfTable()->Get(i);
+ Class* interface = interface_entry->GetInterface();
if (klass->GetClassLoader() != interface->GetClassLoader()) {
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- uint32_t vtable_index = iftable->GetMethodIndexArray()[j];
- const Method* method = klass->GetVirtualMethod(vtable_index);
+ const Method* method = interface_entry->GetMethodArray()->Get(j);
if (!HasSameMethodDescriptorClasses(method, interface,
method->GetClass())) {
LG << "Classes resolve differently in interface"; // TODO: LinkageError
@@ -1684,71 +1687,61 @@
}
bool ClassLinker::LinkInterfaceMethods(Class* klass) {
- int pool_offset = 0;
- int pool_size = 0;
int miranda_count = 0;
int miranda_alloc = 0;
size_t super_ifcount;
if (klass->HasSuperClass()) {
- super_ifcount = klass->GetSuperClass()->GetIFTableCount();
+ super_ifcount = klass->GetSuperClass()->GetIfTableCount();
} else {
super_ifcount = 0;
}
size_t ifcount = super_ifcount;
ifcount += klass->NumInterfaces();
for (size_t i = 0; i < klass->NumInterfaces(); i++) {
- ifcount += klass->GetInterface(i)->GetIFTableCount();
+ ifcount += klass->GetInterface(i)->GetIfTableCount();
}
if (ifcount == 0) {
// TODO: enable these asserts with klass status validation
- // DCHECK(klass->GetIFTableCount() == 0);
- // DCHECK(klass->GetIFTable() == NULL);
+ // DCHECK(klass->GetIfTableCount() == 0);
+ // DCHECK(klass->GetIfTable() == NULL);
return true;
}
- InterfaceEntry* iftable = new InterfaceEntry[ifcount];
- memset(iftable, 0x00, sizeof(InterfaceEntry) * ifcount);
+ ObjectArray<InterfaceEntry>* iftable = AllocObjectArray<InterfaceEntry>(ifcount);
if (super_ifcount != 0) {
- memcpy(iftable, klass->GetSuperClass()->GetIFTable(),
- sizeof(InterfaceEntry) * super_ifcount);
+ ObjectArray<InterfaceEntry>* super_iftable = klass->GetSuperClass()->GetIfTable();
+ for (size_t i = 0; i < super_ifcount; i++) {
+ iftable->Set(i, AllocInterfaceEntry(super_iftable->Get(i)->GetInterface()));
+ }
}
// Flatten the interface inheritance hierarchy.
size_t idx = super_ifcount;
for (size_t i = 0; i < klass->NumInterfaces(); i++) {
- Class* interf = klass->GetInterface(i);
- DCHECK(interf != NULL);
- if (!interf->IsInterface()) {
+ Class* interface = klass->GetInterface(i);
+ DCHECK(interface != NULL);
+ if (!interface->IsInterface()) {
LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
return false;
}
- iftable[idx++].SetInterface(interf);
- for (size_t j = 0; j < interf->GetIFTableCount(); j++) {
- iftable[idx++].SetInterface(interf->GetIFTable()[j].GetInterface());
+ iftable->Set(idx++, AllocInterfaceEntry(interface));
+ for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
+ iftable->Set(idx++, AllocInterfaceEntry(interface->GetIfTable()->Get(j)->GetInterface()));
}
}
- klass->SetIFTable(iftable);
+ klass->SetIfTable(iftable);
CHECK_EQ(idx, ifcount);
- klass->SetIFTableCount(ifcount);
if (klass->IsInterface() || super_ifcount == ifcount) {
return true;
}
- for (size_t i = super_ifcount; i < ifcount; i++) {
- pool_size += iftable[i].GetInterface()->NumVirtualMethods();
- }
- if (pool_size == 0) {
- return true;
- }
- klass->SetIfviPoolCount(pool_size);
- uint32_t* ifvi_pool = new uint32_t[pool_size];
- klass->SetIfviPool(ifvi_pool);
std::vector<Method*> miranda_list;
- for (size_t i = super_ifcount; i < ifcount; ++i) {
- iftable[i].SetMethodIndexArray(ifvi_pool + pool_offset);
- Class* interface = iftable[i].GetInterface();
- pool_offset += interface->NumVirtualMethods(); // end here
+ for (size_t i = 0; i < ifcount; ++i) {
+ InterfaceEntry* interface_entry = iftable->Get(i);
+ Class* interface = interface_entry->GetInterface();
+ ObjectArray<Method>* method_array = AllocObjectArray<Method>(interface->NumVirtualMethods());
+ interface_entry->SetMethodArray(method_array);
ObjectArray<Method>* vtable = klass->GetVTableDuringLinking();
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
Method* interface_method = interface->GetVirtualMethod(j);
- int k; // must be signed
+ int32_t k;
for (k = vtable->GetLength() - 1; k >= 0; --k) {
Method* vtable_method = vtable->Get(k);
if (interface_method->HasSameNameAndDescriptor(vtable_method)) {
@@ -1756,7 +1749,7 @@
LG << "Implementation not public";
return false;
}
- iftable[i].GetMethodIndexArray()[j] = k;
+ method_array->Set(j, vtable_method);
break;
}
}
@@ -1769,16 +1762,16 @@
miranda_list.resize(miranda_alloc);
}
}
+ Method* miranda_method = NULL;
int mir;
for (mir = 0; mir < miranda_count; mir++) {
- Method* miranda_method = miranda_list[mir];
+ miranda_method = miranda_list[mir];
if (miranda_method->HasSameNameAndDescriptor(interface_method)) {
break;
}
}
- // point the interface table at a phantom slot index
- iftable[i].GetMethodIndexArray()[j] =
- vtable->GetLength() + mir;
+ // point the interface table at a phantom slot
+ method_array->Set(j, miranda_method);
if (mir == miranda_count) {
miranda_list[miranda_count++] = interface_method;
}
diff --git a/src/class_linker.h b/src/class_linker.h
index fe375c2..e9606a7 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -175,6 +175,7 @@
Field* AllocField();
Method* AllocMethod();
CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
+ InterfaceEntry* AllocInterfaceEntry(Class* interface);
Class* CreatePrimitiveClass(const char* descriptor,
Class::PrimitiveType type);
@@ -331,7 +332,7 @@
}
ObjectArray<Class>* array_interfaces_;
- InterfaceEntry* array_iftable_;
+ ObjectArray<InterfaceEntry>* array_iftable_;
bool init_done_;
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index c3bb4c3..eab184e 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -390,16 +390,26 @@
bool error = false;
- if (!klass->IsClassClass() && instance)
- if (size != (instance ? klass->GetObjectSize() : klass->GetClassSize())) {
+ if (!klass->IsClassClass() && instance) {
+ size_t expected_size = instance ? klass->GetObjectSize() : klass->GetClassSize();
+ if (size != expected_size) {
LG << "Class size mismatch:"
<< " class=" << class_descriptor
<< " Java=" << klass->GetObjectSize()
- << " C++=" << (instance ? klass->GetObjectSize() : klass->GetClassSize());
+ << " C++=" << expected_size;
+ error = true;
+ }
+ }
+
+ size_t num_fields = instance ? klass->NumInstanceFields() : klass->NumStaticFields();
+ if (offsets.size() != num_fields) {
+ LG << "Field count mismatch:"
+ << " class=" << class_descriptor
+ << " Java=" << num_fields
+ << " C++=" << offsets.size();
error = true;
}
- CHECK_EQ(offsets.size(), instance ? klass->NumInstanceFields() : klass->NumStaticFields());
for (size_t i = 0; i < offsets.size(); i++) {
Field* field = instance ? klass->GetInstanceField(i) : klass->GetStaticField(i);
if (!field->GetName()->Equals(offsets[i].java_name)) {
@@ -550,9 +560,11 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, dex_cache_), "shadow$_dex_cache_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, direct_methods_), "shadow$_direct_methods_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifields_), "shadow$_ifields_"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_), "shadow$_iftable_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_), "shadow$_interfaces_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, interfaces_type_idx_), "shadow$_interfaces_type_idx_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, sfields_), "shadow$_sfields_"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_), "shadow$_source_file_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_), "shadow$_super_class_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, verify_error_class_), "shadow$_verify_error_class_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, virtual_methods_), "shadow$_virtual_methods_"));
@@ -563,17 +575,12 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, array_rank_), "shadow$_array_rank_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, class_size_), "shadow$_class_size_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, clinit_thread_id_), "shadow$_clinit_thread_id_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_), "shadow$_iftable_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, iftable_count_), "shadow$_iftable_count_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_), "shadow$_ifvi_pool_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, ifvi_pool_count_), "shadow$_ifvi_pool_count_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_instance_fields_), "shadow$_num_reference_instance_fields_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, num_reference_static_fields_), "shadow$_num_reference_static_fields_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, object_size_), "shadow$_object_size_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, primitive_type_), "shadow$_primitive_type_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_instance_offsets_), "shadow$_reference_instance_offsets_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, reference_static_offsets_), "shadow$_reference_static_offsets_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, source_file_), "shadow$_source_file_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, status_), "shadow$_status_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Class, super_class_type_idx_), "shadow$_super_class_type_idx_"));
};
@@ -662,9 +669,6 @@
size = sizeof(ClassClass);
class_descriptor = "Ljava/lang/Class;";
- // padding 32-bit
- // this space intentionally left blank
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(ClassClass, serialVersionUID_), "serialVersionUID"));
};
@@ -680,11 +684,11 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, ASCII_), "ASCII"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, CASE_INSENSITIVE_ORDER_), "CASE_INSENSITIVE_ORDER"));
- // padding 32-bit
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
-
// alphabetical 64-bit
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, serialVersionUID_), "serialVersionUID"));
+
+ // alphabetical 32-bit
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(StringClass, REPLACEMENT_CHAR_), "REPLACEMENT_CHAR"));
};
};
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 22dae24..0ac2ee1 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -182,9 +182,9 @@
return static_cast<ObjectArray<StaticStorageBase>*>(GetNonNull(kInitializedStaticStorage));
}
- static size_t LengthAsArray() {
- return kMax;
- }
+ static size_t LengthAsArray() {
+ return kMax;
+ }
private:
diff --git a/src/object.cc b/src/object.cc
index 2c66690..3696374 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -497,9 +497,8 @@
bool have_executable_code = (GetCode() != NULL);
#if !defined(__arm__)
- // Currently we can only compile for ARM, so we can't execute
- // code on other architectures even if we do have it.
- have_executable_code = false;
+ // Currently we can only compile non-native methods for ARM.
+ have_executable_code = IsNative();
#endif
if (have_executable_code && stub != NULL) {
@@ -620,8 +619,10 @@
// All interfaces implemented directly and by our superclass, and
// recursively all super-interfaces of those interfaces, are listed
// in iftable_, so we can just do a linear scan through that.
- for (size_t i = 0; i < iftable_count_; i++) {
- if (iftable_[i].GetInterface() == klass) {
+ int32_t iftable_count = GetIfTableCount();
+ ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ if (iftable->Get(i)->GetInterface() == klass) {
return true;
}
}
@@ -783,11 +784,12 @@
Class* declaring_class = method->GetDeclaringClass();
DCHECK(declaring_class->IsInterface());
// TODO cache to improve lookup speed
- for (size_t i = 0; i < iftable_count_; i++) {
- InterfaceEntry& interface_entry = iftable_[i];
- if (interface_entry.GetInterface() == declaring_class) {
- return GetVTable()->Get(
- interface_entry.GetMethodIndexArray()[method->GetMethodIndex()]);
+ int32_t iftable_count = GetIfTableCount();
+ ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ InterfaceEntry* interface_entry = iftable->Get(i);
+ if (interface_entry->GetInterface() == declaring_class) {
+ return interface_entry->GetMethodArray()->Get(method->GetMethodIndex());
}
}
UNIMPLEMENTED(FATAL) << "Need to throw an error of some kind";
@@ -802,9 +804,10 @@
return method;
}
- InterfaceEntry* iftable = GetIFTable();
- for (size_t i = 0; i < GetIFTableCount(); i++) {
- method = iftable[i].GetInterface()->FindVirtualMethod(name, signature);
+ int32_t iftable_count = GetIfTableCount();
+ ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ method = iftable->Get(i)->GetInterface()->FindVirtualMethod(name, signature);
if (method != NULL) {
return method;
}
diff --git a/src/object.h b/src/object.h
index 8f51244..b7cbee5 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1072,7 +1072,7 @@
// in Class::vtable_.
//
// For abstract methods in an interface class, this is the offset
- // of the method in "iftable_[n]->method_index_array_".
+ // of the method in "iftable_->Get(n)->GetMethodArray()".
uint32_t method_index_; // (could be uint16_t)
// The target native method registered with this method
@@ -1761,49 +1761,23 @@
return GetInterfaces()->Get(i);
}
- size_t GetIFTableCount() const {
- DCHECK(IsResolved());
- DCHECK(sizeof(size_t) == sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, iftable_count_), false);
+ int32_t GetIfTableCount() const {
+ ObjectArray<InterfaceEntry>* iftable = GetIfTable();
+ if (iftable == NULL) {
+ return 0;
+ }
+ return iftable->GetLength();
}
- void SetIFTableCount(size_t new_iftable_count) {
- DCHECK(sizeof(size_t) == sizeof(int32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, iftable_count_),
- new_iftable_count, false);
- }
-
- InterfaceEntry* GetIFTable() const {
+ ObjectArray<InterfaceEntry>* GetIfTable() const {
DCHECK(IsResolved());
- return GetFieldPtr<InterfaceEntry*>(
+ return GetFieldObject<ObjectArray<InterfaceEntry>*>(
OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
}
- void SetIFTable(InterfaceEntry* new_iftable) {
- SetFieldPtr<InterfaceEntry*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_),
- new_iftable, false);
- }
-
- size_t GetIfviPoolCount() const {
- DCHECK(IsResolved());
- CHECK(sizeof(size_t) == sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_count_), false);
- }
-
- void SetIfviPoolCount(size_t new_count) {
- CHECK(sizeof(size_t) == sizeof(int32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_count_), new_count,
- false);
- }
-
- uint32_t* GetIfviPool() const {
- DCHECK(IsResolved());
- return GetFieldPtr<uint32_t*>(
- OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_), false);
- }
-
- void SetIfviPool(uint32_t* new_pool) {
- SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Class, ifvi_pool_), new_pool, false);
+ void SetIfTable(ObjectArray<InterfaceEntry>* new_iftable) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_),
+ new_iftable, false);
}
// Get instance fields
@@ -1955,14 +1929,14 @@
klass, false);
}
- const char* GetSourceFile() const {
+ String* GetSourceFile() const {
DCHECK(IsLoaded());
- return GetFieldPtr<const char*>(
+ return GetFieldPtr<String*>(
OFFSET_OF_OBJECT_MEMBER(Class, source_file_), false);
}
- void SetSourceFile(const char* new_source_file) {
- SetFieldPtr<const char*>(OFFSET_OF_OBJECT_MEMBER(Class, source_file_),
+ void SetSourceFile(String* new_source_file) {
+ SetFieldPtr<String*>(OFFSET_OF_OBJECT_MEMBER(Class, source_file_),
new_source_file, false);
}
@@ -1981,7 +1955,7 @@
// For array classes, the class object for base element, for
// instanceof/checkcast (for String[][][], this will be String).
// Otherwise, NULL.
- Class* component_type_; // TODO: make an instance field
+ Class* component_type_;
// descriptor for the class such as "Ljava/lang/Class;" or "[C"
String* descriptor_;
@@ -2005,6 +1979,21 @@
// specifies the number of reference fields.
ObjectArray<Field>* ifields_;
+ // Interface table (iftable_), one entry per interface supported by
+ // this class. That means one entry for each interface we support
+ // directly, indirectly via superclass, or indirectly via
+ // superinterface. This will be null if neither we nor our
+ // superclass implement any interfaces.
+ //
+ // Why we need this: given "class Foo implements Face", declare
+ // "Face faceObj = new Foo()". Invoke faceObj.blah(), where "blah"
+ // is part of the Face interface. We can't easily use a single
+ // vtable.
+ //
+ // For every interface a concrete class implements, we create an array
+ // of the concrete vtable_ methods for the methods in the interface.
+ ObjectArray<InterfaceEntry>* iftable_;
+
// array of interfaces this class implements directly
// see also interfaces_type_idx_
ObjectArray<Class>* interfaces_;
@@ -2016,6 +2005,9 @@
// Static fields
ObjectArray<Field>* sfields_;
+ // source file name, if known. Otherwise, NULL.
+ String* source_file_;
+
// The superclass, or NULL if this is java.lang.Object or a
// primitive type.
// see also super_class_type_idx_;
@@ -2046,40 +2038,6 @@
// threadId, used to check for recursive <clinit> invocation
pid_t clinit_thread_id_;
- // Interface table (iftable_), one entry per interface supported by
- // this class. That means one entry for each interface we support
- // directly, indirectly via superclass, or indirectly via
- // superinterface. This will be null if neither we nor our
- // superclass implement any interfaces.
- //
- // Why we need this: given "class Foo implements Face", declare
- // "Face faceObj = new Foo()". Invoke faceObj.blah(), where "blah"
- // is part of the Face interface. We can't easily use a single
- // vtable.
- //
- // For every interface a concrete class implements, we create a list
- // of virtualMethod indices for the methods in the interface.
- //
- // see also iftable_count_;
- // TODO convert to ObjectArray<?>
- //
- InterfaceEntry* iftable_;
-
- // size of iftable_
- size_t iftable_count_;
-
- // The interface vtable indices for iftable get stored here. By
- // placing them all in a single pool for each class that implements
- // interfaces, we decrease the number of allocations.
- //
- // see also ifvi_pool_count_
- //
- // TODO convert to IntArray
- uint32_t* ifvi_pool_;
-
- // size of ifvi_pool_
- size_t ifvi_pool_count_;
-
// number of instance fields that are object refs
size_t num_reference_instance_fields_;
@@ -2099,9 +2057,6 @@
// Bitmap of offsets of sfields.
uint32_t reference_static_offsets_;
- // source file name, if known. Otherwise, NULL.
- const char* source_file_;
-
// state of class initialization
Status status_;
@@ -2328,8 +2283,6 @@
class ClassClass : public Class {
private:
- // Padding to ensure the 64-bit serialVersionUID_ begins on a 8-byte boundary
- int32_t padding_;
int64_t serialVersionUID_;
friend struct ClassClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
@@ -2339,8 +2292,8 @@
private:
CharArray* ASCII_;
Object* CASE_INSENSITIVE_ORDER_;
- uint32_t REPLACEMENT_CHAR_;
int64_t serialVersionUID_;
+ uint32_t REPLACEMENT_CHAR_;
friend struct StringClassOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
};
@@ -2725,39 +2678,49 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(StackTraceElement);
};
-class InterfaceEntry {
+ class InterfaceEntry : public ObjectArray<Object> {
public:
- InterfaceEntry() : interface_(NULL), method_index_array_(NULL) {
- }
-
Class* GetInterface() const {
- DCHECK(interface_ != NULL);
- return interface_;
+ Class* interface = Get(kInterface)->AsClass();
+ DCHECK(interface != NULL);
+ return interface;
}
void SetInterface(Class* interface) {
+ DCHECK(interface != NULL);
DCHECK(interface->IsInterface());
- interface_ = interface;
+ DCHECK(Get(kInterface) == NULL);
+ Set(kInterface, interface);
}
- uint32_t* GetMethodIndexArray() const {
- return method_index_array_;
+ ObjectArray<Method>* GetMethodArray() const {
+ ObjectArray<Method>* method_array = down_cast<ObjectArray<Method>*>(Get(kMethodArray));
+ DCHECK(method_array != NULL);
+ return method_array;
}
- void SetMethodIndexArray(uint32_t* new_mia) {
- method_index_array_ = new_mia;
+ void SetMethodArray(ObjectArray<Method>* new_ma) {
+ DCHECK(new_ma != NULL);
+ DCHECK(Get(kMethodArray) == NULL);
+ Set(kMethodArray, new_ma);
+ }
+
+ static size_t LengthAsArray() {
+ return kMax;
}
private:
- // Points to the interface class.
- Class* interface_;
- // Index into array of vtable offsets. This points into the
- // ifvi_pool_, which holds the vtables for all interfaces declared by
- // this class.
- uint32_t* method_index_array_;
+ enum ArrayIndex {
+ // Points to the interface class.
+ kInterface = 0,
+ // Method pointers into the vtable, allow fast map from interface
+ // method index to concrete instance method.
+ kMethodArray = 1,
+ kMax = 2,
+ };
- DISALLOW_COPY_AND_ASSIGN(InterfaceEntry);
+ DISALLOW_IMPLICIT_CONSTRUCTORS(InterfaceEntry);
};
} // namespace art
diff --git a/src/thread.cc b/src/thread.cc
index 9361d00..78cb1c6 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -325,7 +325,11 @@
if (errno != 0) {
PLOG(FATAL) << "pthread_mutexattr_init failed";
}
+#if VERIFY_OBJECT_ENABLED
+ errno = pthread_mutexattr_settype(&debug_attributes, PTHREAD_MUTEX_RECURSIVE);
+#else
errno = pthread_mutexattr_settype(&debug_attributes, PTHREAD_MUTEX_ERRORCHECK);
+#endif
if (errno != 0) {
PLOG(FATAL) << "pthread_mutexattr_settype failed";
}
@@ -928,7 +932,7 @@
StackTraceElement* obj =
StackTraceElement::Alloc(readable_descriptor,
method->GetName(),
- String::AllocFromModifiedUtf8(klass->GetSourceFile()),
+ klass->GetSourceFile(),
dex_file.GetLineNumFromPC(method,
method->ToDexPC(build_trace_visitor.GetPC(i))));
java_traces->Set(i, obj);