Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: runtime/vm/assembler.cc

Issue 1147303002: Support untagged object pool entries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebased Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/assembler.h" 5 #include "vm/assembler.h"
6 6
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 #include "vm/cpu.h" 8 #include "vm/cpu.h"
9 #include "vm/heap.h" 9 #include "vm/heap.h"
10 #include "vm/memory_region.h" 10 #include "vm/memory_region.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // Unmark the buffer, so we cannot emit after this. 57 // Unmark the buffer, so we cannot emit after this.
58 buffer_->has_ensured_capacity_ = false; 58 buffer_->has_ensured_capacity_ = false;
59 // Make sure the generated instruction doesn't take up more 59 // Make sure the generated instruction doesn't take up more
60 // space than the minimum gap. 60 // space than the minimum gap.
61 intptr_t delta = gap_ - ComputeGap(); 61 intptr_t delta = gap_ - ComputeGap();
62 ASSERT(delta <= kMinimumGap); 62 ASSERT(delta <= kMinimumGap);
63 } 63 }
64 #endif 64 #endif
65 65
66 66
67 AssemblerBuffer::AssemblerBuffer() 67 AssemblerBuffer::AssemblerBuffer(Assembler* assembler)
68 : pointer_offsets_(new ZoneGrowableArray<intptr_t>(16)) { 68 : assembler_(assembler),
69 pointer_offsets_(new ZoneGrowableArray<intptr_t>(16)) {
69 static const intptr_t kInitialBufferCapacity = 4 * KB; 70 static const intptr_t kInitialBufferCapacity = 4 * KB;
70 contents_ = NewContents(kInitialBufferCapacity); 71 contents_ = NewContents(kInitialBufferCapacity);
71 cursor_ = contents_; 72 cursor_ = contents_;
72 limit_ = ComputeLimit(contents_, kInitialBufferCapacity); 73 limit_ = ComputeLimit(contents_, kInitialBufferCapacity);
73 fixup_ = NULL; 74 fixup_ = NULL;
74 #if defined(DEBUG) 75 #if defined(DEBUG)
75 has_ensured_capacity_ = false; 76 has_ensured_capacity_ = false;
76 fixups_processed_ = false; 77 fixups_processed_ = false;
77 #endif 78 #endif
78 79
79 // Verify internal state. 80 // Verify internal state.
80 ASSERT(Capacity() == kInitialBufferCapacity); 81 ASSERT(Capacity() == kInitialBufferCapacity);
81 ASSERT(Size() == 0); 82 ASSERT(Size() == 0);
82 } 83 }
83 84
84 85
85 AssemblerBuffer::~AssemblerBuffer() { 86 AssemblerBuffer::~AssemblerBuffer() {
86 } 87 }
87 88
88 89
89 void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) { 90 void AssemblerBuffer::ProcessFixups(const MemoryRegion& region) {
90 AssemblerFixup* fixup = fixup_; 91 AssemblerFixup* fixup = fixup_;
91 while (fixup != NULL) { 92 while (fixup != NULL) {
92 fixup->Process(region, fixup->position()); 93 fixup->Process(region, fixup->position(), assembler_);
93 fixup = fixup->previous(); 94 fixup = fixup->previous();
94 } 95 }
95 } 96 }
96 97
97 98
98 void AssemblerBuffer::FinalizeInstructions(const MemoryRegion& instructions) { 99 void AssemblerBuffer::FinalizeInstructions(const MemoryRegion& instructions) {
99 // Copy the instructions from the buffer. 100 // Copy the instructions from the buffer.
100 MemoryRegion from(reinterpret_cast<void*>(contents()), Size()); 101 MemoryRegion from(reinterpret_cast<void*>(contents()), Size());
101 instructions.CopyFrom(0, from); 102 instructions.CopyFrom(0, from);
102 103
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 138 }
138 139
139 140
140 class PatchCodeWithHandle : public AssemblerFixup { 141 class PatchCodeWithHandle : public AssemblerFixup {
141 public: 142 public:
142 PatchCodeWithHandle(ZoneGrowableArray<intptr_t>* pointer_offsets, 143 PatchCodeWithHandle(ZoneGrowableArray<intptr_t>* pointer_offsets,
143 const Object& object) 144 const Object& object)
144 : pointer_offsets_(pointer_offsets), object_(object) { 145 : pointer_offsets_(pointer_offsets), object_(object) {
145 } 146 }
146 147
147 void Process(const MemoryRegion& region, intptr_t position) { 148 void Process(const MemoryRegion& region,
149 intptr_t position,
150 Assembler* assembler) {
148 // Patch the handle into the code. Once the instructions are installed into 151 // Patch the handle into the code. Once the instructions are installed into
149 // a raw code object and the pointer offsets are setup, the handle is 152 // a raw code object and the pointer offsets are setup, the handle is
150 // resolved. 153 // resolved.
151 region.Store<const Object*>(position, &object_); 154 region.Store<const Object*>(position, &object_);
152 pointer_offsets_->Add(position); 155 pointer_offsets_->Add(position);
153 } 156 }
154 157
155 virtual bool IsPointerOffset() const { return true; } 158 virtual bool IsPointerOffset() const { return true; }
156 159
157 private: 160 private:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 238
236 for (intptr_t i = 0; i < comments_.length(); i++) { 239 for (intptr_t i = 0; i < comments_.length(); i++) {
237 comments.SetPCOffsetAt(i, comments_[i]->pc_offset()); 240 comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
238 comments.SetCommentAt(i, comments_[i]->comment()); 241 comments.SetCommentAt(i, comments_[i]->comment());
239 } 242 }
240 243
241 return comments; 244 return comments;
242 } 245 }
243 246
244 247
245 intptr_t ObjectPool::AddObject(const Object& obj, Patchability patchable) { 248 intptr_t ObjectPoolHelper::AddObject(const Object& obj) {
246 // The object pool cannot be used in the vm isolate. 249 // The object pool cannot be used in the vm isolate.
247 ASSERT(Isolate::Current() != Dart::vm_isolate()); 250 ASSERT(Isolate::Current() != Dart::vm_isolate());
248 if (object_pool_.IsNull()) { 251 ASSERT(obj.IsNotTemporaryScopedHandle());
249 object_pool_ = GrowableObjectArray::New(Heap::kOld); 252 tagged_entries_.Add(&obj);
250 } 253 // The object isn't patchable. Record the index for fast lookup.
251 object_pool_.Add(obj, Heap::kOld); 254 intptr_t index = Assembler::kNumFixedEntries + tagged_entries_.length() - 1;
252 patchable_pool_entries_.Add(patchable); 255 object_index_table_.Insert(ObjIndexPair(&obj, index));
253 if (patchable == kNotPatchable) { 256 return index;
254 // The object isn't patchable. Record the index for fast lookup.
255 object_pool_index_table_.Insert(
256 ObjIndexPair(&obj, object_pool_.Length() - 1));
257 }
258 return object_pool_.Length() - 1;
259 } 257 }
260 258
261 259
262 intptr_t ObjectPool::AddExternalLabel(const ExternalLabel* label, 260 intptr_t ObjectPoolHelper::AddFixedObject(const Object& obj) {
263 Patchability patchable) { 261 // The object pool cannot be used in the vm isolate.
264 ASSERT(Isolate::Current() != Dart::vm_isolate()); 262 ASSERT(Isolate::Current() != Dart::vm_isolate());
265 const uword address = label->address(); 263 ASSERT(obj.IsNotTemporaryScopedHandle());
266 ASSERT(Utils::IsAligned(address, 4)); 264 fixed_entries_.Add(ObjectPool::Entry(&obj));
267 // The address is stored in the object array as a RawSmi. 265 // The object isn't patchable. Record the index for fast lookup.
268 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address)); 266 object_index_table_.Insert(
269 return AddObject(smi, patchable); 267 ObjIndexPair(&obj, fixed_entries_.length() - 1));
268 return fixed_entries_.length() - 1;
270 } 269 }
271 270
272 271
273 intptr_t ObjectPool::FindObject(const Object& obj, Patchability patchable) { 272 intptr_t ObjectPoolHelper::AddFixedExternalLabel(const ExternalLabel* label) {
273 ASSERT(Isolate::Current() != Dart::vm_isolate());
274 uword value = label->address();
275 fixed_entries_.Add(ObjectPool::Entry(value));
276 ASSERT(fixed_entries_.length() <= Assembler::kNumFixedEntries);
277 untagged_index_table_.Insert(
278 UntaggedIndexPair(value, fixed_entries_.length() - 1));
279 return fixed_entries_.length() - 1;
280 }
281
282
283 intptr_t ObjectPoolHelper::AddUntagged(uword value, Patchability patchable) {
284 ASSERT(Isolate::Current() != Dart::vm_isolate());
285 untagged_entries_.Add(value);
286 intptr_t index =
287 Assembler::kNumFixedEntries + untagged_entries_.length() - 1;
288 if (patchable == kNotPatchable) {
289 // The entry isn't patchable. Record the index for fast lookup.
290 untagged_index_table_.Insert(UntaggedIndexPair(value, index));
291 }
292 return index;
293 }
294
295
296 intptr_t ObjectPoolHelper::AddExternalLabel(const ExternalLabel* label,
297 Patchability patchable) {
298 return AddUntagged(label->address(), patchable);
299 }
300
301
302 intptr_t ObjectPoolHelper::AddImmediate(uword imm) {
303 return AddUntagged(imm, kNotPatchable);
304 }
305
306
307 intptr_t ObjectPoolHelper::FindObject(const Object& obj) {
274 // The object pool cannot be used in the vm isolate. 308 // The object pool cannot be used in the vm isolate.
275 ASSERT(Isolate::Current() != Dart::vm_isolate()); 309 ASSERT(Isolate::Current() != Dart::vm_isolate());
310 // Check if we've already got it in the object pool.
311 intptr_t idx = object_index_table_.Lookup(&obj);
312 return (idx != ObjIndexPair::kNoIndex) ? idx : AddObject(obj);
313 }
276 314
277 // If the object is not patchable, check if we've already got it in the 315
278 // object pool. 316 intptr_t ObjectPoolHelper::FindUntagged(uword value, Patchability patchable) {
279 if (patchable == kNotPatchable && !object_pool_.IsNull()) { 317 // The object pool cannot be used in the vm isolate.
280 intptr_t idx = object_pool_index_table_.Lookup(&obj); 318 ASSERT(Isolate::Current() != Dart::vm_isolate());
281 if (idx != ObjIndexPair::kNoIndex) { 319 if (patchable == kNotPatchable) {
282 ASSERT(patchable_pool_entries_[idx] == kNotPatchable); 320 // Check if we've already got it in the object pool.
321 intptr_t idx = untagged_index_table_.Lookup(value);
322 if (idx != UntaggedIndexPair::kNoIndex) {
283 return idx; 323 return idx;
284 } 324 }
285 } 325 }
286 326 return AddUntagged(value, patchable);
287 return AddObject(obj, patchable);
288 } 327 }
289 328
290 329
291 intptr_t ObjectPool::FindExternalLabel(const ExternalLabel* label, 330 intptr_t ObjectPoolHelper::FindExternalLabel(const ExternalLabel* label,
292 Patchability patchable) { 331 Patchability patchable) {
293 // The object pool cannot be used in the vm isolate. 332 return FindUntagged(label->address(), patchable);
294 ASSERT(Isolate::Current() != Dart::vm_isolate());
295 const uword address = label->address();
296 ASSERT(Utils::IsAligned(address, 4));
297 // The address is stored in the object array as a RawSmi.
298 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address));
299 return FindObject(smi, patchable);
300 } 333 }
301 334
302 335
336 intptr_t ObjectPoolHelper::FindImmediate(uword imm) {
337 return FindUntagged(imm, kNotPatchable);
338 }
339
340
341 RawObjectPool* ObjectPoolHelper::MakeObjectPool() {
342 // Code in the VM isolate does not use object pool.
343 if (Isolate::Current() == Dart::vm_isolate()) {
344 return Object::empty_object_pool().raw();
345 }
346
347 intptr_t length =
348 Assembler::kNumFixedEntries +
349 tagged_entries_.length() +
350 untagged_entries_.length();
351 const ObjectPool& object_pool = ObjectPool::Handle(
352 ObjectPool::New(length, tagged_entries_.length()));
353 intptr_t i = 0;
354 for (; i < Assembler::kNumFixedObjectEntries; ++i) {
355 object_pool.SetObjectAt(i, *fixed_entries_[i].obj_);
356 }
357 for (; i < Assembler::kNumFixedEntries; ++i) {
358 object_pool.SetRawValueAt(i, fixed_entries_[i].raw_value_);
359 }
360 for (i = 0; i < tagged_entries_.length(); ++i) {
361 object_pool.SetObjectAt(Assembler::kNumFixedEntries + i,
362 *tagged_entries_[i]);
363 }
364 for (intptr_t j = 0; j < untagged_entries_.length(); ++j) {
365 object_pool.SetRawValueAt(Assembler::kNumFixedEntries + i + j,
366 untagged_entries_[j]);
367 }
368 return object_pool.raw();
369 }
370
371
372 void ObjectPoolIndexFixup::Process(const MemoryRegion& region,
373 intptr_t position,
374 Assembler* assembler) {
375 int32_t index = region.Load<int32_t>(position - sizeof(int32_t));
376 index += assembler->object_pool().UntaggedEntryStart() * kWordSize;
377 region.Store<int32_t>(position - sizeof(int32_t), index);
378 }
379
303 } // namespace dart 380 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/assembler.h ('k') | runtime/vm/assembler_x64.h » ('j') | runtime/vm/assembler_x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698