Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 26 matching lines...) Expand all Loading... | |
| 37 | 37 |
| 38 index = object_pool_wrapper_.AddObject(Bool::True()); | 38 index = object_pool_wrapper_.AddObject(Bool::True()); |
| 39 ASSERT(index == 1); | 39 ASSERT(index == 1); |
| 40 | 40 |
| 41 index = object_pool_wrapper_.AddObject(Bool::False()); | 41 index = object_pool_wrapper_.AddObject(Bool::False()); |
| 42 ASSERT(index == 2); | 42 ASSERT(index == 2); |
| 43 | 43 |
| 44 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); | 44 const Smi& vacant = Smi::Handle(Smi::New(0xfa >> kSmiTagShift)); |
| 45 StubCode* stub_code = isolate->stub_code(); | 45 StubCode* stub_code = isolate->stub_code(); |
| 46 if (stub_code->UpdateStoreBuffer_entry() != NULL) { | 46 if (stub_code->UpdateStoreBuffer_entry() != NULL) { |
| 47 object_pool_wrapper_.AddExternalLabel( | 47 object_pool_wrapper_.AddObject( |
| 48 &stub_code->UpdateStoreBufferLabel(), kNotPatchable); | 48 Code::Handle(stub_code->UpdateStoreBufferCode()), kNotPatchable); |
|
srdjan
2015/06/18 21:29:46
Code::Handle(isolate,
Florian Schneider
2015/06/29 14:50:24
Done.
| |
| 49 } else { | 49 } else { |
| 50 object_pool_wrapper_.AddObject(vacant); | 50 object_pool_wrapper_.AddObject(vacant); |
| 51 } | 51 } |
| 52 | 52 |
| 53 if (stub_code->CallToRuntime_entry() != NULL) { | 53 if (stub_code->CallToRuntime_entry() != NULL) { |
| 54 object_pool_wrapper_.AddExternalLabel( | 54 object_pool_wrapper_.AddObject( |
| 55 &stub_code->CallToRuntimeLabel(), kNotPatchable); | 55 Code::Handle(stub_code->CallToRuntimeCode()), kNotPatchable); |
|
srdjan
2015/06/18 21:29:46
Code::Handle(isolate,
Florian Schneider
2015/06/29 14:50:24
Done.
| |
| 56 } else { | 56 } else { |
| 57 object_pool_wrapper_.AddObject(vacant); | 57 object_pool_wrapper_.AddObject(vacant); |
| 58 } | 58 } |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { | 63 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) { |
| 64 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); | 64 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length); |
| 65 } | 65 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. | 104 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. |
| 105 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 105 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 106 EmitRegisterREX(TMP, REX_W); | 106 EmitRegisterREX(TMP, REX_W); |
| 107 EmitUint8(0xB8 | (TMP & 7)); | 107 EmitUint8(0xB8 | (TMP & 7)); |
| 108 EmitInt64(label->address()); | 108 EmitInt64(label->address()); |
| 109 } | 109 } |
| 110 call(TMP); | 110 call(TMP); |
| 111 } | 111 } |
| 112 | 112 |
| 113 | 113 |
| 114 void Assembler::CallPatchable(const ExternalLabel* label) { | 114 void Assembler::CallPatchable(const Code& target) { |
| 115 ASSERT(allow_constant_pool()); | 115 ASSERT(allow_constant_pool()); |
| 116 intptr_t call_start = buffer_.GetPosition(); | 116 intptr_t call_start = buffer_.GetPosition(); |
| 117 const int32_t offset = ObjectPool::element_offset( | 117 const int32_t offset = ObjectPool::element_offset( |
| 118 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 118 object_pool_wrapper_.FindObject(target, kPatchable)); |
| 119 call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); | 119 LoadWordFromPoolOffset(CODE_REG, PP, offset - kHeapObjectTag); |
| 120 movq(TMP, FieldAddress(CODE_REG, Code::instructions_offset())); | |
| 121 addq(TMP, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 122 call(TMP); | |
| 120 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); | 123 ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
| 121 } | 124 } |
| 122 | 125 |
| 123 | 126 |
| 124 void Assembler::Call(const ExternalLabel* label, Register pp) { | 127 void Assembler::Call(const Code& target, Register pp) { |
| 125 if (Isolate::Current() == Dart::vm_isolate()) { | 128 if (Isolate::Current() == Dart::vm_isolate()) { |
| 126 call(label); | 129 UNREACHABLE(); |
| 127 } else { | 130 } else { |
| 128 const int32_t offset = ObjectPool::element_offset( | 131 const int32_t offset = ObjectPool::element_offset( |
| 129 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); | 132 object_pool_wrapper_.FindObject(target, kNotPatchable)); |
| 130 call(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 133 LoadWordFromPoolOffset(CODE_REG, PP, offset - kHeapObjectTag); |
| 134 movq(TMP, FieldAddress(CODE_REG, Code::instructions_offset())); | |
| 135 addq(TMP, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 136 call(TMP); | |
| 131 } | 137 } |
| 132 } | 138 } |
| 133 | 139 |
| 134 | 140 |
| 135 void Assembler::pushq(Register reg) { | 141 void Assembler::pushq(Register reg) { |
| 136 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 142 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 137 EmitRegisterREX(reg, REX_NONE); | 143 EmitRegisterREX(reg, REX_NONE); |
| 138 EmitUint8(0x50 | (reg & 7)); | 144 EmitUint8(0x50 | (reg & 7)); |
| 139 } | 145 } |
| 140 | 146 |
| (...skipping 2409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2550 EmitUint8(0x70 + condition); | 2556 EmitUint8(0x70 + condition); |
| 2551 EmitNearLabelLink(label); | 2557 EmitNearLabelLink(label); |
| 2552 } else { | 2558 } else { |
| 2553 EmitUint8(0x0F); | 2559 EmitUint8(0x0F); |
| 2554 EmitUint8(0x80 + condition); | 2560 EmitUint8(0x80 + condition); |
| 2555 EmitLabelLink(label); | 2561 EmitLabelLink(label); |
| 2556 } | 2562 } |
| 2557 } | 2563 } |
| 2558 | 2564 |
| 2559 | 2565 |
| 2560 void Assembler::j(Condition condition, const ExternalLabel* label) { | |
| 2561 Label no_jump; | |
| 2562 // Negate condition. | |
| 2563 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump); | |
| 2564 jmp(label); | |
| 2565 Bind(&no_jump); | |
| 2566 } | |
| 2567 | |
| 2568 | |
| 2569 void Assembler::J(Condition condition, const ExternalLabel* label, | |
| 2570 Register pp) { | |
| 2571 Label no_jump; | |
| 2572 // Negate condition. | |
| 2573 j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump); | |
| 2574 Jmp(label, pp); | |
| 2575 Bind(&no_jump); | |
| 2576 } | |
| 2577 | |
| 2578 | |
| 2579 void Assembler::jmp(Register reg) { | 2566 void Assembler::jmp(Register reg) { |
| 2580 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2567 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2581 Operand operand(reg); | 2568 Operand operand(reg); |
| 2582 EmitOperandREX(4, operand, REX_NONE); | 2569 EmitOperandREX(4, operand, REX_NONE); |
| 2583 EmitUint8(0xFF); | 2570 EmitUint8(0xFF); |
| 2584 EmitOperand(4, operand); | 2571 EmitOperand(4, operand); |
| 2585 } | 2572 } |
| 2586 | 2573 |
| 2587 | 2574 |
| 2588 void Assembler::jmp(const Address& dst) { | 2575 void Assembler::jmp(const Address& dst) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2624 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. | 2611 { // Encode movq(TMP, Immediate(label->address())), but always as imm64. |
| 2625 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2612 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2626 EmitRegisterREX(TMP, REX_W); | 2613 EmitRegisterREX(TMP, REX_W); |
| 2627 EmitUint8(0xB8 | (TMP & 7)); | 2614 EmitUint8(0xB8 | (TMP & 7)); |
| 2628 EmitInt64(label->address()); | 2615 EmitInt64(label->address()); |
| 2629 } | 2616 } |
| 2630 jmp(TMP); | 2617 jmp(TMP); |
| 2631 } | 2618 } |
| 2632 | 2619 |
| 2633 | 2620 |
| 2634 void Assembler::JmpPatchable(const ExternalLabel* label, Register pp) { | 2621 void Assembler::JmpPatchable(const Code& target, Register pp) { |
| 2635 ASSERT(allow_constant_pool()); | 2622 ASSERT(allow_constant_pool()); |
| 2636 intptr_t call_start = buffer_.GetPosition(); | 2623 intptr_t call_start = buffer_.GetPosition(); |
| 2637 const int32_t offset = ObjectPool::element_offset( | 2624 const int32_t offset = ObjectPool::element_offset( |
| 2638 object_pool_wrapper_.FindExternalLabel(label, kPatchable)); | 2625 object_pool_wrapper_.FindObject(target, kPatchable)); |
| 2639 // Patchable jumps always use a 32-bit immediate encoding. | 2626 LoadWordFromPoolOffset(CODE_REG, pp, offset - kHeapObjectTag); |
| 2640 jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); | 2627 movq(TMP, FieldAddress(CODE_REG, Code::instructions_offset())); |
| 2628 addq(TMP, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 2629 jmp(TMP); | |
| 2641 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); | 2630 ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
| 2642 } | 2631 } |
| 2643 | 2632 |
| 2644 | 2633 |
| 2645 void Assembler::Jmp(const ExternalLabel* label, Register pp) { | 2634 void Assembler::Jmp(const Code& target, Register pp) { |
| 2646 const int32_t offset = ObjectPool::element_offset( | 2635 const int32_t offset = ObjectPool::element_offset( |
| 2647 object_pool_wrapper_.FindExternalLabel(label, kNotPatchable)); | 2636 object_pool_wrapper_.FindObject(target, kNotPatchable)); |
| 2648 jmp(Address(pp, offset - kHeapObjectTag)); | 2637 movq(CODE_REG, FieldAddress(pp, offset)); |
| 2638 movq(TMP, FieldAddress(CODE_REG, Code::instructions_offset())); | |
| 2639 addq(TMP, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 2640 jmp(TMP); | |
| 2649 } | 2641 } |
| 2650 | 2642 |
| 2651 | 2643 |
| 2644 void Assembler::J(Condition condition, | |
| 2645 const Code& target, | |
| 2646 Register pp) { | |
|
srdjan
2015/06/18 21:29:47
All arguments on one line
Florian Schneider
2015/06/29 14:50:24
Done.
| |
| 2647 Label no_jump; | |
| 2648 j(static_cast<Condition>(condition ^ 1), &no_jump); // Negate condition. | |
| 2649 Jmp(target, pp); | |
| 2650 Bind(&no_jump); | |
| 2651 } | |
| 2652 | |
| 2653 | |
| 2652 void Assembler::lock() { | 2654 void Assembler::lock() { |
| 2653 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2655 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2654 EmitUint8(0xF0); | 2656 EmitUint8(0xF0); |
| 2655 } | 2657 } |
| 2656 | 2658 |
| 2657 | 2659 |
| 2658 void Assembler::cmpxchgl(const Address& address, Register reg) { | 2660 void Assembler::cmpxchgl(const Address& address, Register reg) { |
| 2659 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2661 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 2660 EmitOperandREX(reg, address, REX_NONE); | 2662 EmitOperandREX(reg, address, REX_NONE); |
| 2661 EmitUint8(0x0F); | 2663 EmitUint8(0x0F); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3075 StoreIntoObjectFilter(object, value, &done); | 3077 StoreIntoObjectFilter(object, value, &done); |
| 3076 } else { | 3078 } else { |
| 3077 StoreIntoObjectFilterNoSmi(object, value, &done); | 3079 StoreIntoObjectFilterNoSmi(object, value, &done); |
| 3078 } | 3080 } |
| 3079 // A store buffer update is required. | 3081 // A store buffer update is required. |
| 3080 if (value != RDX) pushq(RDX); | 3082 if (value != RDX) pushq(RDX); |
| 3081 if (object != RDX) { | 3083 if (object != RDX) { |
| 3082 movq(RDX, object); | 3084 movq(RDX, object); |
| 3083 } | 3085 } |
| 3084 StubCode* stub_code = Isolate::Current()->stub_code(); | 3086 StubCode* stub_code = Isolate::Current()->stub_code(); |
| 3085 Call(&stub_code->UpdateStoreBufferLabel(), PP); | 3087 Call(Code::Handle(stub_code->UpdateStoreBufferCode()), PP); |
| 3086 if (value != RDX) popq(RDX); | 3088 if (value != RDX) popq(RDX); |
| 3087 Bind(&done); | 3089 Bind(&done); |
| 3088 } | 3090 } |
| 3089 | 3091 |
| 3090 | 3092 |
| 3091 void Assembler::StoreIntoObjectNoBarrier(Register object, | 3093 void Assembler::StoreIntoObjectNoBarrier(Register object, |
| 3092 const Address& dest, | 3094 const Address& dest, |
| 3093 Register value, | 3095 Register value, |
| 3094 FieldContent old_content) { | 3096 FieldContent old_content) { |
| 3095 VerifiedWrite(dest, value, old_content); | 3097 VerifiedWrite(dest, value, old_content); |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3385 call(reg); | 3387 call(reg); |
| 3386 } | 3388 } |
| 3387 | 3389 |
| 3388 | 3390 |
| 3389 void Assembler::CallRuntime(const RuntimeEntry& entry, | 3391 void Assembler::CallRuntime(const RuntimeEntry& entry, |
| 3390 intptr_t argument_count) { | 3392 intptr_t argument_count) { |
| 3391 entry.Call(this, argument_count); | 3393 entry.Call(this, argument_count); |
| 3392 } | 3394 } |
| 3393 | 3395 |
| 3394 | 3396 |
| 3397 void Assembler::RestoreCodePointer() { | |
| 3398 movq(CODE_REG, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); | |
| 3399 } | |
| 3400 | |
| 3401 | |
| 3395 void Assembler::LoadPoolPointer(Register pp) { | 3402 void Assembler::LoadPoolPointer(Register pp) { |
| 3396 // Load new pool pointer. | 3403 // Load new pool pointer. |
| 3397 const intptr_t kRIPRelativeMovqSize = 7; | 3404 CheckCodePointer(); |
| 3398 const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize; | 3405 movq(pp, FieldAddress(CODE_REG, Code::object_pool_offset())); |
| 3399 const intptr_t object_pool_pc_dist = | |
| 3400 Instructions::HeaderSize() - Instructions::object_pool_offset(); | |
| 3401 movq(pp, Address::AddressRIPRelative( | |
| 3402 -entry_to_rip_offset - object_pool_pc_dist)); | |
| 3403 ASSERT(CodeSize() == entry_to_rip_offset); | |
| 3404 } | 3406 } |
| 3405 | 3407 |
| 3406 | 3408 |
| 3407 void Assembler::EnterDartFrameWithInfo(intptr_t frame_size, | 3409 void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) { |
| 3408 Register new_pp, | 3410 CheckCodePointer(); |
| 3409 Register pc_marker_override) { | |
| 3410 EnterFrame(0); | 3411 EnterFrame(0); |
| 3411 pushq(pc_marker_override); | 3412 pushq(CODE_REG); |
| 3412 pushq(PP); | 3413 pushq(PP); |
| 3413 movq(PP, new_pp); | 3414 if (new_pp == kNoRegister) { |
| 3415 LoadPoolPointer(PP); | |
| 3416 } else { | |
| 3417 movq(PP, new_pp); | |
| 3418 } | |
| 3414 if (frame_size != 0) { | 3419 if (frame_size != 0) { |
| 3415 subq(RSP, Immediate(frame_size)); | 3420 subq(RSP, Immediate(frame_size)); |
| 3416 } | 3421 } |
| 3417 } | 3422 } |
| 3418 | 3423 |
| 3419 | 3424 |
| 3420 void Assembler::LeaveDartFrame() { | 3425 void Assembler::LeaveDartFrame(RestorePP restore_pp) { |
| 3421 // Restore caller's PP register that was pushed in EnterDartFrame. | 3426 // Restore caller's PP register that was pushed in EnterDartFrame. |
| 3422 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | 3427 if (restore_pp == kRestoreCallerPP) { |
| 3428 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | |
| 3429 } | |
| 3423 LeaveFrame(); | 3430 LeaveFrame(); |
| 3424 } | 3431 } |
| 3425 | 3432 |
| 3426 | 3433 |
| 3434 void Assembler::CheckCodePointer() { | |
| 3435 #ifdef DEBUG | |
| 3436 Label cid_ok, instructions_ok; | |
| 3437 pushq(RAX); | |
| 3438 LoadClassId(RAX, CODE_REG); | |
| 3439 cmpq(RAX, Immediate(kCodeCid)); | |
| 3440 j(EQUAL, &cid_ok); | |
| 3441 int3(); | |
| 3442 Bind(&cid_ok); | |
| 3443 { | |
| 3444 const intptr_t kRIPRelativeLeaqSize = 7; | |
| 3445 const intptr_t header_to_entry_offset = | |
| 3446 (Instructions::HeaderSize() - kHeapObjectTag); | |
| 3447 const intptr_t header_to_rip_offset = | |
| 3448 CodeSize() + kRIPRelativeLeaqSize + header_to_entry_offset; | |
| 3449 leaq(RAX, Address::AddressRIPRelative(-header_to_rip_offset)); | |
| 3450 ASSERT(CodeSize() == (header_to_rip_offset - header_to_entry_offset)); | |
| 3451 } | |
| 3452 cmpq(RAX, FieldAddress(CODE_REG, Code::instructions_offset())); | |
| 3453 j(EQUAL, &instructions_ok); | |
| 3454 int3(); | |
| 3455 Bind(&instructions_ok); | |
| 3456 popq(RAX); | |
| 3457 #endif | |
| 3458 } | |
| 3459 | |
| 3460 | |
| 3427 // On entry to a function compiled for OSR, the caller's frame pointer, the | 3461 // On entry to a function compiled for OSR, the caller's frame pointer, the |
| 3428 // stack locals, and any copied parameters are already in place. The frame | 3462 // stack locals, and any copied parameters are already in place. The frame |
| 3429 // pointer is already set up. The PC marker is not correct for the | 3463 // pointer is already set up. The PC marker is not correct for the |
| 3430 // optimized function and there may be extra space for spill slots to | 3464 // optimized function and there may be extra space for spill slots to |
| 3431 // allocate. | 3465 // allocate. |
| 3432 void Assembler::EnterOsrFrame(intptr_t extra_size, | 3466 void Assembler::EnterOsrFrame(intptr_t extra_size) { |
| 3433 Register new_pp, | |
| 3434 Register pc_marker_override) { | |
| 3435 if (prologue_offset_ == -1) { | 3467 if (prologue_offset_ == -1) { |
| 3436 Comment("PrologueOffset = %" Pd "", CodeSize()); | 3468 Comment("PrologueOffset = %" Pd "", CodeSize()); |
| 3437 prologue_offset_ = CodeSize(); | 3469 prologue_offset_ = CodeSize(); |
| 3438 } | 3470 } |
| 3439 movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override); | 3471 RestoreCodePointer(); |
| 3440 movq(PP, new_pp); | 3472 movq(PP, FieldAddress(CODE_REG, Code::object_pool_offset())); |
| 3473 | |
| 3474 CheckCodePointer(); | |
| 3441 if (extra_size != 0) { | 3475 if (extra_size != 0) { |
| 3442 subq(RSP, Immediate(extra_size)); | 3476 subq(RSP, Immediate(extra_size)); |
| 3443 } | 3477 } |
| 3444 } | 3478 } |
| 3445 | 3479 |
| 3446 | 3480 |
| 3447 void Assembler::EnterStubFrame() { | 3481 void Assembler::EnterStubFrame() { |
| 3482 CheckCodePointer(); | |
| 3448 EnterFrame(0); | 3483 EnterFrame(0); |
| 3449 pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. | 3484 pushq(CODE_REG); |
| 3450 pushq(PP); // Save caller's pool pointer | 3485 pushq(PP); // Save caller's pool pointer |
| 3451 LoadPoolPointer(PP); | 3486 LoadPoolPointer(PP); |
| 3452 } | 3487 } |
| 3453 | 3488 |
| 3454 | 3489 |
| 3455 void Assembler::LeaveStubFrame() { | 3490 void Assembler::LeaveStubFrame() { |
| 3456 // Restore caller's PP register that was pushed in EnterStubFrame. | 3491 // Restore caller's PP register that was pushed in EnterStubFrame. |
| 3457 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); | 3492 movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
| 3458 LeaveFrame(); | 3493 LeaveFrame(); |
| 3459 } | 3494 } |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3926 | 3961 |
| 3927 | 3962 |
| 3928 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3963 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3929 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3964 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
| 3930 return xmm_reg_names[reg]; | 3965 return xmm_reg_names[reg]; |
| 3931 } | 3966 } |
| 3932 | 3967 |
| 3933 } // namespace dart | 3968 } // namespace dart |
| 3934 | 3969 |
| 3935 #endif // defined TARGET_ARCH_X64 | 3970 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |