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" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 __ leaq(RAX, Address(RBP, (kParamEndSlotFromFp + | 776 __ leaq(RAX, Address(RBP, (kParamEndSlotFromFp + |
777 function().NumParameters()) * kWordSize)); | 777 function().NumParameters()) * kWordSize)); |
778 } else { | 778 } else { |
779 __ leaq(RAX, | 779 __ leaq(RAX, |
780 Address(RBP, kFirstLocalSlotFromFp * kWordSize)); | 780 Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
781 } | 781 } |
782 __ LoadImmediate( | 782 __ LoadImmediate( |
783 RBX, Immediate(reinterpret_cast<uword>(native_c_function())), PP); | 783 RBX, Immediate(reinterpret_cast<uword>(native_c_function())), PP); |
784 __ LoadImmediate( | 784 __ LoadImmediate( |
785 R10, Immediate(argc_tag), PP); | 785 R10, Immediate(argc_tag), PP); |
786 const ExternalLabel* stub_entry = (is_bootstrap_native() || is_leaf_call) ? | 786 const Code& stub = Code::Handle((is_bootstrap_native() || is_leaf_call) ? |
787 &stub_code->CallBootstrapCFunctionLabel() : | 787 stub_code->CallBootstrapCFunctionCode() : |
788 &stub_code->CallNativeCFunctionLabel(); | 788 stub_code->CallNativeCFunctionCode()); |
789 compiler->GenerateCall(token_pos(), | 789 compiler->GenerateCall(token_pos(), |
790 stub_entry, | 790 stub, |
791 RawPcDescriptors::kOther, | 791 RawPcDescriptors::kOther, |
792 locs()); | 792 locs()); |
793 __ popq(result); | 793 __ popq(result); |
794 } | 794 } |
795 | 795 |
796 | 796 |
797 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { | 797 static bool CanBeImmediateIndex(Value* index, intptr_t cid) { |
798 if (!index->definition()->IsConstant()) return false; | 798 if (!index->definition()->IsConstant()) return false; |
799 const Object& constant = index->definition()->AsConstant()->value(); | 799 const Object& constant = index->definition()->AsConstant()->value(); |
800 if (!constant.IsSmi()) return false; | 800 if (!constant.IsSmi()) return false; |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 StubCode* stub_code = isolate->stub_code(); | 1660 StubCode* stub_code = isolate->stub_code(); |
1661 | 1661 |
1662 if (Assembler::EmittingComments()) { | 1662 if (Assembler::EmittingComments()) { |
1663 __ Comment("%s slow path allocation of %s", | 1663 __ Comment("%s slow path allocation of %s", |
1664 instruction_->DebugName(), | 1664 instruction_->DebugName(), |
1665 String::Handle(cls_.PrettyName()).ToCString()); | 1665 String::Handle(cls_.PrettyName()).ToCString()); |
1666 } | 1666 } |
1667 __ Bind(entry_label()); | 1667 __ Bind(entry_label()); |
1668 const Code& stub = | 1668 const Code& stub = |
1669 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); | 1669 Code::Handle(isolate, stub_code->GetAllocationStubForClass(cls_)); |
1670 const ExternalLabel label(stub.EntryPoint()); | |
1671 | 1670 |
1672 LocationSummary* locs = instruction_->locs(); | 1671 LocationSummary* locs = instruction_->locs(); |
1673 | 1672 |
1674 locs->live_registers()->Remove(Location::RegisterLocation(result_)); | 1673 locs->live_registers()->Remove(Location::RegisterLocation(result_)); |
1675 | 1674 |
1676 compiler->SaveLiveRegisters(locs); | 1675 compiler->SaveLiveRegisters(locs); |
1677 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. | 1676 compiler->GenerateCall(Scanner::kNoSourcePos, // No token position. |
1678 &label, | 1677 stub, |
1679 RawPcDescriptors::kOther, | 1678 RawPcDescriptors::kOther, |
1680 locs); | 1679 locs); |
1681 __ MoveRegister(result_, RAX); | 1680 __ MoveRegister(result_, RAX); |
1682 compiler->RestoreLiveRegisters(locs); | 1681 compiler->RestoreLiveRegisters(locs); |
1683 __ jmp(exit_label()); | 1682 __ jmp(exit_label()); |
1684 } | 1683 } |
1685 | 1684 |
1686 static void Allocate(FlowGraphCompiler* compiler, | 1685 static void Allocate(FlowGraphCompiler* compiler, |
1687 Instruction* instruction, | 1686 Instruction* instruction, |
1688 const Class& cls, | 1687 const Class& cls, |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 __ popq(kResultReg); | 2120 __ popq(kResultReg); |
2122 __ Bind(&done); | 2121 __ Bind(&done); |
2123 return; | 2122 return; |
2124 } | 2123 } |
2125 } | 2124 } |
2126 | 2125 |
2127 __ Bind(&slow_path); | 2126 __ Bind(&slow_path); |
2128 Isolate* isolate = compiler->isolate(); | 2127 Isolate* isolate = compiler->isolate(); |
2129 const Code& stub = Code::Handle( | 2128 const Code& stub = Code::Handle( |
2130 isolate, isolate->stub_code()->GetAllocateArrayStub()); | 2129 isolate, isolate->stub_code()->GetAllocateArrayStub()); |
2131 const ExternalLabel label(stub.EntryPoint()); | |
2132 compiler->GenerateCall(token_pos(), | 2130 compiler->GenerateCall(token_pos(), |
2133 &label, | 2131 stub, |
2134 RawPcDescriptors::kOther, | 2132 RawPcDescriptors::kOther, |
2135 locs()); | 2133 locs()); |
2136 compiler->AddStubCallTarget(stub); | 2134 compiler->AddStubCallTarget(stub); |
2137 __ Bind(&done); | 2135 __ Bind(&done); |
2138 ASSERT(locs()->out(0).reg() == kResultReg); | 2136 ASSERT(locs()->out(0).reg() == kResultReg); |
2139 } | 2137 } |
2140 | 2138 |
2141 | 2139 |
2142 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, | 2140 LocationSummary* LoadFieldInstr::MakeLocationSummary(Zone* zone, |
2143 bool opt) const { | 2141 bool opt) const { |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2393 __ Comment("AllocateContextSlowPath"); | 2391 __ Comment("AllocateContextSlowPath"); |
2394 __ Bind(entry_label()); | 2392 __ Bind(entry_label()); |
2395 | 2393 |
2396 LocationSummary* locs = instruction_->locs(); | 2394 LocationSummary* locs = instruction_->locs(); |
2397 locs->live_registers()->Remove(locs->out(0)); | 2395 locs->live_registers()->Remove(locs->out(0)); |
2398 | 2396 |
2399 compiler->SaveLiveRegisters(locs); | 2397 compiler->SaveLiveRegisters(locs); |
2400 | 2398 |
2401 __ LoadImmediate(R10, Immediate(instruction_->num_context_variables()), PP); | 2399 __ LoadImmediate(R10, Immediate(instruction_->num_context_variables()), PP); |
2402 StubCode* stub_code = compiler->isolate()->stub_code(); | 2400 StubCode* stub_code = compiler->isolate()->stub_code(); |
2403 const ExternalLabel label(stub_code->AllocateContextEntryPoint()); | |
2404 compiler->GenerateCall(instruction_->token_pos(), | 2401 compiler->GenerateCall(instruction_->token_pos(), |
2405 &label, | 2402 Code::Handle(stub_code->AllocateContextCode()), |
2406 RawPcDescriptors::kOther, | 2403 RawPcDescriptors::kOther, |
2407 locs); | 2404 locs); |
2408 ASSERT(instruction_->locs()->out(0).reg() == RAX); | 2405 ASSERT(instruction_->locs()->out(0).reg() == RAX); |
2409 compiler->RestoreLiveRegisters(instruction_->locs()); | 2406 compiler->RestoreLiveRegisters(instruction_->locs()); |
2410 __ jmp(exit_label()); | 2407 __ jmp(exit_label()); |
2411 } | 2408 } |
2412 | 2409 |
2413 private: | 2410 private: |
2414 AllocateUninitializedContextInstr* instruction_; | 2411 AllocateUninitializedContextInstr* instruction_; |
2415 }; | 2412 }; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2449 return locs; | 2446 return locs; |
2450 } | 2447 } |
2451 | 2448 |
2452 | 2449 |
2453 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2450 void AllocateContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2454 ASSERT(locs()->temp(0).reg() == R10); | 2451 ASSERT(locs()->temp(0).reg() == R10); |
2455 ASSERT(locs()->out(0).reg() == RAX); | 2452 ASSERT(locs()->out(0).reg() == RAX); |
2456 StubCode* stub_code = compiler->isolate()->stub_code(); | 2453 StubCode* stub_code = compiler->isolate()->stub_code(); |
2457 | 2454 |
2458 __ LoadImmediate(R10, Immediate(num_context_variables()), PP); | 2455 __ LoadImmediate(R10, Immediate(num_context_variables()), PP); |
2459 const ExternalLabel label(stub_code->AllocateContextEntryPoint()); | |
2460 compiler->GenerateCall(token_pos(), | 2456 compiler->GenerateCall(token_pos(), |
2461 &label, | 2457 Code::Handle(stub_code->AllocateContextCode()), |
2462 RawPcDescriptors::kOther, | 2458 RawPcDescriptors::kOther, |
2463 locs()); | 2459 locs()); |
2464 } | 2460 } |
2465 | 2461 |
2466 | 2462 |
2467 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone, | 2463 LocationSummary* InitStaticFieldInstr::MakeLocationSummary(Zone* zone, |
2468 bool opt) const { | 2464 bool opt) const { |
2469 const intptr_t kNumInputs = 1; | 2465 const intptr_t kNumInputs = 1; |
2470 const intptr_t kNumTemps = 1; | 2466 const intptr_t kNumTemps = 1; |
2471 LocationSummary* locs = new(zone) LocationSummary( | 2467 LocationSummary* locs = new(zone) LocationSummary( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2539 | 2535 |
2540 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2536 void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
2541 __ Bind(compiler->GetJumpLabel(this)); | 2537 __ Bind(compiler->GetJumpLabel(this)); |
2542 compiler->AddExceptionHandler(catch_try_index(), | 2538 compiler->AddExceptionHandler(catch_try_index(), |
2543 try_index(), | 2539 try_index(), |
2544 compiler->assembler()->CodeSize(), | 2540 compiler->assembler()->CodeSize(), |
2545 catch_handler_types_, | 2541 catch_handler_types_, |
2546 needs_stacktrace()); | 2542 needs_stacktrace()); |
2547 | 2543 |
2548 // Restore the pool pointer. | 2544 // Restore the pool pointer. |
| 2545 __ RestoreCodePointer(); |
2549 __ LoadPoolPointer(PP); | 2546 __ LoadPoolPointer(PP); |
2550 | 2547 |
2551 if (HasParallelMove()) { | 2548 if (HasParallelMove()) { |
2552 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 2549 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
2553 } | 2550 } |
2554 | 2551 |
2555 // Restore RSP from RBP as we are coming from a throw and the code for | 2552 // Restore RSP from RBP as we are coming from a throw and the code for |
2556 // popping arguments has not been run. | 2553 // popping arguments has not been run. |
2557 const intptr_t fp_sp_dist = | 2554 const intptr_t fp_sp_dist = |
2558 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; | 2555 (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize; |
(...skipping 3627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6186 | 6183 |
6187 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone, | 6184 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone, |
6188 bool opt) const { | 6185 bool opt) const { |
6189 const intptr_t kNumInputs = 1; | 6186 const intptr_t kNumInputs = 1; |
6190 const intptr_t kNumTemps = 1; | 6187 const intptr_t kNumTemps = 1; |
6191 | 6188 |
6192 LocationSummary* summary = new(zone) LocationSummary( | 6189 LocationSummary* summary = new(zone) LocationSummary( |
6193 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6190 zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6194 | 6191 |
6195 summary->set_in(0, Location::RequiresRegister()); | 6192 summary->set_in(0, Location::RequiresRegister()); |
6196 summary->set_temp(0, Location::RequiresRegister()); | 6193 summary->set_temp(0, Location::RegisterLocation(R13)); |
6197 | 6194 |
6198 return summary; | 6195 return summary; |
6199 } | 6196 } |
6200 | 6197 |
6201 | 6198 |
6202 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6199 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6203 Register offset_reg = locs()->in(0).reg(); | 6200 Register offset_reg = locs()->in(0).reg(); |
6204 Register target_address_reg = locs()->temp_slot(0)->reg(); | 6201 Register target_address_reg = locs()->temp_slot(0)->reg(); |
6205 | 6202 |
| 6203 { |
| 6204 const intptr_t kRIPRelativeLeaqSize = 7; |
| 6205 const intptr_t entry_to_rip_offset = |
| 6206 __ CodeSize() + kRIPRelativeLeaqSize; |
| 6207 __ leaq(target_address_reg, |
| 6208 Address::AddressRIPRelative(-entry_to_rip_offset)); |
| 6209 ASSERT(__ CodeSize() == entry_to_rip_offset); |
| 6210 } |
| 6211 |
6206 // Load from [current frame pointer] + kPcMarkerSlotFromFp. | 6212 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
6207 __ movq(target_address_reg, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); | |
6208 | 6213 |
6209 // Calculate the final absolute address. | 6214 // Calculate the final absolute address. |
6210 if (offset()->definition()->representation() == kTagged) { | 6215 if (offset()->definition()->representation() == kTagged) { |
6211 __ SmiUntag(offset_reg); | 6216 __ SmiUntag(offset_reg); |
6212 } | 6217 } |
6213 __ addq(target_address_reg, offset_reg); | 6218 __ addq(target_address_reg, offset_reg); |
6214 | 6219 |
6215 // Jump to the absolute address. | 6220 // Jump to the absolute address. |
6216 __ jmp(target_address_reg); | 6221 __ jmp(target_address_reg); |
6217 } | 6222 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6316 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6321 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6317 // Arguments descriptor is expected in R10. | 6322 // Arguments descriptor is expected in R10. |
6318 intptr_t argument_count = ArgumentCount(); | 6323 intptr_t argument_count = ArgumentCount(); |
6319 const Array& arguments_descriptor = | 6324 const Array& arguments_descriptor = |
6320 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 6325 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
6321 argument_names())); | 6326 argument_names())); |
6322 __ LoadObject(R10, arguments_descriptor, PP); | 6327 __ LoadObject(R10, arguments_descriptor, PP); |
6323 | 6328 |
6324 // Function in RAX. | 6329 // Function in RAX. |
6325 ASSERT(locs()->in(0).reg() == RAX); | 6330 ASSERT(locs()->in(0).reg() == RAX); |
6326 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); | 6331 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
| 6332 __ movq(RCX, FieldAddress(CODE_REG, Code::instructions_offset())); |
6327 | 6333 |
6328 // RAX: Function. | 6334 // RAX: Function. |
6329 // R10: Arguments descriptor array. | 6335 // R10: Arguments descriptor array. |
6330 // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | 6336 // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). |
6331 __ xorq(RBX, RBX); | 6337 __ xorq(RBX, RBX); |
6332 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 6338 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
6333 __ call(RCX); | 6339 __ call(RCX); |
6334 compiler->RecordSafepoint(locs()); | 6340 compiler->RecordSafepoint(locs()); |
6335 // Marks either the continuation point in unoptimized code or the | 6341 // Marks either the continuation point in unoptimized code or the |
6336 // deoptimization point in optimized code, after call. | 6342 // deoptimization point in optimized code, after call. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6374 bool opt) const { | 6380 bool opt) const { |
6375 return MakeCallSummary(zone); | 6381 return MakeCallSummary(zone); |
6376 } | 6382 } |
6377 | 6383 |
6378 | 6384 |
6379 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6385 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6380 Isolate* isolate = compiler->isolate(); | 6386 Isolate* isolate = compiler->isolate(); |
6381 StubCode* stub_code = isolate->stub_code(); | 6387 StubCode* stub_code = isolate->stub_code(); |
6382 const Code& stub = Code::Handle(isolate, | 6388 const Code& stub = Code::Handle(isolate, |
6383 stub_code->GetAllocationStubForClass(cls())); | 6389 stub_code->GetAllocationStubForClass(cls())); |
6384 const ExternalLabel label(stub.EntryPoint()); | |
6385 compiler->GenerateCall(token_pos(), | 6390 compiler->GenerateCall(token_pos(), |
6386 &label, | 6391 stub, |
6387 RawPcDescriptors::kOther, | 6392 RawPcDescriptors::kOther, |
6388 locs()); | 6393 locs()); |
6389 compiler->AddStubCallTarget(stub); | 6394 compiler->AddStubCallTarget(stub); |
6390 __ Drop(ArgumentCount()); // Discard arguments. | 6395 __ Drop(ArgumentCount()); // Discard arguments. |
6391 } | 6396 } |
6392 | 6397 |
6393 | 6398 |
6394 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6399 void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6395 ASSERT(!compiler->is_optimizing()); | 6400 ASSERT(!compiler->is_optimizing()); |
6396 StubCode* stub_code = compiler->isolate()->stub_code(); | 6401 StubCode* stub_code = compiler->isolate()->stub_code(); |
6397 const ExternalLabel label(stub_code->DebugStepCheckEntryPoint()); | 6402 __ CallPatchable(Code::Handle(stub_code->DebugStepCheckCode())); |
6398 __ CallPatchable(&label); | |
6399 compiler->AddCurrentDescriptor(stub_kind_, Isolate::kNoDeoptId, token_pos()); | 6403 compiler->AddCurrentDescriptor(stub_kind_, Isolate::kNoDeoptId, token_pos()); |
6400 compiler->RecordSafepoint(locs()); | 6404 compiler->RecordSafepoint(locs()); |
6401 } | 6405 } |
6402 | 6406 |
6403 | 6407 |
6404 LocationSummary* GrowRegExpStackInstr::MakeLocationSummary( | 6408 LocationSummary* GrowRegExpStackInstr::MakeLocationSummary( |
6405 Zone* zone, bool opt) const { | 6409 Zone* zone, bool opt) const { |
6406 const intptr_t kNumInputs = 1; | 6410 const intptr_t kNumInputs = 1; |
6407 const intptr_t kNumTemps = 0; | 6411 const intptr_t kNumTemps = 0; |
6408 LocationSummary* locs = new(zone) LocationSummary( | 6412 LocationSummary* locs = new(zone) LocationSummary( |
(...skipping 17 matching lines...) Expand all Loading... |
6426 __ Drop(1); | 6430 __ Drop(1); |
6427 __ popq(result); | 6431 __ popq(result); |
6428 } | 6432 } |
6429 | 6433 |
6430 | 6434 |
6431 } // namespace dart | 6435 } // namespace dart |
6432 | 6436 |
6433 #undef __ | 6437 #undef __ |
6434 | 6438 |
6435 #endif // defined TARGET_ARCH_X64 | 6439 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |