| 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
|
|
|