@@ -306,6 +306,7 @@ static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
306
306
ASSERT (comp->HasICData ());
307
307
const ICData& ic_data = *comp->ic_data ();
308
308
ASSERT (ic_data.NumberOfChecks () > 0 );
309
+ ASSERT (ic_data.num_args_tested () == 1 );
309
310
Label* deopt = compiler->AddDeoptStub (comp->cid (),
310
311
comp->token_index (),
311
312
comp->try_index (),
@@ -637,10 +638,47 @@ LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
637
638
}
638
639
639
640
641
+ static void EmitLoadIndexedPolymorphic (FlowGraphCompiler* compiler,
642
+ LoadIndexedComp* comp) {
643
+ Label* deopt = compiler->AddDeoptStub (comp->cid (),
644
+ comp->token_index (),
645
+ comp->try_index (),
646
+ kDeoptLoadIndexedPolymorphic );
647
+ if (comp->ic_data ()->NumberOfChecks () == 0 ) {
648
+ __ jmp (deopt);
649
+ return ;
650
+ }
651
+ ASSERT (comp->HasICData ());
652
+ const ICData& ic_data = *comp->ic_data ();
653
+ ASSERT (ic_data.num_args_tested () == 1 );
654
+ // No indexed access on Smi.
655
+ ASSERT (ic_data.GetReceiverClassIdAt (0 ) != kSmi );
656
+ // Load receiver into EAX.
657
+ const intptr_t kNumArguments = 2 ;
658
+ __ movl (EAX, Address (ESP, (kNumArguments - 1 ) * kWordSize ));
659
+ __ testl (EAX, Immediate (kSmiTagMask ));
660
+ __ j (ZERO, deopt);
661
+ Label done;
662
+ __ LoadClassId (EDI, EAX);
663
+ compiler->EmitTestAndCall (ic_data,
664
+ EDI, // Class id register.
665
+ kNumArguments ,
666
+ Array::Handle (), // No named arguments.
667
+ deopt, &done, // Labels.
668
+ comp->cid (),
669
+ comp->token_index (),
670
+ comp->try_index ());
671
+ __ Bind (&done);
672
+ }
673
+
640
674
641
675
void LoadIndexedComp::EmitNativeCode (FlowGraphCompiler* compiler) {
642
676
if (receiver_type () == kIllegalObjectKind ) {
643
- compiler->EmitLoadIndexedGeneric (this );
677
+ if (HasICData ()) {
678
+ EmitLoadIndexedPolymorphic (compiler, this );
679
+ } else {
680
+ compiler->EmitLoadIndexedGeneric (this );
681
+ }
644
682
ASSERT (locs ()->out ().reg () == EAX);
645
683
return ;
646
684
}
@@ -719,7 +757,6 @@ LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
719
757
}
720
758
721
759
722
-
723
760
static void EmitStoreIndexedGeneric (FlowGraphCompiler* compiler,
724
761
StoreIndexedComp* comp) {
725
762
const String& function_name =
@@ -737,14 +774,52 @@ static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
737
774
comp->try_index (),
738
775
function_name,
739
776
kNumArguments ,
740
- Array::ZoneHandle (), // No optional arguments .
777
+ Array::ZoneHandle (), // No named args .
741
778
kNumArgsChecked );
742
779
}
743
780
744
781
782
+ static void EmitStoreIndexedPolymorphic (FlowGraphCompiler* compiler,
783
+ StoreIndexedComp* comp) {
784
+ Label* deopt = compiler->AddDeoptStub (comp->cid (),
785
+ comp->token_index (),
786
+ comp->try_index (),
787
+ kDeoptStoreIndexedPolymorphic );
788
+ if (comp->ic_data ()->NumberOfChecks () == 0 ) {
789
+ __ jmp (deopt);
790
+ return ;
791
+ }
792
+ ASSERT (comp->HasICData ());
793
+ const ICData& ic_data = *comp->ic_data ();
794
+ ASSERT (ic_data.num_args_tested () == 1 );
795
+ // No indexed access on Smi.
796
+ ASSERT (ic_data.GetReceiverClassIdAt (0 ) != kSmi );
797
+ // Load receiver into EAX.
798
+ const intptr_t kNumArguments = 3 ;
799
+ __ movl (EAX, Address (ESP, (kNumArguments - 1 ) * kWordSize ));
800
+ __ testl (EAX, Immediate (kSmiTagMask ));
801
+ __ j (ZERO, deopt);
802
+ Label done;
803
+ __ LoadClassId (EDI, EAX);
804
+ compiler->EmitTestAndCall (ic_data,
805
+ EDI, // Class id register.
806
+ kNumArguments ,
807
+ Array::Handle (), // No named arguments.
808
+ deopt, &done, // Labels.
809
+ comp->cid (),
810
+ comp->token_index (),
811
+ comp->try_index ());
812
+ __ Bind (&done);
813
+ }
814
+
815
+
745
816
void StoreIndexedComp::EmitNativeCode (FlowGraphCompiler* compiler) {
746
817
if (receiver_type () == kIllegalObjectKind ) {
747
- EmitStoreIndexedGeneric (compiler, this );
818
+ if (HasICData ()) {
819
+ EmitStoreIndexedPolymorphic (compiler, this );
820
+ } else {
821
+ EmitStoreIndexedGeneric (compiler, this );
822
+ }
748
823
return ;
749
824
}
750
825
@@ -1760,12 +1835,16 @@ LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1760
1835
1761
1836
void PolymorphicInstanceCallComp::EmitNativeCode (FlowGraphCompiler* compiler) {
1762
1837
ASSERT (instance_call ()->VerifyComputation ());
1763
- ASSERT (HasICData ());
1764
- ASSERT (ic_data ()->num_args_tested () == 1 );
1765
1838
Label* deopt = compiler->AddDeoptStub (instance_call ()->cid (),
1766
1839
instance_call ()->token_index (),
1767
1840
instance_call ()->try_index (),
1768
1841
kDeoptPolymorphicInstanceCallTestFail );
1842
+ if (!HasICData () || (ic_data ()->NumberOfChecks () == 0 )) {
1843
+ __ jmp (deopt);
1844
+ return ;
1845
+ }
1846
+ ASSERT (HasICData ());
1847
+ ASSERT (ic_data ()->num_args_tested () == 1 );
1769
1848
Label handle_smi;
1770
1849
Label* is_smi_label =
1771
1850
ic_data ()->GetReceiverClassIdAt (0 ) == kSmi ? &handle_smi : deopt;
@@ -1777,21 +1856,14 @@ void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1777
1856
__ j (ZERO, is_smi_label);
1778
1857
Label done;
1779
1858
__ LoadClassId (EDI, EAX);
1780
- for (intptr_t i = 0 ; i < ic_data ()->NumberOfChecks (); i++) {
1781
- Label next_test;
1782
- __ cmpl (EDI, Immediate (ic_data ()->GetReceiverClassIdAt (i)));
1783
- __ j (NOT_EQUAL, &next_test);
1784
- const Function& target = Function::ZoneHandle (ic_data ()->GetTargetAt (i));
1785
- compiler->GenerateStaticCall (instance_call ()->cid (),
1786
- instance_call ()->token_index (),
1787
- instance_call ()->try_index (),
1788
- target,
1789
- instance_call ()->ArgumentCount (),
1790
- instance_call ()->argument_names ());
1791
- __ jmp (&done);
1792
- __ Bind (&next_test);
1793
- }
1794
- __ jmp (deopt);
1859
+ compiler->EmitTestAndCall (*ic_data (),
1860
+ EDI, // Class id register.
1861
+ instance_call ()->ArgumentCount (),
1862
+ instance_call ()->argument_names (),
1863
+ deopt, &done, // Labels.
1864
+ instance_call ()->cid (),
1865
+ instance_call ()->token_index (),
1866
+ instance_call ()->try_index ());
1795
1867
if (is_smi_label == &handle_smi) {
1796
1868
__ Bind (&handle_smi);
1797
1869
ASSERT (ic_data ()->GetReceiverClassIdAt (0 ) == kSmi );
0 commit comments