| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 297 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 298 locs->set_in(0, Location::RegisterOrConstant(left())); | 298 locs->set_in(0, Location::RegisterOrConstant(left())); |
| 299 // Only one input can be a constant operand. The case of two constant | 299 // Only one input can be a constant operand. The case of two constant |
| 300 // operands should be handled by constant propagation. | 300 // operands should be handled by constant propagation. |
| 301 locs->set_in(1, locs->in(0).IsConstant() | 301 locs->set_in(1, locs->in(0).IsConstant() |
| 302 ? Location::RequiresRegister() | 302 ? Location::RequiresRegister() |
| 303 : Location::RegisterOrConstant(right())); | 303 : Location::RegisterOrConstant(right())); |
| 304 locs->set_out(Location::RequiresRegister()); | 304 locs->set_out(Location::RequiresRegister()); |
| 305 return locs; | 305 return locs; |
| 306 } | 306 } |
| 307 if (IsCheckedStrictEqual()) { | 307 UNREACHABLE(); |
| 308 const intptr_t kNumTemps = 1; | 308 return NULL; |
| 309 LocationSummary* locs = | |
| 310 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 311 locs->set_in(0, Location::RequiresRegister()); | |
| 312 locs->set_in(1, Location::RequiresRegister()); | |
| 313 locs->set_temp(0, Location::RequiresRegister()); | |
| 314 locs->set_out(Location::RequiresRegister()); | |
| 315 return locs; | |
| 316 } | |
| 317 if (IsPolymorphic()) { | |
| 318 const intptr_t kNumTemps = 1; | |
| 319 LocationSummary* locs = | |
| 320 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | |
| 321 locs->set_in(0, Location::RegisterLocation(A1)); | |
| 322 locs->set_in(1, Location::RegisterLocation(A0)); | |
| 323 locs->set_temp(0, Location::RegisterLocation(T0)); | |
| 324 locs->set_out(Location::RegisterLocation(V0)); | |
| 325 return locs; | |
| 326 } | |
| 327 const intptr_t kNumTemps = 1; | |
| 328 LocationSummary* locs = | |
| 329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | |
| 330 locs->set_in(0, Location::RegisterLocation(A1)); | |
| 331 locs->set_in(1, Location::RegisterLocation(A0)); | |
| 332 locs->set_temp(0, Location::RegisterLocation(T0)); | |
| 333 locs->set_out(Location::RegisterLocation(V0)); | |
| 334 return locs; | |
| 335 } | |
| 336 | |
| 337 | |
| 338 // A1: left. | |
| 339 // A0: right. | |
| 340 // Uses T0 to load ic_call_data. | |
| 341 // Result in V0. | |
| 342 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, | |
| 343 intptr_t deopt_id, | |
| 344 intptr_t token_pos, | |
| 345 Token::Kind kind, | |
| 346 LocationSummary* locs, | |
| 347 const ICData& original_ic_data) { | |
| 348 if (!compiler->is_optimizing()) { | |
| 349 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 350 deopt_id, | |
| 351 token_pos); | |
| 352 } | |
| 353 const int kNumberOfArguments = 2; | |
| 354 const Array& kNoArgumentNames = Object::null_array(); | |
| 355 const int kNumArgumentsChecked = 2; | |
| 356 | |
| 357 __ TraceSimMsg("EmitEqualityAsInstanceCall"); | |
| 358 __ Comment("EmitEqualityAsInstanceCall"); | |
| 359 | |
| 360 ICData& equality_ic_data = ICData::ZoneHandle(); | |
| 361 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { | |
| 362 ASSERT(!original_ic_data.IsNull()); | |
| 363 if (original_ic_data.NumberOfChecks() == 0) { | |
| 364 // IC call for reoptimization populates original ICData. | |
| 365 equality_ic_data = original_ic_data.raw(); | |
| 366 } else { | |
| 367 // Megamorphic call. | |
| 368 equality_ic_data = original_ic_data.AsUnaryClassChecks(); | |
| 369 } | |
| 370 } else { | |
| 371 const Array& arguments_descriptor = | |
| 372 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments, | |
| 373 kNoArgumentNames)); | |
| 374 equality_ic_data = ICData::New(compiler->parsed_function().function(), | |
| 375 Symbols::EqualOperator(), | |
| 376 arguments_descriptor, | |
| 377 deopt_id, | |
| 378 kNumArgumentsChecked); | |
| 379 } | |
| 380 compiler->GenerateInstanceCall(deopt_id, | |
| 381 token_pos, | |
| 382 kNumberOfArguments, | |
| 383 kNoArgumentNames, | |
| 384 locs, | |
| 385 equality_ic_data); | |
| 386 if (kind == Token::kNE) { | |
| 387 Label true_label, done; | |
| 388 // Negate the condition: true label returns false and vice versa. | |
| 389 __ BranchEqual(V0, Bool::True(), &true_label); | |
| 390 __ LoadObject(V0, Bool::True()); | |
| 391 __ b(&done); | |
| 392 __ Bind(&true_label); | |
| 393 __ LoadObject(V0, Bool::False()); | |
| 394 __ Bind(&done); | |
| 395 } | |
| 396 } | 309 } |
| 397 | 310 |
| 398 | 311 |
| 399 static void LoadValueCid(FlowGraphCompiler* compiler, | 312 static void LoadValueCid(FlowGraphCompiler* compiler, |
| 400 Register value_cid_reg, | 313 Register value_cid_reg, |
| 401 Register value_reg, | 314 Register value_reg, |
| 402 Label* value_is_smi = NULL) { | 315 Label* value_is_smi = NULL) { |
| 403 __ TraceSimMsg("LoadValueCid"); | 316 __ TraceSimMsg("LoadValueCid"); |
| 404 Label done; | 317 Label done; |
| 405 if (value_is_smi == NULL) { | 318 if (value_is_smi == NULL) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 case GE: __ beq(CMPRES1, ZR, is_true); break; | 354 case GE: __ beq(CMPRES1, ZR, is_true); break; |
| 442 case LT: __ bne(CMPRES1, ZR, is_true); break; | 355 case LT: __ bne(CMPRES1, ZR, is_true); break; |
| 443 case LE: __ beq(CMPRES2, ZR, is_true); break; | 356 case LE: __ beq(CMPRES2, ZR, is_true); break; |
| 444 default: | 357 default: |
| 445 UNREACHABLE(); | 358 UNREACHABLE(); |
| 446 break; | 359 break; |
| 447 } | 360 } |
| 448 } | 361 } |
| 449 | 362 |
| 450 | 363 |
| 451 // A1: left, also on stack. | |
| 452 // A0: right, also on stack. | |
| 453 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | |
| 454 const ICData& orig_ic_data, | |
| 455 LocationSummary* locs, | |
| 456 BranchInstr* branch, | |
| 457 Token::Kind kind, | |
| 458 intptr_t deopt_id, | |
| 459 intptr_t token_pos) { | |
| 460 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | |
| 461 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); | |
| 462 ASSERT(ic_data.NumberOfChecks() > 0); | |
| 463 ASSERT(ic_data.num_args_tested() == 1); | |
| 464 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); | |
| 465 Register left = locs->in(0).reg(); | |
| 466 Register right = locs->in(1).reg(); | |
| 467 ASSERT(left == A1); | |
| 468 ASSERT(right == A0); | |
| 469 Register temp = locs->temp(0).reg(); | |
| 470 | |
| 471 __ TraceSimMsg("EmitEqualityAsPolymorphicCall"); | |
| 472 __ Comment("EmitEqualityAsPolymorphicCall"); | |
| 473 | |
| 474 LoadValueCid(compiler, temp, left, | |
| 475 (ic_data.GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); | |
| 476 // 'temp' contains class-id of the left argument. | |
| 477 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 478 Condition cond = TokenKindToSmiCondition(kind); | |
| 479 Label done; | |
| 480 const intptr_t len = ic_data.NumberOfChecks(); | |
| 481 for (intptr_t i = 0; i < len; i++) { | |
| 482 // Assert that the Smi is at position 0, if at all. | |
| 483 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); | |
| 484 Label next_test; | |
| 485 if (i < len - 1) { | |
| 486 __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), &next_test); | |
| 487 } else { | |
| 488 __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt); | |
| 489 } | |
| 490 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | |
| 491 if (target.Owner() == object_store->object_class()) { | |
| 492 // Object.== is same as ===. | |
| 493 __ Drop(2); | |
| 494 __ slt(CMPRES1, left, right); | |
| 495 __ slt(CMPRES2, right, left); | |
| 496 if (branch != NULL) { | |
| 497 branch->EmitBranchOnCondition(compiler, cond); | |
| 498 } else { | |
| 499 Register result = locs->out().reg(); | |
| 500 Label load_true; | |
| 501 EmitBranchAfterCompare(compiler, cond, &load_true); | |
| 502 __ LoadObject(result, Bool::False()); | |
| 503 __ b(&done); | |
| 504 __ Bind(&load_true); | |
| 505 __ LoadObject(result, Bool::True()); | |
| 506 } | |
| 507 } else { | |
| 508 const int kNumberOfArguments = 2; | |
| 509 const Array& kNoArgumentNames = Object::null_array(); | |
| 510 compiler->GenerateStaticCall(deopt_id, | |
| 511 token_pos, | |
| 512 target, | |
| 513 kNumberOfArguments, | |
| 514 kNoArgumentNames, | |
| 515 locs); | |
| 516 if (branch == NULL) { | |
| 517 if (kind == Token::kNE) { | |
| 518 Label is_true; | |
| 519 __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); | |
| 520 __ beq(CMPRES, CMPRES2, &is_true); | |
| 521 __ LoadObject(V0, Bool::True()); | |
| 522 __ b(&done); | |
| 523 __ Bind(&is_true); | |
| 524 __ LoadObject(V0, Bool::False()); | |
| 525 } | |
| 526 } else { | |
| 527 if (branch->is_checked()) { | |
| 528 EmitAssertBoolean(V0, token_pos, deopt_id, locs, compiler); | |
| 529 } | |
| 530 __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); | |
| 531 branch->EmitBranchOnCondition(compiler, cond); | |
| 532 } | |
| 533 } | |
| 534 if (i < len - 1) { | |
| 535 __ b(&done); | |
| 536 __ Bind(&next_test); | |
| 537 } | |
| 538 } | |
| 539 __ Bind(&done); | |
| 540 } | |
| 541 | |
| 542 | |
| 543 // Emit code when ICData's targets are all Object == (which is ===). | |
| 544 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, | |
| 545 const ICData& orig_ic_data, | |
| 546 const LocationSummary& locs, | |
| 547 Token::Kind kind, | |
| 548 BranchInstr* branch, | |
| 549 intptr_t deopt_id) { | |
| 550 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | |
| 551 Register left = locs.in(0).reg(); | |
| 552 Register right = locs.in(1).reg(); | |
| 553 Register temp = locs.temp(0).reg(); | |
| 554 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); | |
| 555 | |
| 556 __ Comment("CheckedStrictEqual"); | |
| 557 | |
| 558 __ andi(CMPRES, left, Immediate(kSmiTagMask)); | |
| 559 __ beq(CMPRES, ZR, deopt); | |
| 560 // 'left' is not Smi. | |
| 561 Label identity_compare; | |
| 562 __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null())); | |
| 563 __ beq(right, CMPRES1, &identity_compare); | |
| 564 __ beq(left, CMPRES1, &identity_compare); | |
| 565 | |
| 566 __ LoadClassId(temp, left); | |
| 567 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); | |
| 568 const intptr_t len = ic_data.NumberOfChecks(); | |
| 569 for (intptr_t i = 0; i < len; i++) { | |
| 570 if (i == (len - 1)) { | |
| 571 __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt); | |
| 572 } else { | |
| 573 __ BranchEqual(temp, ic_data.GetReceiverClassIdAt(i), &identity_compare); | |
| 574 } | |
| 575 } | |
| 576 __ Bind(&identity_compare); | |
| 577 __ subu(CMPRES1, left, right); | |
| 578 if (branch == NULL) { | |
| 579 Label done, is_equal; | |
| 580 Register result = locs.out().reg(); | |
| 581 __ beq(CMPRES, ZR, &is_equal); | |
| 582 // Not equal. | |
| 583 __ LoadObject(result, Bool::Get(kind != Token::kEQ)); | |
| 584 __ b(&done); | |
| 585 __ Bind(&is_equal); | |
| 586 __ LoadObject(result, Bool::Get(kind == Token::kEQ)); | |
| 587 __ Bind(&done); | |
| 588 | |
| 589 } else { | |
| 590 Condition cond = TokenKindToSmiCondition(kind); | |
| 591 __ mov(CMPRES2, ZR); | |
| 592 branch->EmitBranchOnCondition(compiler, cond); | |
| 593 } | |
| 594 } | |
| 595 | |
| 596 | |
| 597 // First test if receiver is NULL, in which case === is applied. | |
| 598 // If type feedback was provided (lists of <class-id, target>), do a | |
| 599 // type by type check (either === or static call to the operator. | |
| 600 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, | |
| 601 LocationSummary* locs, | |
| 602 Token::Kind kind, | |
| 603 BranchInstr* branch, | |
| 604 const ICData& ic_data, | |
| 605 intptr_t deopt_id, | |
| 606 intptr_t token_pos) { | |
| 607 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | |
| 608 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | |
| 609 Register left = locs->in(0).reg(); | |
| 610 Register right = locs->in(1).reg(); | |
| 611 __ TraceSimMsg("EmitGenericEqualityCompare"); | |
| 612 __ Comment("EmitGenericEqualityCompare"); | |
| 613 ASSERT(left == A1); | |
| 614 ASSERT(right == A0); | |
| 615 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
| 616 __ sw(A1, Address(SP, 1 * kWordSize)); | |
| 617 __ sw(A0, Address(SP, 0 * kWordSize)); | |
| 618 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, | |
| 619 deopt_id, token_pos); | |
| 620 } | |
| 621 | |
| 622 | |
| 623 static Condition FlipCondition(Condition condition) { | 364 static Condition FlipCondition(Condition condition) { |
| 624 switch (condition) { | 365 switch (condition) { |
| 625 case EQ: return EQ; | 366 case EQ: return EQ; |
| 626 case NE: return NE; | 367 case NE: return NE; |
| 627 case LT: return GT; | 368 case LT: return GT; |
| 628 case LE: return GE; | 369 case LE: return GE; |
| 629 case GT: return LT; | 370 case GT: return LT; |
| 630 case GE: return LE; | 371 case GE: return LE; |
| 631 default: | 372 default: |
| 632 UNREACHABLE(); | 373 UNREACHABLE(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 return; | 473 return; |
| 733 } | 474 } |
| 734 if (operation_cid() == kMintCid) { | 475 if (operation_cid() == kMintCid) { |
| 735 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); | 476 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch); |
| 736 return; | 477 return; |
| 737 } | 478 } |
| 738 if (operation_cid() == kDoubleCid) { | 479 if (operation_cid() == kDoubleCid) { |
| 739 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); | 480 EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
| 740 return; | 481 return; |
| 741 } | 482 } |
| 742 if (IsCheckedStrictEqual()) { | 483 UNREACHABLE(); |
| 743 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, | |
| 744 deopt_id()); | |
| 745 return; | |
| 746 } | |
| 747 if (IsPolymorphic()) { | |
| 748 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), | |
| 749 deopt_id(), token_pos()); | |
| 750 return; | |
| 751 } | |
| 752 Register left = locs()->in(0).reg(); | |
| 753 Register right = locs()->in(1).reg(); | |
| 754 ASSERT(left == A1); | |
| 755 ASSERT(right == A0); | |
| 756 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
| 757 __ sw(A1, Address(SP, 1 * kWordSize)); | |
| 758 __ sw(A0, Address(SP, 0 * kWordSize)); | |
| 759 EmitEqualityAsInstanceCall(compiler, | |
| 760 deopt_id(), | |
| 761 token_pos(), | |
| 762 kind(), | |
| 763 locs(), | |
| 764 *ic_data()); | |
| 765 ASSERT(locs()->out().reg() == V0); | |
| 766 } | 484 } |
| 767 | 485 |
| 768 | 486 |
| 769 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, | 487 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
| 770 BranchInstr* branch) { | 488 BranchInstr* branch) { |
| 771 __ TraceSimMsg("EqualityCompareInstr"); | 489 __ TraceSimMsg("EqualityCompareInstr"); |
| 772 __ Comment("EqualityCompareInstr:BranchCode"); | 490 __ Comment("EqualityCompareInstr:BranchCode"); |
| 773 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); | 491 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
| 774 if (operation_cid() == kSmiCid) { | 492 if (operation_cid() == kSmiCid) { |
| 775 // Deoptimizes if both arguments not Smi. | 493 // Deoptimizes if both arguments not Smi. |
| 776 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); | 494 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); |
| 777 return; | 495 return; |
| 778 } | 496 } |
| 779 if (operation_cid() == kMintCid) { | 497 if (operation_cid() == kMintCid) { |
| 780 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); | 498 EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch); |
| 781 return; | 499 return; |
| 782 } | 500 } |
| 783 if (operation_cid() == kDoubleCid) { | 501 if (operation_cid() == kDoubleCid) { |
| 784 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); | 502 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
| 785 return; | 503 return; |
| 786 } | 504 } |
| 787 if (IsCheckedStrictEqual()) { | 505 UNREACHABLE(); |
| 788 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, | |
| 789 deopt_id()); | |
| 790 return; | |
| 791 } | |
| 792 if (IsPolymorphic()) { | |
| 793 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), | |
| 794 deopt_id(), token_pos()); | |
| 795 return; | |
| 796 } | |
| 797 Register left = locs()->in(0).reg(); | |
| 798 Register right = locs()->in(1).reg(); | |
| 799 ASSERT(left == A1); | |
| 800 ASSERT(right == A0); | |
| 801 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
| 802 __ sw(A1, Address(SP, 1 * kWordSize)); | |
| 803 __ sw(A0, Address(SP, 0 * kWordSize)); | |
| 804 EmitEqualityAsInstanceCall(compiler, | |
| 805 deopt_id(), | |
| 806 token_pos(), | |
| 807 Token::kEQ, // kNE reverse occurs at branch. | |
| 808 locs(), | |
| 809 *ic_data()); | |
| 810 if (branch->is_checked()) { | |
| 811 EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler); | |
| 812 } | |
| 813 Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; | |
| 814 __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); | |
| 815 branch->EmitBranchOnCondition(compiler, branch_condition); | |
| 816 } | 506 } |
| 817 | 507 |
| 818 | 508 |
| 819 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { | 509 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { |
| 820 const intptr_t kNumInputs = 2; | 510 const intptr_t kNumInputs = 2; |
| 821 const intptr_t kNumTemps = 0; | 511 const intptr_t kNumTemps = 0; |
| 822 if (operation_cid() == kMintCid) { | 512 if (operation_cid() == kMintCid) { |
| 823 const intptr_t kNumTemps = 2; | 513 const intptr_t kNumTemps = 2; |
| 824 LocationSummary* locs = | 514 LocationSummary* locs = |
| 825 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 515 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 3264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4090 compiler->GenerateCall(token_pos(), | 3780 compiler->GenerateCall(token_pos(), |
| 4091 &label, | 3781 &label, |
| 4092 PcDescriptors::kOther, | 3782 PcDescriptors::kOther, |
| 4093 locs()); | 3783 locs()); |
| 4094 __ Drop(2); // Discard type arguments and receiver. | 3784 __ Drop(2); // Discard type arguments and receiver. |
| 4095 } | 3785 } |
| 4096 | 3786 |
| 4097 } // namespace dart | 3787 } // namespace dart |
| 4098 | 3788 |
| 4099 #endif // defined TARGET_ARCH_MIPS | 3789 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |