Add ObjectArray::CopyOf
As part of doing this, moved Heap::Alloc* helpers to the corresponding
classes in object.h to break heap.h<->object.h cycle due to use of
Heap from ObjectArray::CopyOf (which is templatized and needs to be
defined in .h file).
Change-Id: I1870af6e9dc6552820034ead5e20d13ae4da67da
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 22bcca6..5db2bea 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -113,11 +113,11 @@
}
DexCache* ClassLinker::AllocDexCache() {
- return down_cast<DexCache*>(Heap::AllocObjectArray<Object>(object_array_class_, DexCache::kMax));
+ return down_cast<DexCache*>(AllocObjectArray<Object>(DexCache::kMax));
}
Class* ClassLinker::AllocClass(DexCache* dex_cache) {
- Class* klass = down_cast<Class*>(Heap::AllocObject(java_lang_Class_));
+ Class* klass = down_cast<Class*>(Object::Alloc(java_lang_Class_));
klass->dex_cache_ = dex_cache;
return klass;
}
@@ -1106,18 +1106,12 @@
}
bool ClassLinker::LinkVirtualMethods(Class* klass) {
- uint32_t max_count = klass->NumVirtualMethods();
- if (klass->GetSuperClass() != NULL) {
- max_count += klass->GetSuperClass()->vtable_->GetLength();
- } else {
- CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
- }
- // TODO: do not assign to the vtable field until it is fully constructed.
- klass->vtable_ = AllocObjectArray<Method>(max_count);
if (klass->HasSuperClass()) {
+ uint32_t max_count = klass->NumVirtualMethods() + klass->GetSuperClass()->vtable_->GetLength();
size_t actual_count = klass->GetSuperClass()->vtable_->GetLength();
CHECK_LE(actual_count, max_count);
- ObjectArray<Method>::Copy(klass->GetSuperClass()->vtable_, 0, klass->vtable_, 0, actual_count);
+ // TODO: do not assign to the vtable field until it is fully constructed.
+ klass->vtable_ = klass->GetSuperClass()->vtable_->CopyOf(max_count);
// See if any of our virtual methods override the superclass.
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
Method* local_method = klass->GetVirtualMethod(i);
@@ -1148,20 +1142,23 @@
}
CHECK_LE(actual_count, max_count);
if (actual_count < max_count) {
- ObjectArray<Method>* new_vtable = AllocObjectArray<Method>(actual_count);
- ObjectArray<Method>::Copy(klass->vtable_, 0, new_vtable, 0, actual_count);
- klass->vtable_ = new_vtable;
+ // TODO: do not assign to the vtable field until it is fully constructed.
+ klass->vtable_ = klass->vtable_->CopyOf(actual_count);
LG << "shrunk vtable: "
<< "was " << max_count << ", "
<< "now " << actual_count;
}
} else {
CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
- if (!IsUint(16, klass->NumVirtualMethods())) {
+ uint32_t num_virtual_methods = klass->NumVirtualMethods();
+ CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
+ if (!IsUint(16, num_virtual_methods)) {
LG << "Too many methods"; // TODO: VirtualMachineError
return false;
}
- for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
+ // TODO: do not assign to the vtable field until it is fully constructed.
+ klass->vtable_ = AllocObjectArray<Method>(num_virtual_methods);
+ for (size_t i = 0; i < num_virtual_methods; ++i) {
klass->vtable_->Set(i, klass->GetVirtualMethod(i));
klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
}
@@ -1267,20 +1264,13 @@
if (miranda_count != 0) {
int old_method_count = klass->NumVirtualMethods();
int new_method_count = old_method_count + miranda_count;
- ObjectArray<Method>* new_virtual_methods = AllocObjectArray<Method>(new_method_count);
- ObjectArray<Method>::Copy(klass->virtual_methods_, 0,
- new_virtual_methods, 0,
- old_method_count);
- klass->virtual_methods_ = new_virtual_methods;
+ klass->virtual_methods_ = klass->virtual_methods_->CopyOf(new_method_count);
CHECK(klass->vtable_ != NULL);
int old_vtable_count = klass->vtable_->GetLength();
int new_vtable_count = old_vtable_count + miranda_count;
- ObjectArray<Method>* new_vtable = AllocObjectArray<Method>(new_vtable_count);
- ObjectArray<Method>::Copy(klass->vtable_, 0,
- new_vtable, 0,
- old_vtable_count);
- klass->vtable_ = new_vtable;
+ // TODO: do not assign to the vtable field until it is fully constructed.
+ klass->vtable_ = klass->vtable_->CopyOf(new_vtable_count);
for (int i = 0; i < miranda_count; i++) {
Method* meth = AllocMethod();
@@ -1511,9 +1501,9 @@
const DexFile* dex_file = FindDexFile(referring->GetDexCache());
const DexFile::StringId& string_id = dex_file->GetStringId(string_idx);
const char* string_data = dex_file->GetStringData(string_id);
- String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_,
- char_array_class_,
- string_data);
+ String* new_string = String::AllocFromModifiedUtf8(java_lang_String_,
+ char_array_class_,
+ string_data);
// TODO: intern the new string
referring->GetDexCache()->SetResolvedString(string_idx, new_string);
return new_string;
diff --git a/src/class_linker.h b/src/class_linker.h
index 086234d..738979b 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -28,8 +28,10 @@
StaticField* AllocStaticField();
InstanceField* AllocInstanceField();
Method* AllocMethod();
- template <class C> ObjectArray<C>* AllocObjectArray(size_t length) {
- return Heap::AllocObjectArray<C>(object_array_class_, length);
+
+ template <class T>
+ ObjectArray<T>* AllocObjectArray(size_t length) {
+ return ObjectArray<T>::Alloc(object_array_class_, length);
}
diff --git a/src/heap.cc b/src/heap.cc
index 851433b..6ec6aac 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -66,10 +66,6 @@
delete live_bitmap_;
}
-Object* Heap::AllocObject(Class* klass) {
- return AllocObject(klass, klass->object_size_);
-}
-
Object* Heap::AllocObject(Class* klass, size_t num_bytes) {
Object* obj = Allocate(num_bytes);
if (obj != NULL) {
@@ -179,17 +175,6 @@
return NULL;
}
-String* Heap::AllocStringFromModifiedUtf8(Class* java_lang_String,
- Class* char_array,
- const char* data) {
- String* string = AllocString(java_lang_String);
- uint32_t count = strlen(data); // TODO
- CharArray* array = AllocCharArray(char_array, count);
- string->array_ = array;
- string->count_ = count;
- return string;
-}
-
void Heap::CollectGarbage() {
CollectGarbageInternal();
}
diff --git a/src/heap.h b/src/heap.h
index e54135e..1059fd7 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -7,12 +7,13 @@
#include <vector>
#include "globals.h"
-#include "object.h"
#include "object_bitmap.h"
#include "thread.h"
namespace art {
+class Class;
+class Object;
class Space;
class HeapBitmap;
@@ -30,43 +31,9 @@
static void Destroy();
- // Allocates and initializes storage for a class instance.
- static Object* AllocObject(Class* klass);
-
+ // Allocates and initializes storage for an object instance.
static Object* AllocObject(Class* klass, size_t num_bytes);
- static Array* AllocArray(Class* array_class,
- size_t component_count,
- size_t component_size) {
- size_t size = sizeof(Array) + component_count * component_size;
- Array* array = down_cast<Array*>(AllocObject(array_class, size));
- if (array != NULL) {
- array->SetLength(component_count);
- }
- return array;
- }
-
- template <class C> static ObjectArray<C>* AllocObjectArray(Class* object_array_class,
- size_t length) {
- return down_cast<ObjectArray<C>*>(AllocArray(object_array_class,
- length,
- sizeof(uint32_t)));
- }
-
- static CharArray* AllocCharArray(Class* char_array_class, size_t length) {
- return down_cast<CharArray*>(AllocArray(char_array_class,
- length,
- sizeof(uint16_t)));
- }
-
- static String* AllocString(Class* java_lang_String) {
- return down_cast<String*>(AllocObject(java_lang_String));
- }
-
- static String* AllocStringFromModifiedUtf8(Class* java_lang_String,
- Class* char_array,
- const char* data);
-
// Initiates an explicit garbage collection.
static void CollectGarbage();
diff --git a/src/object.cc b/src/object.cc
index 289f526..fbcfa8b 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include "globals.h"
+#include "heap.h"
#include "logging.h"
#include "dex_cache.h"
#include "dex_file.h"
diff --git a/src/object.h b/src/object.h
index bf965df..a154959 100644
--- a/src/object.h
+++ b/src/object.h
@@ -6,6 +6,7 @@
#include "constants.h"
#include "casts.h"
#include "globals.h"
+#include "heap.h"
#include "logging.h"
#include "macros.h"
#include "offsets.h"
@@ -104,6 +105,8 @@
class Object {
public:
+ static Object* Alloc(Class* klass);
+
Class* GetClass() const {
return klass_;
}
@@ -563,6 +566,16 @@
class Array : public Object {
public:
+ static Array* Alloc(Class* array_class,
+ size_t component_count,
+ size_t component_size) {
+ size_t size = sizeof(Array) + component_count * component_size;
+ Array* array = down_cast<Array*>(Heap::AllocObject(array_class, size));
+ if (array != NULL) {
+ array->SetLength(component_count);
+ }
+ return array;
+ }
uint32_t GetLength() const {
return length_;
}
@@ -587,21 +600,33 @@
template<class T>
class ObjectArray : public Array {
public:
- C* Get(uint32_t i) const {
+ static ObjectArray<T>* Alloc(Class* object_array_class,
+ size_t length) {
+ return down_cast<ObjectArray<T>*>(Array::Alloc(object_array_class,
+ length,
+ sizeof(uint32_t)));
+ }
+
+ T* Get(uint32_t i) const {
DCHECK_LT(i, GetLength());
Object* const * data = reinterpret_cast<Object* const *>(GetData());
- return down_cast<C*>(data[i]);
+ return down_cast<T*>(data[i]);
}
- void Set(uint32_t i, C* object) {
+ void Set(uint32_t i, T* object) {
DCHECK_LT(i, GetLength());
- C** data = reinterpret_cast<C**>(GetData());
+ T** data = reinterpret_cast<T**>(GetData());
data[i] = object;
}
- static void Copy(ObjectArray<C>* src, int src_pos, ObjectArray<C>* dst, int dst_pos, size_t length) {
+ static void Copy(ObjectArray<T>* src, int src_pos, ObjectArray<T>* dst, int dst_pos, size_t length) {
for (size_t i = 0; i < length; i++) {
dst->Set(dst_pos + i, src->Get(src_pos + i));
}
}
+ ObjectArray<T>* CopyOf(size_t new_length) {
+ ObjectArray<T>* new_array = Alloc(klass_, new_length);
+ Copy(this, 0, new_array, 0, std::min(GetLength(), new_length));
+ return new_array;
+ }
private:
ObjectArray();
@@ -945,6 +970,10 @@
};
std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
+inline Object* Object::Alloc(Class* klass) {
+ return Heap::AllocObject(klass, klass->object_size_);
+}
+
class DataObject : public Object {
public:
uint32_t fields_[0];
@@ -953,12 +982,34 @@
};
class CharArray : public Array {
+ public:
+ static CharArray* Alloc(Class* char_array_class, size_t length) {
+ return down_cast<CharArray*>(Array::Alloc(char_array_class,
+ length,
+ sizeof(uint16_t)));
+ }
private:
CharArray();
};
class String : public Object {
public:
+ static String* Alloc(Class* java_lang_String) {
+ return down_cast<String*>(Object::Alloc(java_lang_String));
+ }
+
+ static String* AllocFromModifiedUtf8(Class* java_lang_String,
+ Class* char_array,
+ const char* data) {
+ String* string = Alloc(java_lang_String);
+ uint32_t count = strlen(data); // TODO
+ CharArray* array = CharArray::Alloc(char_array, count);
+ string->array_ = array;
+ string->count_ = count;
+ return string;
+ }
+
+ public: // TODO: private
CharArray* array_;
uint32_t hash_code_;
diff --git a/src/thread.h b/src/thread.h
index ed2ba12..d0f6623 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -11,7 +11,6 @@
#include "jni_internal.h"
#include "logging.h"
#include "macros.h"
-#include "object.h"
#include "offsets.h"
#include "runtime.h"
@@ -19,6 +18,7 @@
namespace art {
+class Method;
class Object;
class Runtime;
class StackHandleBlock;