Move allocation of fields and methods to heap
Also make Object and subclasses constructors private to prevent
accidental non-heap allocation.
Change-Id: If9513967ba012748eb0d54c04e92df0f0944d385
diff --git a/src/class_linker.cc b/src/class_linker.cc
index a205a06..15c2e40 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -172,36 +172,42 @@
// Load static fields.
if (klass->num_sfields_ != 0) {
// TODO: allocate on the object heap.
- klass->sfields_ = new StaticField[klass->NumStaticFields()]();
+ klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
uint32_t last_idx = 0;
for (size_t i = 0; i < klass->num_sfields_; ++i) {
RawDexFile::Field raw_field;
raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
- LoadField(klass, raw_field, &klass->sfields_[i]);
+ StaticField* sfield = Heap::AllocStaticField();
+ klass->sfields_[i] = sfield;
+ LoadField(klass, raw_field, sfield);
}
}
// Load instance fields.
if (klass->NumInstanceFields() != 0) {
// TODO: allocate on the object heap.
- klass->ifields_ = new InstanceField[klass->NumInstanceFields()]();
+ klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
uint32_t last_idx = 0;
for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
RawDexFile::Field raw_field;
raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
- LoadField(klass, raw_field, klass->GetInstanceField(i));
+ InstanceField* ifield = Heap::AllocInstanceField();
+ klass->ifields_[i] = ifield;
+ LoadField(klass, raw_field, ifield);
}
}
// Load direct methods.
if (klass->NumDirectMethods() != 0) {
// TODO: append direct methods to class object
- klass->direct_methods_ = new Method[klass->NumDirectMethods()]();
+ klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
uint32_t last_idx = 0;
for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
RawDexFile::Method raw_method;
raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
- LoadMethod(klass, raw_method, klass->GetDirectMethod(i));
+ Method* meth = Heap::AllocMethod();
+ klass->direct_methods_[i] = meth;
+ LoadMethod(klass, raw_method, meth);
// TODO: register maps
}
}
@@ -209,12 +215,14 @@
// Load virtual methods.
if (klass->NumVirtualMethods() != 0) {
// TODO: append virtual methods to class object
- klass->virtual_methods_ = new Method[klass->NumVirtualMethods()]();
+ klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
uint32_t last_idx = 0;
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
RawDexFile::Method raw_method;
raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
- LoadMethod(klass, raw_method, klass->GetVirtualMethod(i));
+ Method* meth = Heap::AllocMethod();
+ klass->virtual_methods_[i] = meth;
+ LoadMethod(klass, raw_method, meth);
// TODO: register maps
}
}
@@ -922,39 +930,28 @@
}
}
if (miranda_count != 0) {
- Method* newVirtualMethods;
- Method* meth;
- int oldMethodCount, oldVtableCount;
- if (klass->virtual_methods_ == NULL) {
- newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
-
- } else {
- newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
+ int oldMethodCount = klass->NumVirtualMethods();
+ int newMethodCount = oldMethodCount + miranda_count;
+ Method** newVirtualMethods = new Method*[newMethodCount];
+ if (klass->virtual_methods_ != NULL) {
memcpy(newVirtualMethods,
klass->virtual_methods_,
- klass->NumVirtualMethods() * sizeof(Method));
-
+ klass->NumVirtualMethods() * sizeof(Method*));
}
- if (newVirtualMethods != klass->virtual_methods_) {
- Method* meth = newVirtualMethods;
- for (size_t i = 0; i < klass->NumVirtualMethods(); i++, meth++) {
- klass->vtable_[meth->method_index_] = meth;
- }
- }
- oldMethodCount = klass->NumVirtualMethods();
klass->virtual_methods_ = newVirtualMethods;
- klass->num_virtual_methods_ += miranda_count;
+ klass->num_virtual_methods_ = newMethodCount;
CHECK(klass->vtable_ != NULL);
- oldVtableCount = klass->vtable_count_;
+ int oldVtableCount = klass->vtable_count_;
klass->vtable_count_ += miranda_count;
- meth = klass->virtual_methods_ + oldMethodCount;
- for (int i = 0; i < miranda_count; i++, meth++) {
+ for (int i = 0; i < miranda_count; i++) {
+ Method* meth = Heap::AllocMethod();
memcpy(meth, miranda_list[i], sizeof(Method));
meth->klass_ = klass;
meth->access_flags_ |= kAccMiranda;
meth->method_index_ = 0xFFFF & (oldVtableCount + i);
+ klass->virtual_methods_[oldMethodCount+i] = meth;
klass->vtable_[oldVtableCount + i] = meth;
}
}
@@ -980,17 +977,18 @@
// Move references to the front.
klass->num_reference_ifields_ = 0;
size_t i = 0;
- size_t j = klass->NumInstanceFields() - 1;
- for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
+ for ( ; i < klass->NumInstanceFields(); i++) {
InstanceField* pField = klass->GetInstanceField(i);
char c = pField->GetType();
if (c != '[' && c != 'L') {
- while (j > i) {
- InstanceField* refField = klass->GetInstanceField(j--);
+ for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+ InstanceField* refField = klass->GetInstanceField(j);
char rc = refField->GetType();
if (rc == '[' || rc == 'L') {
- pField->Swap(refField);
+ klass->SetInstanceField(i, refField);
+ klass->SetInstanceField(j, pField);
+ pField = refField;
c = rc;
klass->num_reference_ifields_++;
break;
@@ -1023,12 +1021,13 @@
// Next field is 64-bit, so search for a 32-bit field we can
// swap into it.
bool found = false;
- j = klass->NumInstanceFields() - 1;
- while (j > i) {
- InstanceField* singleField = klass->GetInstanceField(j--);
+ for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+ InstanceField* singleField = klass->GetInstanceField(j);
char rc = singleField->GetType();
if (rc != 'J' && rc != 'D') {
- pField->Swap(singleField);
+ klass->SetInstanceField(i, singleField);
+ klass->SetInstanceField(j, pField);
+ pField = singleField;
pField->SetOffset(fieldOffset);
fieldOffset += sizeof(uint32_t);
found = true;
@@ -1045,16 +1044,17 @@
// Alignment is good, shuffle any double-wide fields forward, and
// finish assigning field offsets to all fields.
assert(i == klass->NumInstanceFields() || (fieldOffset & 0x04) == 0);
- j = klass->NumInstanceFields() - 1;
for ( ; i < klass->NumInstanceFields(); i++) {
InstanceField* pField = klass->GetInstanceField(i);
char c = pField->GetType();
if (c != 'D' && c != 'J') {
- while (j > i) {
- InstanceField* doubleField = klass->GetInstanceField(j--);
+ for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
+ InstanceField* doubleField = klass->GetInstanceField(j);
char rc = doubleField->GetType();
if (rc == 'D' || rc == 'J') {
- pField->Swap(doubleField);
+ klass->SetInstanceField(i, doubleField);
+ klass->SetInstanceField(j, pField);
+ pField = doubleField;
c = rc;
break;
}