| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 return MakeCallSummary(); | 296 return MakeCallSummary(); |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| 300 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 300 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 301 ASSERT(VerifyCallComputation(this)); | 301 ASSERT(VerifyCallComputation(this)); |
| 302 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 302 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 303 cid(), | 303 cid(), |
| 304 token_index(), | 304 token_index(), |
| 305 try_index()); | 305 try_index()); |
| 306 compiler->EmitInstanceCall(cid(), | 306 compiler->GenerateInstanceCall(cid(), |
| 307 token_index(), | 307 token_index(), |
| 308 try_index(), | 308 try_index(), |
| 309 function_name(), | 309 function_name(), |
| 310 ArgumentCount(), | 310 ArgumentCount(), |
| 311 argument_names(), | 311 argument_names(), |
| 312 checked_argument_count()); | 312 checked_argument_count()); |
| 313 } | 313 } |
| 314 | 314 |
| 315 | 315 |
| 316 LocationSummary* StaticCallComp::MakeLocationSummary() const { | 316 LocationSummary* StaticCallComp::MakeLocationSummary() const { |
| 317 return MakeCallSummary(); | 317 return MakeCallSummary(); |
| 318 } | 318 } |
| 319 | 319 |
| 320 | 320 |
| 321 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 321 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 322 ASSERT(VerifyCallComputation(this)); | 322 ASSERT(VerifyCallComputation(this)); |
| 323 compiler->EmitStaticCall(token_index(), | 323 compiler->GenerateStaticCall(cid(), |
| 324 try_index(), | 324 token_index(), |
| 325 function(), | 325 try_index(), |
| 326 ArgumentCount(), | 326 function(), |
| 327 argument_names()); | 327 ArgumentCount(), |
| 328 argument_names()); |
| 328 } | 329 } |
| 329 | 330 |
| 330 | 331 |
| 331 LocationSummary* LoadLocalComp::MakeLocationSummary() const { | 332 LocationSummary* LoadLocalComp::MakeLocationSummary() const { |
| 332 return LocationSummary::Make(0, Location::RequiresRegister()); | 333 return LocationSummary::Make(0, Location::RequiresRegister()); |
| 333 } | 334 } |
| 334 | 335 |
| 335 | 336 |
| 336 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 337 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 337 Register result = locs()->out().reg(); | 338 Register result = locs()->out().reg(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 __ jmp(&done); | 467 __ jmp(&done); |
| 467 | 468 |
| 468 __ Bind(&non_null_compare); | 469 __ Bind(&non_null_compare); |
| 469 __ pushq(left); | 470 __ pushq(left); |
| 470 __ pushq(right); | 471 __ pushq(right); |
| 471 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | 472 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); |
| 472 const int kNumberOfArguments = 2; | 473 const int kNumberOfArguments = 2; |
| 473 const Array& kNoArgumentNames = Array::Handle(); | 474 const Array& kNoArgumentNames = Array::Handle(); |
| 474 const int kNumArgumentsChecked = 1; | 475 const int kNumArgumentsChecked = 1; |
| 475 | 476 |
| 476 compiler->EmitInstanceCall(cid(), | 477 compiler->GenerateInstanceCall(cid(), |
| 477 token_index(), | 478 token_index(), |
| 478 try_index(), | 479 try_index(), |
| 479 operator_name, | 480 operator_name, |
| 480 kNumberOfArguments, | 481 kNumberOfArguments, |
| 481 kNoArgumentNames, | 482 kNoArgumentNames, |
| 482 kNumArgumentsChecked); | 483 kNumArgumentsChecked); |
| 483 __ Bind(&done); | 484 __ Bind(&done); |
| 484 } | 485 } |
| 485 | 486 |
| 486 | 487 |
| 487 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 488 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| 488 LocationSummary* locs = new LocationSummary(0, 3); | 489 LocationSummary* locs = new LocationSummary(0, 3); |
| 489 locs->set_temp(0, Location::RegisterLocation(RAX)); | 490 locs->set_temp(0, Location::RegisterLocation(RAX)); |
| 490 locs->set_temp(1, Location::RegisterLocation(RBX)); | 491 locs->set_temp(1, Location::RegisterLocation(RBX)); |
| 491 locs->set_temp(2, Location::RegisterLocation(R10)); | 492 locs->set_temp(2, Location::RegisterLocation(R10)); |
| 492 locs->set_out(Location::RequiresRegister()); | 493 locs->set_out(Location::RequiresRegister()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 Register value = locs()->in(2).reg(); | 532 Register value = locs()->in(2).reg(); |
| 532 | 533 |
| 533 const String& function_name = | 534 const String& function_name = |
| 534 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 535 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 535 | 536 |
| 536 __ pushq(receiver); | 537 __ pushq(receiver); |
| 537 __ pushq(index); | 538 __ pushq(index); |
| 538 __ pushq(value); | 539 __ pushq(value); |
| 539 const intptr_t kNumArguments = 3; | 540 const intptr_t kNumArguments = 3; |
| 540 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 541 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
| 541 compiler->EmitInstanceCall(cid(), | 542 compiler->GenerateInstanceCall(cid(), |
| 542 token_index(), | 543 token_index(), |
| 543 try_index(), | 544 try_index(), |
| 544 function_name, | 545 function_name, |
| 545 kNumArguments, | 546 kNumArguments, |
| 546 Array::ZoneHandle(), // No optional arguments. | 547 Array::ZoneHandle(), // No optional arguments. |
| 547 kNumArgsChecked); | 548 kNumArgsChecked); |
| 548 } | 549 } |
| 549 | 550 |
| 550 | 551 |
| 551 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 552 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
| 552 const intptr_t kNumInputs = 2; | 553 const intptr_t kNumInputs = 2; |
| 553 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 554 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
| 554 return NULL; | 555 return NULL; |
| 555 } | 556 } |
| 556 | 557 |
| 557 | 558 |
| 558 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 559 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 559 Register receiver = locs()->in(0).reg(); | 560 Register receiver = locs()->in(0).reg(); |
| 560 Register value = locs()->in(1).reg(); | 561 Register value = locs()->in(1).reg(); |
| 561 Register result = locs()->out().reg(); | 562 Register result = locs()->out().reg(); |
| 562 | 563 |
| 563 // Preserve the value (second argument) under the arguments as the result | 564 // Preserve the value (second argument) under the arguments as the result |
| 564 // of the computation, then call the setter. | 565 // of the computation, then call the setter. |
| 565 const String& function_name = | 566 const String& function_name = |
| 566 String::ZoneHandle(Field::SetterSymbol(field_name())); | 567 String::ZoneHandle(Field::SetterSymbol(field_name())); |
| 567 | 568 |
| 568 // Insert a copy of the second (last) argument under the arguments. | 569 // Insert a copy of the second (last) argument under the arguments. |
| 569 // TODO(fschneider): Avoid preserving the value if the result is not used. | 570 // TODO(fschneider): Avoid preserving the value if the result is not used. |
| 570 __ pushq(value); | 571 __ pushq(value); |
| 571 __ pushq(receiver); | 572 __ pushq(receiver); |
| 572 __ pushq(value); | 573 __ pushq(value); |
| 573 compiler->EmitInstanceCall(cid(), | 574 compiler->GenerateInstanceCall(cid(), |
| 574 token_index(), | 575 token_index(), |
| 575 try_index(), | 576 try_index(), |
| 576 function_name, | 577 function_name, |
| 577 2, | 578 2, |
| 578 Array::ZoneHandle(), | 579 Array::ZoneHandle(), |
| 579 1); | 580 1); |
| 580 __ popq(result); | 581 __ popq(result); |
| 581 } | 582 } |
| 582 | 583 |
| 583 | 584 |
| 584 LocationSummary* StaticSetterComp::MakeLocationSummary() const { | 585 LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
| 585 const intptr_t kNumInputs = 1; | 586 const intptr_t kNumInputs = 1; |
| 586 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); | 587 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
| 587 } | 588 } |
| 588 | 589 |
| 589 | 590 |
| 590 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 591 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 591 Register value = locs()->in(0).reg(); | 592 Register value = locs()->in(0).reg(); |
| 592 Register result = locs()->out().reg(); | 593 Register result = locs()->out().reg(); |
| 593 | 594 |
| 594 // Preserve the argument as the result of the computation, | 595 // Preserve the argument as the result of the computation, |
| 595 // then call the setter. | 596 // then call the setter. |
| 596 | 597 |
| 597 // Duplicate the argument. | 598 // Duplicate the argument. |
| 598 // TODO(fschneider): Avoid preserving the value if the result is not used. | 599 // TODO(fschneider): Avoid preserving the value if the result is not used. |
| 599 __ pushq(value); | 600 __ pushq(value); |
| 600 __ pushq(value); | 601 __ pushq(value); |
| 601 compiler->EmitStaticCall(token_index(), | 602 compiler->GenerateStaticCall(cid(), |
| 602 try_index(), | 603 token_index(), |
| 603 setter_function(), | 604 try_index(), |
| 604 1, | 605 setter_function(), |
| 605 Array::ZoneHandle()); | 606 1, |
| 607 Array::ZoneHandle()); |
| 606 __ popq(result); | 608 __ popq(result); |
| 607 } | 609 } |
| 608 | 610 |
| 609 | 611 |
| 610 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { | 612 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
| 611 // TODO(fschneider): For this instruction the input register may be | 613 // TODO(fschneider): For this instruction the input register may be |
| 612 // reused for the result (but is not required to) because the input | 614 // reused for the result (but is not required to) because the input |
| 613 // is not used after the result is defined. We should consider adding | 615 // is not used after the result is defined. We should consider adding |
| 614 // this information to the input policy. | 616 // this information to the input policy. |
| 615 return LocationSummary::Make(1, Location::RequiresRegister()); | 617 return LocationSummary::Make(1, Location::RequiresRegister()); |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1428 } else { | 1430 } else { |
| 1429 UNREACHABLE(); | 1431 UNREACHABLE(); |
| 1430 } | 1432 } |
| 1431 } | 1433 } |
| 1432 | 1434 |
| 1433 } // namespace dart | 1435 } // namespace dart |
| 1434 | 1436 |
| 1435 #undef __ | 1437 #undef __ |
| 1436 | 1438 |
| 1437 #endif // defined TARGET_ARCH_X64 | 1439 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |