| 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 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 466 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 467 if (receiver_type() == kIllegalObjectKind) { | 467 if (receiver_type() == kIllegalObjectKind) { |
| 468 EmitLoadIndexedGeneric(compiler, this); | 468 EmitLoadIndexedGeneric(compiler, this); |
| 469 return; | 469 return; |
| 470 } | 470 } |
| 471 | 471 |
| 472 Register receiver = locs()->in(0).reg(); | 472 Register receiver = locs()->in(0).reg(); |
| 473 Register index = locs()->in(1).reg(); | 473 Register index = locs()->in(1).reg(); |
| 474 Register result = locs()->out().reg(); | 474 Register result = locs()->out().reg(); |
| 475 | 475 |
| 476 const Class& receiver_class = | |
| 477 Class::ZoneHandle(Isolate::Current()->class_table()->At( | |
| 478 receiver_type())); | |
| 479 | |
| 480 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? | 476 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? |
| 481 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; | 477 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; |
| 482 | 478 |
| 483 Label* deopt = compiler->AddDeoptStub(cid(), | 479 Label* deopt = compiler->AddDeoptStub(cid(), |
| 484 token_index(), | 480 token_index(), |
| 485 try_index(), | 481 try_index(), |
| 486 deopt_reason, | 482 deopt_reason, |
| 487 receiver, | 483 receiver, |
| 488 index); | 484 index); |
| 489 | 485 |
| 490 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. | 486 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 491 __ j(ZERO, deopt); | 487 __ j(ZERO, deopt); |
| 492 __ CompareClassId(receiver, receiver_class.id()); | 488 __ CompareClassId(receiver, receiver_type()); |
| 493 __ j(NOT_EQUAL, deopt); | 489 __ j(NOT_EQUAL, deopt); |
| 494 | 490 |
| 495 __ testq(index, Immediate(kSmiTagMask)); | 491 __ testq(index, Immediate(kSmiTagMask)); |
| 496 __ j(NOT_ZERO, deopt); | 492 __ j(NOT_ZERO, deopt); |
| 497 | 493 |
| 498 switch (receiver_type()) { | 494 switch (receiver_type()) { |
| 499 case kArray: | 495 case kArray: |
| 500 case kImmutableArray: | 496 case kImmutableArray: |
| 501 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); | 497 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); |
| 502 __ j(ABOVE_EQUAL, deopt); | 498 __ j(ABOVE_EQUAL, deopt); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 520 | 516 |
| 521 default: | 517 default: |
| 522 UNREACHABLE(); | 518 UNREACHABLE(); |
| 523 break; | 519 break; |
| 524 } | 520 } |
| 525 } | 521 } |
| 526 | 522 |
| 527 | 523 |
| 528 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { | 524 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { |
| 529 const intptr_t kNumInputs = 3; | 525 const intptr_t kNumInputs = 3; |
| 530 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 526 if (receiver_type() == kGrowableObjectArray) { |
| 527 const intptr_t kNumTemps = 1; |
| 528 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 529 locs->set_in(0, Location::RequiresRegister()); |
| 530 locs->set_in(1, Location::RequiresRegister()); |
| 531 locs->set_in(2, Location::RequiresRegister()); |
| 532 locs->set_temp(0, Location::RequiresRegister()); |
| 533 locs->set_out(Location::NoLocation()); |
| 534 return locs; |
| 535 } else if (receiver_type() == kArray) { |
| 536 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
| 537 } else { |
| 538 ASSERT(receiver_type() == kIllegalObjectKind); |
| 539 return MakeCallSummary(); |
| 540 } |
| 531 } | 541 } |
| 532 | 542 |
| 533 | 543 |
| 534 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 535 Register receiver = locs()->in(0).reg(); | |
| 536 Register index = locs()->in(1).reg(); | |
| 537 Register value = locs()->in(2).reg(); | |
| 538 | 544 |
| 545 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, |
| 546 StoreIndexedComp* comp) { |
| 539 const String& function_name = | 547 const String& function_name = |
| 540 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 548 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 541 | 549 |
| 542 __ pushq(receiver); | 550 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 543 __ pushq(index); | 551 comp->cid(), |
| 544 __ pushq(value); | 552 comp->token_index(), |
| 553 comp->try_index()); |
| 554 |
| 545 const intptr_t kNumArguments = 3; | 555 const intptr_t kNumArguments = 3; |
| 546 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 556 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
| 547 compiler->GenerateInstanceCall(cid(), | 557 compiler->GenerateInstanceCall(comp->cid(), |
| 548 token_index(), | 558 comp->token_index(), |
| 549 try_index(), | 559 comp->try_index(), |
| 550 function_name, | 560 function_name, |
| 551 kNumArguments, | 561 kNumArguments, |
| 552 Array::ZoneHandle(), // No optional arguments. | 562 Array::ZoneHandle(), // No optional arguments. |
| 553 kNumArgsChecked); | 563 kNumArgsChecked); |
| 554 } | 564 } |
| 555 | 565 |
| 556 | 566 |
| 567 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 568 if (receiver_type() == kIllegalObjectKind) { |
| 569 EmitStoreIndexedGeneric(compiler, this); |
| 570 return; |
| 571 } |
| 572 |
| 573 Register receiver = locs()->in(0).reg(); |
| 574 Register index = locs()->in(1).reg(); |
| 575 Register value = locs()->in(2).reg(); |
| 576 |
| 577 const Class& receiver_class = |
| 578 Class::ZoneHandle(Isolate::Current()->class_table()->At( |
| 579 receiver_type())); |
| 580 |
| 581 Label* deopt = compiler->AddDeoptStub(cid(), |
| 582 token_index(), |
| 583 try_index(), |
| 584 kDeoptStoreIndexed, |
| 585 receiver, |
| 586 index, |
| 587 value); |
| 588 |
| 589 __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. |
| 590 __ j(ZERO, deopt); |
| 591 __ CompareClassId(receiver, receiver_class.id()); |
| 592 __ j(NOT_EQUAL, deopt); |
| 593 |
| 594 __ testq(index, Immediate(kSmiTagMask)); |
| 595 __ j(NOT_ZERO, deopt); |
| 596 |
| 597 switch (receiver_type()) { |
| 598 case kArray: |
| 599 case kImmutableArray: |
| 600 __ cmpq(index, FieldAddress(receiver, Array::length_offset())); |
| 601 __ j(ABOVE_EQUAL, deopt); |
| 602 // Note that index is Smi, i.e, times 4. |
| 603 ASSERT(kSmiTagShift == 1); |
| 604 __ StoreIntoObject(receiver, |
| 605 FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)), |
| 606 value); |
| 607 break; |
| 608 |
| 609 case kGrowableObjectArray: { |
| 610 Register temp = locs()->temp(0).reg(); |
| 611 __ cmpq(index, |
| 612 FieldAddress(receiver, GrowableObjectArray::length_offset())); |
| 613 __ j(ABOVE_EQUAL, deopt); |
| 614 __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset())); |
| 615 // Note that index is Smi, i.e, times 4. |
| 616 ASSERT(kSmiTagShift == 1); |
| 617 __ StoreIntoObject(temp, |
| 618 FieldAddress(temp, index, TIMES_4, sizeof(RawArray)), |
| 619 value); |
| 620 break; |
| 621 } |
| 622 |
| 623 default: |
| 624 UNREACHABLE(); |
| 625 break; |
| 626 } |
| 627 } |
| 628 |
| 629 |
| 557 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { | 630 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
| 558 const intptr_t kNumInputs = 2; | 631 const intptr_t kNumInputs = 2; |
| 559 return LocationSummary::Make(kNumInputs, Location::NoLocation()); | 632 return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
| 560 return NULL; | 633 return NULL; |
| 561 } | 634 } |
| 562 | 635 |
| 563 | 636 |
| 564 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 637 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 565 Register receiver = locs()->in(0).reg(); | 638 Register receiver = locs()->in(0).reg(); |
| 566 Register value = locs()->in(1).reg(); | 639 Register value = locs()->in(1).reg(); |
| (...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1389 } else { | 1462 } else { |
| 1390 UNREACHABLE(); | 1463 UNREACHABLE(); |
| 1391 } | 1464 } |
| 1392 } | 1465 } |
| 1393 | 1466 |
| 1394 } // namespace dart | 1467 } // namespace dart |
| 1395 | 1468 |
| 1396 #undef __ | 1469 #undef __ |
| 1397 | 1470 |
| 1398 #endif // defined TARGET_ARCH_X64 | 1471 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |