Index: runtime/vm/assembler.cc |
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc |
index 23d08e04139694732d021a38cbcde48a3f2a0de5..8981e55f042f72eaba12f8973bd993a4adf4f751 100644 |
--- a/runtime/vm/assembler.cc |
+++ b/runtime/vm/assembler.cc |
@@ -64,8 +64,9 @@ AssemblerBuffer::EnsureCapacity::~EnsureCapacity() { |
#endif |
-AssemblerBuffer::AssemblerBuffer() |
- : pointer_offsets_(new ZoneGrowableArray<intptr_t>(16)) { |
+AssemblerBuffer::AssemblerBuffer(Assembler* assembler) |
+ : assembler_(assembler), |
+ pointer_offsets_(new ZoneGrowableArray<intptr_t>(16)) { |
static const intptr_t kInitialBufferCapacity = 4 * KB; |
contents_ = NewContents(kInitialBufferCapacity); |
cursor_ = contents_; |
@@ -89,7 +90,7 @@ AssemblerBuffer::~AssemblerBuffer() { |
void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) { |
AssemblerFixup* fixup = fixup_; |
while (fixup != NULL) { |
- fixup->Process(region, fixup->position()); |
+ fixup->Process(region, fixup->position(), assembler_); |
fixup = fixup->previous(); |
} |
} |
@@ -144,7 +145,9 @@ class PatchCodeWithHandle : public AssemblerFixup { |
: pointer_offsets_(pointer_offsets), object_(object) { |
} |
- void Process(const MemoryRegion& region, intptr_t position) { |
+ void Process(const MemoryRegion& region, |
+ intptr_t position, |
+ Assembler* assembler) { |
// Patch the handle into the code. Once the instructions are installed into |
// a raw code object and the pointer offsets are setup, the handle is |
// resolved. |
@@ -242,62 +245,136 @@ const Code::Comments& Assembler::GetCodeComments() const { |
} |
-intptr_t ObjectPool::AddObject(const Object& obj, Patchability patchable) { |
+intptr_t ObjectPoolHelper::AddObject(const Object& obj) { |
// The object pool cannot be used in the vm isolate. |
ASSERT(Isolate::Current() != Dart::vm_isolate()); |
- if (object_pool_.IsNull()) { |
- object_pool_ = GrowableObjectArray::New(Heap::kOld); |
- } |
- object_pool_.Add(obj, Heap::kOld); |
- patchable_pool_entries_.Add(patchable); |
+ ASSERT(obj.IsNotTemporaryScopedHandle()); |
+ tagged_entries_.Add(&obj); |
+ // The object isn't patchable. Record the index for fast lookup. |
+ intptr_t index = Assembler::kNumFixedEntries + tagged_entries_.length() - 1; |
+ object_index_table_.Insert(ObjIndexPair(&obj, index)); |
+ return index; |
+} |
+ |
+ |
+intptr_t ObjectPoolHelper::AddFixedObject(const Object& obj) { |
+ // The object pool cannot be used in the vm isolate. |
+ ASSERT(Isolate::Current() != Dart::vm_isolate()); |
+ ASSERT(obj.IsNotTemporaryScopedHandle()); |
+ fixed_entries_.Add(ObjectPool::Entry(&obj)); |
+ // The object isn't patchable. Record the index for fast lookup. |
+ object_index_table_.Insert( |
+ ObjIndexPair(&obj, fixed_entries_.length() - 1)); |
+ return fixed_entries_.length() - 1; |
+} |
+ |
+ |
+intptr_t ObjectPoolHelper::AddFixedExternalLabel(const ExternalLabel* label) { |
+ ASSERT(Isolate::Current() != Dart::vm_isolate()); |
+ uword value = label->address(); |
+ fixed_entries_.Add(ObjectPool::Entry(value)); |
+ ASSERT(fixed_entries_.length() <= Assembler::kNumFixedEntries); |
+ untagged_index_table_.Insert( |
+ UntaggedIndexPair(value, fixed_entries_.length() - 1)); |
+ return fixed_entries_.length() - 1; |
+} |
+ |
+ |
+intptr_t ObjectPoolHelper::AddUntagged(uword value, Patchability patchable) { |
+ ASSERT(Isolate::Current() != Dart::vm_isolate()); |
+ untagged_entries_.Add(value); |
+ intptr_t index = |
+ Assembler::kNumFixedEntries + untagged_entries_.length() - 1; |
if (patchable == kNotPatchable) { |
- // The object isn't patchable. Record the index for fast lookup. |
- object_pool_index_table_.Insert( |
- ObjIndexPair(&obj, object_pool_.Length() - 1)); |
+ // The entry isn't patchable. Record the index for fast lookup. |
+ untagged_index_table_.Insert(UntaggedIndexPair(value, index)); |
} |
- return object_pool_.Length() - 1; |
+ return index; |
} |
-intptr_t ObjectPool::AddExternalLabel(const ExternalLabel* label, |
- Patchability patchable) { |
- ASSERT(Isolate::Current() != Dart::vm_isolate()); |
- const uword address = label->address(); |
- ASSERT(Utils::IsAligned(address, 4)); |
- // The address is stored in the object array as a RawSmi. |
- const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address)); |
- return AddObject(smi, patchable); |
+intptr_t ObjectPoolHelper::AddExternalLabel(const ExternalLabel* label, |
+ Patchability patchable) { |
+ return AddUntagged(label->address(), patchable); |
} |
-intptr_t ObjectPool::FindObject(const Object& obj, Patchability patchable) { |
+intptr_t ObjectPoolHelper::AddImmediate(uword imm) { |
+ return AddUntagged(imm, kNotPatchable); |
+} |
+ |
+ |
+intptr_t ObjectPoolHelper::FindObject(const Object& obj) { |
// The object pool cannot be used in the vm isolate. |
ASSERT(Isolate::Current() != Dart::vm_isolate()); |
+ // Check if we've already got it in the object pool. |
+ intptr_t idx = object_index_table_.Lookup(&obj); |
+ return (idx != ObjIndexPair::kNoIndex) ? idx : AddObject(obj); |
+} |
- // If the object is not patchable, check if we've already got it in the |
- // object pool. |
- if (patchable == kNotPatchable && !object_pool_.IsNull()) { |
- intptr_t idx = object_pool_index_table_.Lookup(&obj); |
- if (idx != ObjIndexPair::kNoIndex) { |
- ASSERT(patchable_pool_entries_[idx] == kNotPatchable); |
+ |
+intptr_t ObjectPoolHelper::FindUntagged(uword value, Patchability patchable) { |
+ // The object pool cannot be used in the vm isolate. |
+ ASSERT(Isolate::Current() != Dart::vm_isolate()); |
+ if (patchable == kNotPatchable) { |
+ // Check if we've already got it in the object pool. |
+ intptr_t idx = untagged_index_table_.Lookup(value); |
+ if (idx != UntaggedIndexPair::kNoIndex) { |
return idx; |
} |
} |
+ return AddUntagged(value, patchable); |
+} |
- return AddObject(obj, patchable); |
+ |
+intptr_t ObjectPoolHelper::FindExternalLabel(const ExternalLabel* label, |
+ Patchability patchable) { |
+ return FindUntagged(label->address(), patchable); |
} |
-intptr_t ObjectPool::FindExternalLabel(const ExternalLabel* label, |
- Patchability patchable) { |
- // The object pool cannot be used in the vm isolate. |
- ASSERT(Isolate::Current() != Dart::vm_isolate()); |
- const uword address = label->address(); |
- ASSERT(Utils::IsAligned(address, 4)); |
- // The address is stored in the object array as a RawSmi. |
- const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address)); |
- return FindObject(smi, patchable); |
+intptr_t ObjectPoolHelper::FindImmediate(uword imm) { |
+ return FindUntagged(imm, kNotPatchable); |
} |
+RawObjectPool* ObjectPoolHelper::MakeObjectPool() { |
+ // Code in the VM isolate does not use object pool. |
+ if (Isolate::Current() == Dart::vm_isolate()) { |
+ return Object::empty_object_pool().raw(); |
+ } |
+ |
+ intptr_t length = |
+ Assembler::kNumFixedEntries + |
+ tagged_entries_.length() + |
+ untagged_entries_.length(); |
+ const ObjectPool& object_pool = ObjectPool::Handle( |
+ ObjectPool::New(length, tagged_entries_.length())); |
+ intptr_t i = 0; |
+ for (; i < Assembler::kNumFixedObjectEntries; ++i) { |
+ object_pool.SetObjectAt(i, *fixed_entries_[i].obj_); |
+ } |
+ for (; i < Assembler::kNumFixedEntries; ++i) { |
+ object_pool.SetRawValueAt(i, fixed_entries_[i].raw_value_); |
+ } |
+ for (i = 0; i < tagged_entries_.length(); ++i) { |
+ object_pool.SetObjectAt(Assembler::kNumFixedEntries + i, |
+ *tagged_entries_[i]); |
+ } |
+ for (intptr_t j = 0; j < untagged_entries_.length(); ++j) { |
+ object_pool.SetRawValueAt(Assembler::kNumFixedEntries + i + j, |
+ untagged_entries_[j]); |
+ } |
+ return object_pool.raw(); |
+} |
+ |
+ |
+void ObjectPoolIndexFixup::Process(const MemoryRegion& region, |
+ intptr_t position, |
+ Assembler* assembler) { |
+ int32_t index = region.Load<int32_t>(position - sizeof(int32_t)); |
+ index += assembler->object_pool().UntaggedEntryStart() * kWordSize; |
+ region.Store<int32_t>(position - sizeof(int32_t), index); |
+} |
+ |
} // namespace dart |