OLD | NEW |
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" |
(...skipping 17 matching lines...) Expand all Loading... |
28 Assembler::Assembler(bool use_far_branches) | 28 Assembler::Assembler(bool use_far_branches) |
29 : buffer_(), | 29 : buffer_(), |
30 prologue_offset_(-1), | 30 prologue_offset_(-1), |
31 use_far_branches_(use_far_branches), | 31 use_far_branches_(use_far_branches), |
32 comments_(), | 32 comments_(), |
33 allow_constant_pool_(true) { | 33 allow_constant_pool_(true) { |
34 if (Isolate::Current() != Dart::vm_isolate()) { | 34 if (Isolate::Current() != Dart::vm_isolate()) { |
35 // 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 |
36 // at the same index. | 36 // at the same index. |
37 intptr_t index = | 37 intptr_t index = |
38 object_pool_.AddObject(Object::null_object(), kNotPatchable); | 38 object_pool_.AddObject(Object::null_object()); |
39 ASSERT(index == 0); | 39 ASSERT(index == 0); |
40 | 40 |
41 index = object_pool_.AddObject(Bool::True(), kNotPatchable); | 41 index = object_pool_.AddObject(Bool::True()); |
42 ASSERT(index == 1); | 42 ASSERT(index == 1); |
43 | 43 |
44 index = object_pool_.AddObject(Bool::False(), kNotPatchable); | 44 index = object_pool_.AddObject(Bool::False()); |
45 ASSERT(index == 2); | 45 ASSERT(index == 2); |
46 | 46 |
47 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); | 47 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); |
48 StubCode* stub_code = Isolate::Current()->stub_code(); | 48 StubCode* stub_code = Isolate::Current()->stub_code(); |
49 if (stub_code->UpdateStoreBuffer_entry() != NULL) { | 49 if (stub_code->UpdateStoreBuffer_entry() != NULL) { |
50 object_pool_.AddExternalLabel( | 50 object_pool_.AddExternalLabel( |
51 &stub_code->UpdateStoreBufferLabel(), kNotPatchable); | 51 &stub_code->UpdateStoreBufferLabel(), kNotPatchable); |
52 } else { | 52 } else { |
53 object_pool_.AddObject(vacant, kNotPatchable); | 53 object_pool_.AddObject(vacant); |
54 } | 54 } |
55 | 55 |
56 if (stub_code->CallToRuntime_entry() != NULL) { | 56 if (stub_code->CallToRuntime_entry() != NULL) { |
57 object_pool_.AddExternalLabel( | 57 object_pool_.AddExternalLabel( |
58 &stub_code->CallToRuntimeLabel(), kNotPatchable); | 58 &stub_code->CallToRuntimeLabel(), kNotPatchable); |
59 } else { | 59 } else { |
60 object_pool_.AddObject(vacant, kNotPatchable); | 60 object_pool_.AddObject(vacant); |
61 } | 61 } |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 | 65 |
66 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 66 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
67 ASSERT(Utils::IsAligned(data, 4)); | 67 ASSERT(Utils::IsAligned(data, 4)); |
68 ASSERT(Utils::IsAligned(length, 4)); | 68 ASSERT(Utils::IsAligned(length, 4)); |
69 const uword end = data + length; | 69 const uword end = data + length; |
70 while (data < end) { | 70 while (data < end) { |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 Operand::CanHold(upper20, kXRegSizeInBits, &op); | 383 Operand::CanHold(upper20, kXRegSizeInBits, &op); |
384 ASSERT(ot == Operand::Immediate); | 384 ASSERT(ot == Operand::Immediate); |
385 ASSERT(Address::CanHoldOffset(lower12)); | 385 ASSERT(Address::CanHoldOffset(lower12)); |
386 add(dst, pp, op); | 386 add(dst, pp, op); |
387 ldr(dst, Address(dst, lower12)); | 387 ldr(dst, Address(dst, lower12)); |
388 } | 388 } |
389 | 389 |
390 | 390 |
391 intptr_t Assembler::FindImmediate(int64_t imm) { | 391 intptr_t Assembler::FindImmediate(int64_t imm) { |
392 ASSERT(Isolate::Current() != Dart::vm_isolate()); | 392 ASSERT(Isolate::Current() != Dart::vm_isolate()); |
393 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(imm)); | 393 return object_pool_.FindImmediate(imm); |
394 return object_pool_.FindObject(smi, kNotPatchable); | |
395 } | 394 } |
396 | 395 |
397 | 396 |
398 // A set of VM objects that are present in every constant pool. | 397 // A set of VM objects that are present in every constant pool. |
399 static bool IsAlwaysInConstantPool(const Object& object) { | 398 static bool IsAlwaysInConstantPool(const Object& object) { |
400 // TODO(zra): Evaluate putting all VM heap objects into the pool. | 399 // TODO(zra): Evaluate putting all VM heap objects into the pool. |
401 return (object.raw() == Object::null()) | 400 return (object.raw() == Object::null()) |
402 || (object.raw() == Bool::True().raw()) | 401 || (object.raw() == Bool::True().raw()) |
403 || (object.raw() == Bool::False().raw()); | 402 || (object.raw() == Bool::False().raw()); |
404 } | 403 } |
(...skipping 29 matching lines...) Expand all Loading... |
434 (Isolate::Current() != Dart::vm_isolate()); | 433 (Isolate::Current() != Dart::vm_isolate()); |
435 } | 434 } |
436 | 435 |
437 | 436 |
438 void Assembler::LoadExternalLabel(Register dst, | 437 void Assembler::LoadExternalLabel(Register dst, |
439 const ExternalLabel* label, | 438 const ExternalLabel* label, |
440 Patchability patchable, | 439 Patchability patchable, |
441 Register pp) { | 440 Register pp) { |
442 const int64_t target = static_cast<int64_t>(label->address()); | 441 const int64_t target = static_cast<int64_t>(label->address()); |
443 if (CanLoadImmediateFromPool(target, pp)) { | 442 if (CanLoadImmediateFromPool(target, pp)) { |
444 const int32_t offset = | 443 const int32_t offset = ObjectPool::element_offset( |
445 Array::element_offset(object_pool_.FindExternalLabel(label, patchable)); | 444 object_pool_.FindExternalLabel(label, patchable)); |
446 LoadWordFromPoolOffset(dst, pp, offset); | 445 LoadWordFromPoolOffset(dst, pp, offset); |
447 } else { | 446 } else { |
448 LoadImmediate(dst, target, kNoPP); | 447 LoadImmediate(dst, target, kNoPP); |
449 } | 448 } |
450 } | 449 } |
451 | 450 |
452 | 451 |
453 void Assembler::LoadExternalLabelFixed(Register dst, | 452 void Assembler::LoadExternalLabelFixed(Register dst, |
454 const ExternalLabel* label, | 453 const ExternalLabel* label, |
455 Patchability patchable, | 454 Patchability patchable, |
456 Register pp) { | 455 Register pp) { |
457 const int32_t offset = | 456 const int32_t offset = ObjectPool::element_offset( |
458 Array::element_offset(object_pool_.FindExternalLabel(label, patchable)); | 457 object_pool_.FindExternalLabel(label, patchable)); |
459 LoadWordFromPoolOffsetFixed(dst, pp, offset); | 458 LoadWordFromPoolOffsetFixed(dst, pp, offset); |
460 } | 459 } |
461 | 460 |
462 | 461 |
463 void Assembler::LoadIsolate(Register dst, Register pp) { | 462 void Assembler::LoadIsolate(Register dst, Register pp) { |
464 ldr(dst, Address(THR, Thread::isolate_offset())); | 463 ldr(dst, Address(THR, Thread::isolate_offset())); |
465 } | 464 } |
466 | 465 |
467 | 466 |
468 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { | 467 void Assembler::LoadObject(Register dst, const Object& object, Register pp) { |
469 if (CanLoadObjectFromPool(object)) { | 468 if (CanLoadObjectFromPool(object)) { |
470 const int32_t offset = | 469 const int32_t offset = |
471 Array::element_offset(object_pool_.FindObject(object, kNotPatchable)); | 470 ObjectPool::element_offset(object_pool_.FindObject(object)); |
472 LoadWordFromPoolOffset(dst, pp, offset); | 471 LoadWordFromPoolOffset(dst, pp, offset); |
473 } else { | 472 } else { |
474 ASSERT((Isolate::Current() == Dart::vm_isolate()) || | 473 ASSERT((Isolate::Current() == Dart::vm_isolate()) || |
475 object.IsSmi() || | 474 object.IsSmi() || |
476 object.InVMHeap()); | 475 object.InVMHeap()); |
477 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp); | 476 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw()), pp); |
478 } | 477 } |
479 } | 478 } |
480 | 479 |
481 | 480 |
482 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { | 481 void Assembler::CompareObject(Register reg, const Object& object, Register pp) { |
483 if (CanLoadObjectFromPool(object)) { | 482 if (CanLoadObjectFromPool(object)) { |
484 LoadObject(TMP, object, pp); | 483 LoadObject(TMP, object, pp); |
485 CompareRegisters(reg, TMP); | 484 CompareRegisters(reg, TMP); |
486 } else { | 485 } else { |
487 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); | 486 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()), pp); |
488 } | 487 } |
489 } | 488 } |
490 | 489 |
491 | 490 |
492 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { | 491 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm, Register pp) { |
493 if ((pp != kNoPP) && | 492 if ((pp != kNoPP) && |
494 (Isolate::Current() != Dart::vm_isolate()) && | 493 (Isolate::Current() != Dart::vm_isolate()) && |
495 allow_constant_pool()) { | 494 allow_constant_pool()) { |
496 int64_t val_smi_tag = imm & kSmiTagMask; | 495 int64_t val_smi_tag = imm & kSmiTagMask; |
497 imm &= ~kSmiTagMask; // Mask off the tag bits. | 496 imm &= ~kSmiTagMask; // Mask off the tag bits. |
498 const int32_t offset = Array::element_offset(FindImmediate(imm)); | 497 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); |
499 LoadWordFromPoolOffset(reg, pp, offset); | 498 LoadWordFromPoolOffset(reg, pp, offset); |
500 if (val_smi_tag != 0) { | 499 if (val_smi_tag != 0) { |
501 // Add back the tag bits. | 500 // Add back the tag bits. |
502 orri(reg, reg, Immediate(val_smi_tag)); | 501 orri(reg, reg, Immediate(val_smi_tag)); |
503 } | 502 } |
504 } else { | 503 } else { |
505 // TODO(zra): Since this sequence only needs to be decodable, it can be | 504 // TODO(zra): Since this sequence only needs to be decodable, it can be |
506 // of variable length. | 505 // of variable length. |
507 LoadImmediateFixed(reg, imm); | 506 LoadImmediateFixed(reg, imm); |
508 } | 507 } |
(...skipping 15 matching lines...) Expand all Loading... |
524 | 523 |
525 | 524 |
526 void Assembler::LoadImmediate(Register reg, int64_t imm, Register pp) { | 525 void Assembler::LoadImmediate(Register reg, int64_t imm, Register pp) { |
527 Comment("LoadImmediate"); | 526 Comment("LoadImmediate"); |
528 if (CanLoadImmediateFromPool(imm, pp)) { | 527 if (CanLoadImmediateFromPool(imm, pp)) { |
529 // It's a 64-bit constant and we're not in the VM isolate, so load from | 528 // It's a 64-bit constant and we're not in the VM isolate, so load from |
530 // object pool. | 529 // object pool. |
531 // Save the bits that must be masked-off for the SmiTag | 530 // Save the bits that must be masked-off for the SmiTag |
532 int64_t val_smi_tag = imm & kSmiTagMask; | 531 int64_t val_smi_tag = imm & kSmiTagMask; |
533 imm &= ~kSmiTagMask; // Mask off the tag bits. | 532 imm &= ~kSmiTagMask; // Mask off the tag bits. |
534 const int32_t offset = Array::element_offset(FindImmediate(imm)); | 533 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); |
535 LoadWordFromPoolOffset(reg, pp, offset); | 534 LoadWordFromPoolOffset(reg, pp, offset); |
536 if (val_smi_tag != 0) { | 535 if (val_smi_tag != 0) { |
537 // Add back the tag bits. | 536 // Add back the tag bits. |
538 orri(reg, reg, Immediate(val_smi_tag)); | 537 orri(reg, reg, Immediate(val_smi_tag)); |
539 } | 538 } |
540 } else { | 539 } else { |
541 // 0. Is it 0? | 540 // 0. Is it 0? |
542 if (imm == 0) { | 541 if (imm == 0) { |
543 movz(reg, Immediate(0), 0); | 542 movz(reg, Immediate(0), 0); |
544 return; | 543 return; |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 add(base, array, Operand(index, LSL, shift)); | 1461 add(base, array, Operand(index, LSL, shift)); |
1463 } | 1462 } |
1464 const OperandSize size = Address::OperandSizeFor(cid); | 1463 const OperandSize size = Address::OperandSizeFor(cid); |
1465 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1464 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1466 return Address(base, offset, Address::Offset, size); | 1465 return Address(base, offset, Address::Offset, size); |
1467 } | 1466 } |
1468 | 1467 |
1469 } // namespace dart | 1468 } // namespace dart |
1470 | 1469 |
1471 #endif // defined TARGET_ARCH_ARM64 | 1470 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |