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

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

Issue 886173003: VM: Align implementations of assembler constant pools. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
11 #include "vm/runtime_entry.h" 11 #include "vm/runtime_entry.h"
12 #include "vm/simulator.h" 12 #include "vm/simulator.h"
13 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
14 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
15 15
16 // An extra check since we are assuming the existence of /proc/cpuinfo below. 16 // An extra check since we are assuming the existence of /proc/cpuinfo below.
17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID)
18 #error ARM64 cross-compile only supported on Linux 18 #error ARM64 cross-compile only supported on Linux
19 #endif 19 #endif
20 20
21 namespace dart { 21 namespace dart {
22 22
23 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); 23 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
24 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); 24 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
25 DECLARE_FLAG(bool, inline_alloc); 25 DECLARE_FLAG(bool, inline_alloc);
26 26
27 27
28 Assembler::Assembler(bool use_far_branches) 28 Assembler::Assembler(bool use_far_branches)
29 : buffer_(), 29 : buffer_(),
30 object_pool_(GrowableObjectArray::Handle()),
31 patchable_pool_entries_(),
32 prologue_offset_(-1), 30 prologue_offset_(-1),
33 use_far_branches_(use_far_branches), 31 use_far_branches_(use_far_branches),
34 comments_(), 32 comments_(),
35 allow_constant_pool_(true) { 33 allow_constant_pool_(true) {
36 if (Isolate::Current() != Dart::vm_isolate()) { 34 if (Isolate::Current() != Dart::vm_isolate()) {
37 object_pool_ = GrowableObjectArray::New(Heap::kOld);
38
39 // These objects and labels need to be accessible through every pool-pointer 35 // These objects and labels need to be accessible through every pool-pointer
40 // at the same index. 36 // at the same index.
41 object_pool_.Add(Object::null_object(), Heap::kOld); 37 intptr_t index =
42 patchable_pool_entries_.Add(kNotPatchable); 38 object_pool_.AddObject(Object::null_object(), kNotPatchable);
43 object_pool_index_table_.Insert(ObjIndexPair(&Object::null_object(), 0)); 39 ASSERT(index == 0);
44 40
45 object_pool_.Add(Bool::True(), Heap::kOld); 41 index = object_pool_.AddObject(Bool::True(), kNotPatchable);
46 patchable_pool_entries_.Add(kNotPatchable); 42 ASSERT(index == 1);
47 object_pool_index_table_.Insert(ObjIndexPair(&Bool::True(), 1));
48 43
49 object_pool_.Add(Bool::False(), Heap::kOld); 44 index = object_pool_.AddObject(Bool::False(), kNotPatchable);
50 patchable_pool_entries_.Add(kNotPatchable); 45 ASSERT(index == 2);
51 object_pool_index_table_.Insert(ObjIndexPair(&Bool::False(), 2));
52 46
53 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); 47 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift));
54 StubCode* stub_code = Isolate::Current()->stub_code(); 48 StubCode* stub_code = Isolate::Current()->stub_code();
55
56 if (stub_code->UpdateStoreBuffer_entry() != NULL) { 49 if (stub_code->UpdateStoreBuffer_entry() != NULL) {
57 FindExternalLabel(&stub_code->UpdateStoreBufferLabel(), kNotPatchable); 50 object_pool_.AddExternalLabel(
51 &stub_code->UpdateStoreBufferLabel(), kNotPatchable);
58 } else { 52 } else {
59 object_pool_.Add(vacant, Heap::kOld); 53 object_pool_.AddObject(vacant, kNotPatchable);
60 patchable_pool_entries_.Add(kNotPatchable);
61 } 54 }
62 55
63 if (stub_code->CallToRuntime_entry() != NULL) { 56 if (stub_code->CallToRuntime_entry() != NULL) {
64 FindExternalLabel(&stub_code->CallToRuntimeLabel(), kNotPatchable); 57 object_pool_.AddExternalLabel(
58 &stub_code->CallToRuntimeLabel(), kNotPatchable);
65 } else { 59 } else {
66 object_pool_.Add(vacant, Heap::kOld); 60 object_pool_.AddObject(vacant, kNotPatchable);
67 patchable_pool_entries_.Add(kNotPatchable);
68 } 61 }
69 62
70 // Create fixed object pool entries for debugger stubs. 63 // Create fixed object pool entries for debugger stubs.
71 if (stub_code->ICCallBreakpoint_entry() != NULL) { 64 if (stub_code->ICCallBreakpoint_entry() != NULL) {
72 intptr_t index = 65 intptr_t index =
73 FindExternalLabel(&stub_code->ICCallBreakpointLabel(), 66 object_pool_.AddExternalLabel(&stub_code->ICCallBreakpointLabel(),
74 kNotPatchable); 67 kNotPatchable);
75 ASSERT(index == kICCallBreakpointCPIndex); 68 ASSERT(index == kICCallBreakpointCPIndex);
76 } else { 69 } else {
77 object_pool_.Add(vacant, Heap::kOld); 70 object_pool_.AddObject(vacant, kNotPatchable);
78 patchable_pool_entries_.Add(kNotPatchable);
79 } 71 }
80 if (stub_code->ClosureCallBreakpoint_entry() != NULL) { 72 if (stub_code->ClosureCallBreakpoint_entry() != NULL) {
81 intptr_t index = 73 intptr_t index = object_pool_.AddExternalLabel(
82 FindExternalLabel(&stub_code->ClosureCallBreakpointLabel(), 74 &stub_code->ClosureCallBreakpointLabel(), kNotPatchable);
83 kNotPatchable);
84 ASSERT(index == kClosureCallBreakpointCPIndex); 75 ASSERT(index == kClosureCallBreakpointCPIndex);
85 } else { 76 } else {
86 object_pool_.Add(vacant, Heap::kOld); 77 object_pool_.AddObject(vacant, kNotPatchable);
87 patchable_pool_entries_.Add(kNotPatchable);
88 } 78 }
89 if (stub_code->RuntimeCallBreakpoint_entry() != NULL) { 79 if (stub_code->RuntimeCallBreakpoint_entry() != NULL) {
90 intptr_t index = 80 intptr_t index = object_pool_.AddExternalLabel(
91 FindExternalLabel(&stub_code->RuntimeCallBreakpointLabel(), 81 &stub_code->RuntimeCallBreakpointLabel(), kNotPatchable);
92 kNotPatchable);
93 ASSERT(index == kRuntimeCallBreakpointCPIndex); 82 ASSERT(index == kRuntimeCallBreakpointCPIndex);
94 } else { 83 } else {
95 object_pool_.Add(vacant, Heap::kOld); 84 object_pool_.AddObject(vacant, kNotPatchable);
96 patchable_pool_entries_.Add(kNotPatchable);
97 } 85 }
98 } 86 }
99 } 87 }
100 88
101 89
102 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { 90 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
103 ASSERT(Utils::IsAligned(data, 4)); 91 ASSERT(Utils::IsAligned(data, 4));
104 ASSERT(Utils::IsAligned(length, 4)); 92 ASSERT(Utils::IsAligned(length, 4));
105 const uword end = data + length; 93 const uword end = data + length;
106 while (data < end) { 94 while (data < end) {
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 const uint32_t lower12 = offset & 0x00000fff; 405 const uint32_t lower12 = offset & 0x00000fff;
418 const Operand::OperandType ot = 406 const Operand::OperandType ot =
419 Operand::CanHold(upper20, kXRegSizeInBits, &op); 407 Operand::CanHold(upper20, kXRegSizeInBits, &op);
420 ASSERT(ot == Operand::Immediate); 408 ASSERT(ot == Operand::Immediate);
421 ASSERT(Address::CanHoldOffset(lower12)); 409 ASSERT(Address::CanHoldOffset(lower12));
422 add(dst, pp, op); 410 add(dst, pp, op);
423 ldr(dst, Address(dst, lower12)); 411 ldr(dst, Address(dst, lower12));
424 } 412 }
425 413
426 414
427 intptr_t Assembler::FindExternalLabel(const ExternalLabel* label,
428 Patchability patchable) {
429 // The object pool cannot be used in the vm isolate.
430 ASSERT(Isolate::Current() != Dart::vm_isolate());
431 ASSERT(!object_pool_.IsNull());
432 const uword address = label->address();
433 ASSERT(Utils::IsAligned(address, 4));
434 // The address is stored in the object array as a RawSmi.
435 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(address));
436 if (patchable == kNotPatchable) {
437 // If the call site is not patchable, we can try to re-use an existing
438 // entry.
439 return FindObject(smi, kNotPatchable);
440 }
441 // If the call is patchable, do not reuse an existing entry since each
442 // reference may be patched independently.
443 object_pool_.Add(smi, Heap::kOld);
444 patchable_pool_entries_.Add(patchable);
445 return object_pool_.Length() - 1;
446 }
447
448
449 intptr_t Assembler::FindObject(const Object& obj, Patchability patchable) {
450 // The object pool cannot be used in the vm isolate.
451 ASSERT(Isolate::Current() != Dart::vm_isolate());
452 ASSERT(!object_pool_.IsNull());
453
454 // If the object is not patchable, check if we've already got it in the
455 // object pool.
456 if (patchable == kNotPatchable) {
457 intptr_t idx = object_pool_index_table_.Lookup(&obj);
458 if (idx != ObjIndexPair::kNoIndex) {
459 ASSERT(patchable_pool_entries_[idx] == kNotPatchable);
460 return idx;
461 }
462 }
463
464 object_pool_.Add(obj, Heap::kOld);
465 patchable_pool_entries_.Add(patchable);
466 if (patchable == kNotPatchable) {
467 // The object isn't patchable. Record the index for fast lookup.
468 object_pool_index_table_.Insert(
469 ObjIndexPair(&obj, object_pool_.Length() - 1));
470 }
471 return object_pool_.Length() - 1;
472 }
473
474
475 intptr_t Assembler::FindImmediate(int64_t imm) { 415 intptr_t Assembler::FindImmediate(int64_t imm) {
476 ASSERT(Isolate::Current() != Dart::vm_isolate()); 416 ASSERT(Isolate::Current() != Dart::vm_isolate());
477 ASSERT(!object_pool_.IsNull());
478 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); 417 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm));
479 return FindObject(smi, kNotPatchable); 418 return object_pool_.FindObject(smi, kNotPatchable);
480 } 419 }
481 420
482 421
483 // A set of VM objects that are present in every constant pool. 422 // A set of VM objects that are present in every constant pool.
484 static bool IsAlwaysInConstantPool(const Object& object) { 423 static bool IsAlwaysInConstantPool(const Object& object) {
485 // TODO(zra): Evaluate putting all VM heap objects into the pool. 424 // TODO(zra): Evaluate putting all VM heap objects into the pool.
486 return (object.raw() == Object::null()) 425 return (object.raw() == Object::null())
487 || (object.raw() == Bool::True().raw()) 426 || (object.raw() == Bool::True().raw())
488 || (object.raw() == Bool::False().raw()); 427 || (object.raw() == Bool::False().raw());
489 } 428 }
(...skipping 30 matching lines...) Expand all
520 } 459 }
521 460
522 461
523 void Assembler::LoadExternalLabel(Register dst, 462 void Assembler::LoadExternalLabel(Register dst,
524 const ExternalLabel* label, 463 const ExternalLabel* label,
525 Patchability patchable, 464 Patchability patchable,
526 Register pp) { 465 Register pp) {
527 const int64_t target = static_cast<int64_t>(label->address()); 466 const int64_t target = static_cast<int64_t>(label->address());
528 if (CanLoadImmediateFromPool(target, pp)) { 467 if (CanLoadImmediateFromPool(target, pp)) {
529 const int32_t offset = 468 const int32_t offset =
530 Array::element_offset(FindExternalLabel(label, patchable)); 469 Array::element_offset(object_pool_.FindExternalLabel(label, patchable));
531 LoadWordFromPoolOffset(dst, pp, offset); 470 LoadWordFromPoolOffset(dst, pp, offset);
532 } else { 471 } else {
533 LoadImmediate(dst, target, kNoPP); 472 LoadImmediate(dst, target, kNoPP);
534 } 473 }
535 } 474 }
536 475
537 476
538 void Assembler::LoadExternalLabelFixed(Register dst, 477 void Assembler::LoadExternalLabelFixed(Register dst,
539 const ExternalLabel* label, 478 const ExternalLabel* label,
540 Patchability patchable, 479 Patchability patchable,
541 Register pp) { 480 Register pp) {
542 const int32_t offset = 481 const int32_t offset =
543 Array::element_offset(FindExternalLabel(label, patchable)); 482 Array::element_offset(object_pool_.FindExternalLabel(label, patchable));
544 LoadWordFromPoolOffsetFixed(dst, pp, offset); 483 LoadWordFromPoolOffsetFixed(dst, pp, offset);
545 } 484 }
546 485
547 486
548 void Assembler::LoadIsolate(Register dst, Register pp) { 487 void Assembler::LoadIsolate(Register dst, Register pp) {
549 LoadImmediate(dst, reinterpret_cast<uword>(Isolate::Current()), pp); 488 LoadImmediate(dst, reinterpret_cast<uword>(Isolate::Current()), pp);
550 } 489 }
551 490
552 491
553 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { 492 void Assembler::LoadObject(Register dst, const Object& object, Register pp) {
554 if (CanLoadObjectFromPool(object)) { 493 if (CanLoadObjectFromPool(object)) {
555 const int32_t offset = 494 const int32_t offset =
556 Array::element_offset(FindObject(object, kNotPatchable)); 495 Array::element_offset(object_pool_.FindObject(object, kNotPatchable));
557 LoadWordFromPoolOffset(dst, pp, offset); 496 LoadWordFromPoolOffset(dst, pp, offset);
558 } else { 497 } else {
559 ASSERT((Isolate::Current() == Dart::vm_isolate()) || 498 ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
560 object.IsSmi() || 499 object.IsSmi() ||
561 object.InVMHeap()); 500 object.InVMHeap());
562 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp); 501 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp);
563 } 502 }
564 } 503 }
565 504
566 505
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 add(base, array, Operand(index, LSL, shift)); 1485 add(base, array, Operand(index, LSL, shift));
1547 } 1486 }
1548 const OperandSize size = Address::OperandSizeFor(cid); 1487 const OperandSize size = Address::OperandSizeFor(cid);
1549 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); 1488 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
1550 return Address(base, offset, Address::Offset, size); 1489 return Address(base, offset, Address::Offset, size);
1551 } 1490 }
1552 1491
1553 } // namespace dart 1492 } // namespace dart
1554 1493
1555 #endif // defined TARGET_ARCH_ARM64 1494 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698