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

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

Issue 180243013: Stop creating dummy call frames when calling out to C functions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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" // 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 3962 matching lines...) Expand 10 before | Expand all | Expand 10 after
3973 3973
3974 3974
3975 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { 3975 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const {
3976 if ((kind() == MethodRecognizer::kMathSin) || 3976 if ((kind() == MethodRecognizer::kMathSin) ||
3977 (kind() == MethodRecognizer::kMathCos)) { 3977 (kind() == MethodRecognizer::kMathCos)) {
3978 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 3978 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
3979 // double arguments and XMM0 to return the result. Unfortunately 3979 // double arguments and XMM0 to return the result. Unfortunately
3980 // currently we can't specify these registers because ParallelMoveResolver 3980 // currently we can't specify these registers because ParallelMoveResolver
3981 // assumes that XMM0 is free at all times. 3981 // assumes that XMM0 is free at all times.
3982 // TODO(vegorov): allow XMM0 to be used. 3982 // TODO(vegorov): allow XMM0 to be used.
3983 const intptr_t kNumTemps = 0; 3983 const intptr_t kNumTemps = 1;
3984 LocationSummary* summary = 3984 LocationSummary* summary =
3985 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 3985 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
3986 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 3986 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
3987 // R13 is chosen because it is callee saved so we do not need to back it
3988 // up before calling into the runtime.
3989 summary->set_temp(0, Location::RegisterLocation(R13));
3987 summary->set_out(Location::FpuRegisterLocation(XMM1)); 3990 summary->set_out(Location::FpuRegisterLocation(XMM1));
3988 return summary; 3991 return summary;
3989 } 3992 }
3993 ASSERT(kind() == MethodRecognizer::kMathSqrt);
3990 const intptr_t kNumInputs = 1; 3994 const intptr_t kNumInputs = 1;
3991 const intptr_t kNumTemps = 0; 3995 const intptr_t kNumTemps = 0;
3992 LocationSummary* summary = 3996 LocationSummary* summary =
3993 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3997 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3994 summary->set_in(0, Location::RequiresFpuRegister()); 3998 summary->set_in(0, Location::RequiresFpuRegister());
3995 summary->set_out(Location::RequiresFpuRegister()); 3999 summary->set_out(Location::RequiresFpuRegister());
3996 return summary; 4000 return summary;
3997 } 4001 }
3998 4002
3999 4003
4000 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4004 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4001 if (kind() == MethodRecognizer::kMathSqrt) { 4005 if (kind() == MethodRecognizer::kMathSqrt) {
4002 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg()); 4006 __ sqrtsd(locs()->out().fpu_reg(), locs()->in(0).fpu_reg());
4003 } else { 4007 } else {
4004 __ EnterFrame(0); 4008 ASSERT((kind() == MethodRecognizer::kMathSin) ||
4009 (kind() == MethodRecognizer::kMathCos));
4010 // Save RSP.
4011 __ movq(locs()->temp(0).reg(), RSP);
4005 __ ReserveAlignedFrameSpace(0); 4012 __ ReserveAlignedFrameSpace(0);
4006 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4013 __ movaps(XMM0, locs()->in(0).fpu_reg());
4007 __ CallRuntime(TargetFunction(), InputCount()); 4014 __ CallRuntime(TargetFunction(), InputCount());
4008 __ movaps(locs()->out().fpu_reg(), XMM0); 4015 __ movaps(locs()->out().fpu_reg(), XMM0);
4009 __ leave(); 4016 // Restore RSP.
4017 __ movq(RSP, locs()->temp(0).reg());
4010 } 4018 }
4011 } 4019 }
4012 4020
4013 4021
4014 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const { 4022 LocationSummary* UnarySmiOpInstr::MakeLocationSummary(bool opt) const {
4015 const intptr_t kNumInputs = 1; 4023 const intptr_t kNumInputs = 1;
4016 return LocationSummary::Make(kNumInputs, 4024 return LocationSummary::Make(kNumInputs,
4017 Location::SameAsFirstInput(), 4025 Location::SameAsFirstInput(),
4018 LocationSummary::kNoCall); 4026 LocationSummary::kNoCall);
4019 } 4027 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4315 } 4323 }
4316 4324
4317 4325
4318 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const { 4326 LocationSummary* InvokeMathCFunctionInstr::MakeLocationSummary(bool opt) const {
4319 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two 4327 // Calling convention on x64 uses XMM0 and XMM1 to pass the first two
4320 // double arguments and XMM0 to return the result. Unfortunately 4328 // double arguments and XMM0 to return the result. Unfortunately
4321 // currently we can't specify these registers because ParallelMoveResolver 4329 // currently we can't specify these registers because ParallelMoveResolver
4322 // assumes that XMM0 is free at all times. 4330 // assumes that XMM0 is free at all times.
4323 // TODO(vegorov): allow XMM0 to be used. 4331 // TODO(vegorov): allow XMM0 to be used.
4324 ASSERT((InputCount() == 1) || (InputCount() == 2)); 4332 ASSERT((InputCount() == 1) || (InputCount() == 2));
4325 const intptr_t kNumTemps = 0; 4333 const intptr_t kNumTemps = 1;
4326 LocationSummary* result = 4334 LocationSummary* result =
4327 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); 4335 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall);
4336 result->set_temp(0, Location::RegisterLocation(R13));
4328 result->set_in(0, Location::FpuRegisterLocation(XMM2)); 4337 result->set_in(0, Location::FpuRegisterLocation(XMM2));
4329 if (InputCount() == 2) { 4338 if (InputCount() == 2) {
4330 result->set_in(1, Location::FpuRegisterLocation(XMM1)); 4339 result->set_in(1, Location::FpuRegisterLocation(XMM1));
4331 } 4340 }
4332 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4341 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4342 // Temp index 1.
4333 result->AddTemp(Location::RegisterLocation(RAX)); 4343 result->AddTemp(Location::RegisterLocation(RAX));
4344 // Temp index 2.
4334 result->AddTemp(Location::FpuRegisterLocation(XMM4)); 4345 result->AddTemp(Location::FpuRegisterLocation(XMM4));
4335 } 4346 }
4336 result->set_out(Location::FpuRegisterLocation(XMM3)); 4347 result->set_out(Location::FpuRegisterLocation(XMM3));
4337 return result; 4348 return result;
4338 } 4349 }
4339 4350
4340 4351
4341 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4352 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4342 __ EnterFrame(0); 4353 // Save RSP.
4354 __ movq(locs()->temp(kSavedSpTempIndex).reg(), RSP);
4343 __ ReserveAlignedFrameSpace(0); 4355 __ ReserveAlignedFrameSpace(0);
4344 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4356 __ movaps(XMM0, locs()->in(0).fpu_reg());
4345 if (InputCount() == 2) { 4357 if (InputCount() == 2) {
4346 ASSERT(locs()->in(1).fpu_reg() == XMM1); 4358 ASSERT(locs()->in(1).fpu_reg() == XMM1);
4347 } 4359 }
4348 // For pow-function return NaN if exponent is NaN. 4360 // For pow-function return NaN if exponent is NaN.
4349 Label do_call, skip_call; 4361 Label do_call, skip_call;
4350 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { 4362 if (recognized_kind() == MethodRecognizer::kMathDoublePow) {
4351 // Pseudo code: 4363 // Pseudo code:
4352 // if (exponent == 0.0) return 0.0; 4364 // if (exponent == 0.0) return 0.0;
4353 // if (base == 1.0) return 1.0; 4365 // if (base == 1.0) return 1.0;
4354 // if (base.isNaN || exponent.isNaN) { 4366 // if (base.isNaN || exponent.isNaN) {
4355 // return double.NAN; 4367 // return double.NAN;
4356 // } 4368 // }
4357 XmmRegister base = locs()->in(0).fpu_reg(); 4369 XmmRegister base = locs()->in(0).fpu_reg();
4358 XmmRegister exp = locs()->in(1).fpu_reg(); 4370 XmmRegister exp = locs()->in(1).fpu_reg();
4359 XmmRegister result = locs()->out().fpu_reg(); 4371 XmmRegister result = locs()->out().fpu_reg();
4360 Register temp = locs()->temp(0).reg(); 4372 Register temp = locs()->temp(kObjectTempIndex).reg();
4361 XmmRegister zero_temp = locs()->temp(1).fpu_reg(); 4373 XmmRegister zero_temp = locs()->temp(kDoubleTempIndex).fpu_reg();
4362 4374
4363 // Check if exponent is 0.0 -> return 1.0; 4375 // Check if exponent is 0.0 -> return 1.0;
4364 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); 4376 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP);
4365 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); 4377 __ movsd(zero_temp, FieldAddress(temp, Double::value_offset()));
4366 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); 4378 __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP);
4367 __ movsd(result, FieldAddress(temp, Double::value_offset())); 4379 __ movsd(result, FieldAddress(temp, Double::value_offset()));
4368 // 'result' contains 1.0. 4380 // 'result' contains 1.0.
4369 Label exp_is_nan; 4381 Label exp_is_nan;
4370 __ comisd(exp, zero_temp); 4382 __ comisd(exp, zero_temp);
4371 __ j(PARITY_EVEN, &exp_is_nan, Assembler::kNearJump); // NaN. 4383 __ j(PARITY_EVEN, &exp_is_nan, Assembler::kNearJump); // NaN.
(...skipping 16 matching lines...) Expand all
4388 __ comisd(base, result); 4400 __ comisd(base, result);
4389 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump); 4401 __ j(PARITY_EVEN, &base_is_nan, Assembler::kNearJump);
4390 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0 4402 __ j(EQUAL, &skip_call, Assembler::kNearJump); // base and result are 1.0
4391 __ movsd(result, exp); // result is NaN 4403 __ movsd(result, exp); // result is NaN
4392 __ jmp(&skip_call, Assembler::kNearJump); 4404 __ jmp(&skip_call, Assembler::kNearJump);
4393 } 4405 }
4394 __ Bind(&do_call); 4406 __ Bind(&do_call);
4395 __ CallRuntime(TargetFunction(), InputCount()); 4407 __ CallRuntime(TargetFunction(), InputCount());
4396 __ movaps(locs()->out().fpu_reg(), XMM0); 4408 __ movaps(locs()->out().fpu_reg(), XMM0);
4397 __ Bind(&skip_call); 4409 __ Bind(&skip_call);
4398 __ leave(); 4410 // Restore RSP.
4411 __ movq(RSP, locs()->temp(kSavedSpTempIndex).reg());
4399 } 4412 }
4400 4413
4401 4414
4402 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const { 4415 LocationSummary* MergedMathInstr::MakeLocationSummary(bool opt) const {
4403 if (kind() == MergedMathInstr::kTruncDivMod) { 4416 if (kind() == MergedMathInstr::kTruncDivMod) {
4404 const intptr_t kNumInputs = 2; 4417 const intptr_t kNumInputs = 2;
4405 const intptr_t kNumTemps = 1; 4418 const intptr_t kNumTemps = 1;
4406 LocationSummary* summary = 4419 LocationSummary* summary =
4407 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 4420 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
4408 // Both inputs must be writable because they will be untagged. 4421 // Both inputs must be writable because they will be untagged.
4409 summary->set_in(0, Location::RegisterLocation(RAX)); 4422 summary->set_in(0, Location::RegisterLocation(RAX));
4410 summary->set_in(1, Location::WritableRegister()); 4423 summary->set_in(1, Location::WritableRegister());
4411 summary->set_out(Location::RequiresRegister()); 4424 summary->set_out(Location::RequiresRegister());
4412 // Will be used for sign extension and division. 4425 // Will be used for sign extension and division.
4413 summary->set_temp(0, Location::RegisterLocation(RDX)); 4426 summary->set_temp(0, Location::RegisterLocation(RDX));
4414 return summary; 4427 return summary;
4415 } 4428 }
4416 if (kind() == MergedMathInstr::kSinCos) { 4429 if (kind() == MergedMathInstr::kSinCos) {
4417 const intptr_t kNumInputs = 1; 4430 const intptr_t kNumInputs = 1;
4418 const intptr_t kNumTemps = 0; 4431 const intptr_t kNumTemps = 1;
4419 LocationSummary* summary = 4432 LocationSummary* summary =
4420 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 4433 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4421 summary->set_in(0, Location::FpuRegisterLocation(XMM1)); 4434 summary->set_in(0, Location::FpuRegisterLocation(XMM1));
4435 // R13 is chosen because it is callee saved so we do not need to back it
4436 // up before calling into the runtime.
4437 summary->set_temp(0, Location::RegisterLocation(R13));
4422 summary->set_out(Location::RegisterLocation(RAX)); 4438 summary->set_out(Location::RegisterLocation(RAX));
4423 return summary; 4439 return summary;
4424 } 4440 }
4425 UNIMPLEMENTED(); 4441 UNIMPLEMENTED();
4426 return NULL; 4442 return NULL;
4427 } 4443 }
4428 4444
4429 4445
4430 4446
4431 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos); 4447 typedef void (*SinCosCFunction) (double x, double* res_sin, double* res_cos);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
4534 __ SmiTag(RAX); 4550 __ SmiTag(RAX);
4535 __ SmiTag(RDX); 4551 __ SmiTag(RDX);
4536 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX); 4552 __ StoreIntoObjectNoBarrier(result, trunc_div_address, RAX);
4537 __ StoreIntoObjectNoBarrier(result, mod_address, RDX); 4553 __ StoreIntoObjectNoBarrier(result, mod_address, RDX);
4538 // FLAG_throw_on_javascript_int_overflow: not needed. 4554 // FLAG_throw_on_javascript_int_overflow: not needed.
4539 // Note that the result of an integer division/modulo of two 4555 // Note that the result of an integer division/modulo of two
4540 // in-range arguments, cannot create out-of-range result. 4556 // in-range arguments, cannot create out-of-range result.
4541 return; 4557 return;
4542 } 4558 }
4543 if (kind() == MergedMathInstr::kSinCos) { 4559 if (kind() == MergedMathInstr::kSinCos) {
4544 __ EnterFrame(0); 4560 // Save RSP.
4561 __ movq(locs()->temp(0).reg(), RSP);
4545 // +-------------------------------+ 4562 // +-------------------------------+
4546 // | double-argument | <- TOS 4563 // | double-argument | <- TOS
4547 // +-------------------------------+ 4564 // +-------------------------------+
4548 // | address-cos-result | +8 4565 // | address-cos-result | +8
4549 // +-------------------------------+ 4566 // +-------------------------------+
4550 // | address-sin-result | +16 4567 // | address-sin-result | +16
4551 // +-------------------------------+ 4568 // +-------------------------------+
4552 // | double-storage-for-cos-result | +24 4569 // | double-storage-for-cos-result | +24
4553 // +-------------------------------+ 4570 // +-------------------------------+
4554 // | double-storage-for-sin-result | +32 4571 // | double-storage-for-sin-result | +32
4555 // +-------------------------------+ 4572 // +-------------------------------+
4556 // .... 4573 // ....
4557 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2); 4574 __ ReserveAlignedFrameSpace(kDoubleSize * 3 + kWordSize * 2);
4558 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg()); 4575 __ movsd(Address(RSP, 0), locs()->in(0).fpu_reg());
4559 4576
4560 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize)); 4577 __ leaq(RDI, Address(RSP, 2 * kWordSize + kDoubleSize));
4561 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize)); 4578 __ leaq(RSI, Address(RSP, 2 * kWordSize + 2 * kDoubleSize));
4562 __ movaps(XMM0, locs()->in(0).fpu_reg()); 4579 __ movaps(XMM0, locs()->in(0).fpu_reg());
4563 4580
4564 __ CallRuntime(kSinCosRuntimeEntry, InputCount()); 4581 __ CallRuntime(kSinCosRuntimeEntry, InputCount());
4565 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin. 4582 __ movsd(XMM0, Address(RSP, 2 * kWordSize + kDoubleSize * 2)); // sin.
4566 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos. 4583 __ movsd(XMM1, Address(RSP, 2 * kWordSize + kDoubleSize)); // cos.
4567 __ leave(); 4584 // Restore RSP.
4585 __ movq(RSP, locs()->temp(0).reg());
4568 4586
4569 Register result = locs()->out().reg(); 4587 Register result = locs()->out().reg();
4570 const TypedData& res_array = TypedData::ZoneHandle( 4588 const TypedData& res_array = TypedData::ZoneHandle(
4571 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld)); 4589 TypedData::New(kTypedDataFloat64ArrayCid, 2, Heap::kOld));
4572 __ LoadObject(result, res_array, PP); 4590 __ LoadObject(result, res_array, PP);
4573 const intptr_t index_scale = 4591 const intptr_t index_scale =
4574 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid); 4592 FlowGraphCompiler::ElementSizeFor(kTypedDataFloat64ArrayCid);
4575 Address sin_address( 4593 Address sin_address(
4576 FlowGraphCompiler::ElementAddressForIntIndex( 4594 FlowGraphCompiler::ElementAddressForIntIndex(
4577 kTypedDataFloat64ArrayCid, index_scale, result, 4595 kTypedDataFloat64ArrayCid, index_scale, result,
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
5071 PcDescriptors::kOther, 5089 PcDescriptors::kOther,
5072 locs()); 5090 locs());
5073 __ Drop(ArgumentCount()); // Discard arguments. 5091 __ Drop(ArgumentCount()); // Discard arguments.
5074 } 5092 }
5075 5093
5076 } // namespace dart 5094 } // namespace dart
5077 5095
5078 #undef __ 5096 #undef __
5079 5097
5080 #endif // defined TARGET_ARCH_X64 5098 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698