| 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 |