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

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

Issue 1314883002: VM: Use constant pool also for leaf runtime calls on x64, arm, arm64 and mips. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed non-simulated arm/mips build Created 5 years, 4 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_X64) 6 #if defined(TARGET_ARCH_X64)
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/heap.h" 10 #include "vm/heap.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. 74 { // Encode movq(TMP, Immediate(label->address())), but always as imm64.
75 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 75 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
76 EmitRegisterREX(TMP, REX_W); 76 EmitRegisterREX(TMP, REX_W);
77 EmitUint8(0xB8 | (TMP & 7)); 77 EmitUint8(0xB8 | (TMP & 7));
78 EmitInt64(label->address()); 78 EmitInt64(label->address());
79 } 79 }
80 call(TMP); 80 call(TMP);
81 } 81 }
82 82
83 83
84 void Assembler::CallPatchable(const ExternalLabel* label) { 84 void Assembler::CallPatchable(const StubEntry& stub_entry) {
85 ASSERT(constant_pool_allowed()); 85 ASSERT(constant_pool_allowed());
86 intptr_t call_start = buffer_.GetPosition(); 86 intptr_t call_start = buffer_.GetPosition();
87 const int32_t offset = ObjectPool::element_offset( 87 const int32_t offset = ObjectPool::element_offset(
88 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); 88 object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), kPatchable));
89 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); 89 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag));
90 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); 90 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize);
91 } 91 }
92 92
93 93
94 void Assembler::Call(const ExternalLabel* label) { 94 void Assembler::Call(const StubEntry& stub_entry) {
95 ASSERT(constant_pool_allowed()); 95 ASSERT(constant_pool_allowed());
96 const int32_t offset = ObjectPool::element_offset( 96 const int32_t offset = ObjectPool::element_offset(
97 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); 97 object_pool_wrapper_.FindExternalLabel(&stub_entry.label(),
98 kNotPatchable));
98 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); 99 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag));
99 } 100 }
100 101
101 102
102 void Assembler::CallPatchable(const StubEntry& stub_entry) {
103 const ExternalLabel label(stub_entry.EntryPoint());
104 CallPatchable(&label);
105 }
106
107
108 void Assembler::Call(const StubEntry& stub_entry) {
109 const ExternalLabel label(stub_entry.EntryPoint());
110 Call(&label);
111 }
112
113
114 void Assembler::pushq(Register reg) { 103 void Assembler::pushq(Register reg) {
115 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 104 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
116 EmitRegisterREX(reg, REX_NONE); 105 EmitRegisterREX(reg, REX_NONE);
117 EmitUint8(0x50 | (reg & 7)); 106 EmitUint8(0x50 | (reg & 7));
118 } 107 }
119 108
120 109
121 void Assembler::pushq(const Address& address) { 110 void Assembler::pushq(const Address& address) {
122 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 111 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
123 EmitOperandREX(6, address, REX_NONE); 112 EmitOperandREX(6, address, REX_NONE);
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 EmitUint8(0x70 + condition); 2526 EmitUint8(0x70 + condition);
2538 EmitNearLabelLink(label); 2527 EmitNearLabelLink(label);
2539 } else { 2528 } else {
2540 EmitUint8(0x0F); 2529 EmitUint8(0x0F);
2541 EmitUint8(0x80 + condition); 2530 EmitUint8(0x80 + condition);
2542 EmitLabelLink(label); 2531 EmitLabelLink(label);
2543 } 2532 }
2544 } 2533 }
2545 2534
2546 2535
2547 void Assembler::j(Condition condition, const ExternalLabel* label) {
2548 Label no_jump;
2549 // Negate condition.
2550 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump);
2551 jmp(label);
2552 Bind(&no_jump);
2553 }
2554
2555
2556 void Assembler::J(Condition condition, const ExternalLabel* label,
2557 Register pp) {
2558 Label no_jump;
2559 // Negate condition.
2560 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump);
2561 Jmp(label, pp);
2562 Bind(&no_jump);
2563 }
2564
2565
2566 void Assembler::J(Condition condition, const StubEntry& stub_entry, 2536 void Assembler::J(Condition condition, const StubEntry& stub_entry,
2567 Register pp) { 2537 Register pp) {
2568 const ExternalLabel label(stub_entry.EntryPoint()); 2538 Label no_jump;
2569 J(condition, &label, pp); 2539 // Negate condition.
2540 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump);
2541 Jmp(stub_entry, pp);
2542 Bind(&no_jump);
2570 } 2543 }
2571 2544
2572 2545
2573 void Assembler::jmp(Register reg) { 2546 void Assembler::jmp(Register reg) {
2574 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2547 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2575 Operand operand(reg); 2548 Operand operand(reg);
2576 EmitOperandREX(4, operand, REX_NONE); 2549 EmitOperandREX(4, operand, REX_NONE);
2577 EmitUint8(0xFF); 2550 EmitUint8(0xFF);
2578 EmitOperand(4, operand); 2551 EmitOperand(4, operand);
2579 } 2552 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 jmp(TMP); 2597 jmp(TMP);
2625 } 2598 }
2626 2599
2627 2600
2628 void Assembler::jmp(const StubEntry& stub_entry) { 2601 void Assembler::jmp(const StubEntry& stub_entry) {
2629 const ExternalLabel label(stub_entry.EntryPoint()); 2602 const ExternalLabel label(stub_entry.EntryPoint());
2630 jmp(&label); 2603 jmp(&label);
2631 } 2604 }
2632 2605
2633 2606
2634 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { 2607 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
2635 ASSERT((pp != PP) || constant_pool_allowed()); 2608 ASSERT((pp != PP) || constant_pool_allowed());
2636 intptr_t call_start = buffer_.GetPosition(); 2609 intptr_t call_start = buffer_.GetPosition();
2637 const int32_t offset = ObjectPool::element_offset( 2610 const int32_t offset = ObjectPool::element_offset(
2638 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); 2611 object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), kPatchable));
2639 // Patchable jumps always use a 32-bit immediate encoding. 2612 // Patchable jumps always use a 32-bit immediate encoding.
2640 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); 2613 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
2641 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); 2614 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes);
2642 } 2615 }
2643 2616
2644 2617
2645 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { 2618 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
2646 const ExternalLabel label(stub_entry.EntryPoint());
2647 JmpPatchable(&label, pp);
2648 }
2649
2650
2651 void Assembler::Jmp(const ExternalLabel* label, Register pp) {
2652 ASSERT((pp != PP) || constant_pool_allowed()); 2619 ASSERT((pp != PP) || constant_pool_allowed());
2653 const int32_t offset = ObjectPool::element_offset( 2620 const int32_t offset = ObjectPool::element_offset(
2654 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); 2621 object_pool_wrapper_.FindExternalLabel(&stub_entry.label(),
2622 kNotPatchable));
2655 jmp(Address(pp, offset - kHeapObjectTag)); 2623 jmp(Address(pp, offset - kHeapObjectTag));
2656 } 2624 }
2657 2625
2658 2626
2659 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
2660 const ExternalLabel label(stub_entry.EntryPoint());
2661 Jmp(&label, pp);
2662 }
2663
2664
2665 void Assembler::lock() { 2627 void Assembler::lock() {
2666 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2628 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2667 EmitUint8(0xF0); 2629 EmitUint8(0xF0);
2668 } 2630 }
2669 2631
2670 2632
2671 void Assembler::cmpxchgl(const Address& address, Register reg) { 2633 void Assembler::cmpxchgl(const Address& address, Register reg) {
2672 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2634 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2673 EmitOperandREX(reg, address, REX_NONE); 2635 EmitOperandREX(reg, address, REX_NONE);
2674 EmitUint8(0x0F); 2636 EmitUint8(0x0F);
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 offset += kFpuRegisterSize; 3311 offset += kFpuRegisterSize;
3350 } 3312 }
3351 } 3313 }
3352 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize)); 3314 ASSERT(offset == (xmm_regs_count * kFpuRegisterSize));
3353 AddImmediate(RSP, Immediate(offset)); 3315 AddImmediate(RSP, Immediate(offset));
3354 } 3316 }
3355 } 3317 }
3356 3318
3357 3319
3358 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) { 3320 void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
3359 EnterFrame(0); 3321 EnterStubFrame();
3360 3322
3361 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. 3323 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
3362 PushRegisters(CallingConventions::kVolatileCpuRegisters, 3324 PushRegisters(CallingConventions::kVolatileCpuRegisters,
3363 CallingConventions::kVolatileXmmRegisters); 3325 CallingConventions::kVolatileXmmRegisters);
3364 3326
3365 ReserveAlignedFrameSpace(frame_space); 3327 ReserveAlignedFrameSpace(frame_space);
3366 } 3328 }
3367 3329
3368 3330
3369 void Assembler::LeaveCallRuntimeFrame() { 3331 void Assembler::LeaveCallRuntimeFrame() {
3370 // RSP might have been modified to reserve space for arguments 3332 // RSP might have been modified to reserve space for arguments
3371 // and ensure proper alignment of the stack frame. 3333 // and ensure proper alignment of the stack frame.
3372 // We need to restore it before restoring registers. 3334 // We need to restore it before restoring registers.
3373 const intptr_t kPushedCpuRegistersCount = 3335 const intptr_t kPushedCpuRegistersCount =
3374 RegisterSet::RegisterCount(CallingConventions::kVolatileCpuRegisters); 3336 RegisterSet::RegisterCount(CallingConventions::kVolatileCpuRegisters);
3375 const intptr_t kPushedXmmRegistersCount = 3337 const intptr_t kPushedXmmRegistersCount =
3376 RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters); 3338 RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters);
3377 const intptr_t kPushedRegistersSize = 3339 const intptr_t kPushedRegistersSize =
3378 kPushedCpuRegistersCount * kWordSize + 3340 kPushedCpuRegistersCount * kWordSize +
3379 kPushedXmmRegistersCount * kFpuRegisterSize; 3341 kPushedXmmRegistersCount * kFpuRegisterSize +
3342 2 * kWordSize; // PP, pc marker from EnterStubFrame
3380 leaq(RSP, Address(RBP, -kPushedRegistersSize)); 3343 leaq(RSP, Address(RBP, -kPushedRegistersSize));
3381 3344
3382 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch. 3345 // TODO(vegorov): avoid saving FpuTMP, it is used only as scratch.
3383 PopRegisters(CallingConventions::kVolatileCpuRegisters, 3346 PopRegisters(CallingConventions::kVolatileCpuRegisters,
3384 CallingConventions::kVolatileXmmRegisters); 3347 CallingConventions::kVolatileXmmRegisters);
3385 3348
3386 leave(); 3349 LeaveStubFrame();
3387 } 3350 }
3388 3351
3389 3352
3390 void Assembler::CallCFunction(const ExternalLabel* label) {
3391 // Reserve shadow space for outgoing arguments.
3392 if (CallingConventions::kShadowSpaceBytes != 0) {
3393 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
3394 }
3395 call(label);
3396 }
3397
3398
3399 void Assembler::CallCFunction(Register reg) { 3353 void Assembler::CallCFunction(Register reg) {
3400 // Reserve shadow space for outgoing arguments. 3354 // Reserve shadow space for outgoing arguments.
3401 if (CallingConventions::kShadowSpaceBytes != 0) { 3355 if (CallingConventions::kShadowSpaceBytes != 0) {
3402 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes)); 3356 subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
3403 } 3357 }
3404 call(reg); 3358 call(reg);
3405 } 3359 }
3406 3360
3407 3361
3408 void Assembler::CallRuntime(const RuntimeEntry& entry, 3362 void Assembler::CallRuntime(const RuntimeEntry& entry,
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
3974 3928
3975 3929
3976 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3930 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3977 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3931 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3978 return xmm_reg_names[reg]; 3932 return xmm_reg_names[reg];
3979 } 3933 }
3980 3934
3981 } // namespace dart 3935 } // namespace dart
3982 3936
3983 #endif // defined TARGET_ARCH_X64 3937 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698