@@ -3528,19 +3528,34 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3528
3528
StackSym * stackFuncPtrSym = nullptr ;
3529
3529
SymID symID = m_func->GetJITFunctionBody ()->GetLocalClosureReg ();
3530
3530
bool isLdSlotThatWasNotProfiled = false ;
3531
+ bool stableSlot = false ;
3531
3532
StackSym* closureSym = m_func->GetLocalClosureSym ();
3532
3533
3533
3534
uint scopeSlotSize = this ->IsParamScopeDone () ? m_func->GetJITFunctionBody ()->GetScopeSlotArraySize () : m_func->GetJITFunctionBody ()->GetParamScopeSlotArraySize ();
3534
3535
3535
3536
switch (newOpcode)
3536
3537
{
3538
+ case Js::OpCode::LdStableParamSlot:
3539
+ stableSlot = true ;
3540
+ goto ParamSlotCommon;
3541
+
3537
3542
case Js::OpCode::LdParamSlot:
3543
+ stableSlot = false ;
3544
+
3545
+ ParamSlotCommon:
3538
3546
scopeSlotSize = m_func->GetJITFunctionBody ()->GetParamScopeSlotArraySize ();
3539
3547
closureSym = m_func->GetParamClosureSym ();
3540
3548
symID = m_func->GetJITFunctionBody ()->GetParamClosureReg ();
3541
- // Fall through
3549
+ goto LocalSlotCommon;
3550
+
3551
+ case Js::OpCode::LdStableLocalSlot:
3552
+ stableSlot = true ;
3553
+ goto LocalSlotCommon;
3542
3554
3543
3555
case Js::OpCode::LdLocalSlot:
3556
+ stableSlot = false ;
3557
+
3558
+ LocalSlotCommon:
3544
3559
if (!PHASE_OFF (Js::ClosureRangeCheckPhase, m_func))
3545
3560
{
3546
3561
if ((uint32)slotId >= scopeSlotSize + Js::ScopeSlots::FirstSlotIndex)
@@ -3580,7 +3595,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3580
3595
this ->EnsureLoopBodyLoadSlot (symID);
3581
3596
}
3582
3597
3583
- fieldSym = PropertySym::FindOrCreate (symID, slotId, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func);
3598
+ fieldSym = PropertySym::FindOrCreate (symID, slotId, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func, stableSlot );
3584
3599
fieldOpnd = IR::SymOpnd::New (fieldSym, TyVar, m_func);
3585
3600
regOpnd = this ->BuildDstOpnd (regSlot);
3586
3601
instr = nullptr ;
@@ -3637,16 +3652,32 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3637
3652
this ->AddInstr (instr, offset);
3638
3653
break ;
3639
3654
3655
+ case Js::OpCode::StStableParamSlot:
3656
+ case Js::OpCode::StStableParamSlotChkUndecl:
3657
+ stableSlot = true ;
3658
+ goto StParamSlotCommon;
3659
+
3640
3660
case Js::OpCode::StParamSlot:
3641
3661
case Js::OpCode::StParamSlotChkUndecl:
3662
+ stableSlot = false ;
3663
+
3664
+ StParamSlotCommon:
3642
3665
scopeSlotSize = m_func->GetJITFunctionBody ()->GetParamScopeSlotArraySize ();
3643
3666
closureSym = m_func->GetParamClosureSym ();
3644
3667
symID = m_func->GetJITFunctionBody ()->GetParamClosureReg ();
3645
- newOpcode = newOpcode == Js::OpCode::StParamSlot ? Js::OpCode::StLocalSlot : Js::OpCode::StLocalSlotChkUndecl;
3646
- // Fall through
3668
+ newOpcode = newOpcode == Js::OpCode::StParamSlot || newOpcode == Js::OpCode::StStableParamSlot ? Js::OpCode::StLocalSlot : Js::OpCode::StLocalSlotChkUndecl;
3669
+ goto StLocalSlotCommon;
3670
+
3671
+ case Js::OpCode::StStableLocalSlot:
3672
+ case Js::OpCode::StStableLocalSlotChkUndecl:
3673
+ stableSlot = true ;
3674
+ goto StLocalSlotCommon;
3647
3675
3648
3676
case Js::OpCode::StLocalSlot:
3649
3677
case Js::OpCode::StLocalSlotChkUndecl:
3678
+ stableSlot = false ;
3679
+
3680
+ StLocalSlotCommon:
3650
3681
if (!PHASE_OFF (Js::ClosureRangeCheckPhase, m_func))
3651
3682
{
3652
3683
if ((uint32)slotId >= scopeSlotSize + Js::ScopeSlots::FirstSlotIndex)
@@ -3662,7 +3693,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3662
3693
this ->AddInstr (byteCodeUse, offset);
3663
3694
}
3664
3695
3665
- newOpcode = newOpcode == Js::OpCode::StLocalSlot ? Js::OpCode::StSlot : Js::OpCode::StSlotChkUndecl;
3696
+ newOpcode = newOpcode == Js::OpCode::StLocalSlot || newOpcode == Js::OpCode::StStableLocalSlot ? Js::OpCode::StSlot : Js::OpCode::StSlotChkUndecl;
3666
3697
if (m_func->DoStackFrameDisplay ())
3667
3698
{
3668
3699
regOpnd = IR::RegOpnd::New (TyVar, m_func);
@@ -3687,7 +3718,7 @@ IRBuilder::BuildElementSlotI1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3687
3718
this ->EnsureLoopBodyLoadSlot (symID);
3688
3719
}
3689
3720
}
3690
- fieldSym = PropertySym::FindOrCreate (symID, slotId, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func);
3721
+ fieldSym = PropertySym::FindOrCreate (symID, slotId, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func, stableSlot );
3691
3722
fieldOpnd = IR::SymOpnd::New (fieldSym, TyVar, m_func);
3692
3723
regOpnd = this ->BuildSrcOpnd (regSlot);
3693
3724
instr = IR::Instr::New (newOpcode, fieldOpnd, regOpnd, m_func);
@@ -3882,7 +3913,8 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3882
3913
IR::Instr *instr;
3883
3914
PropertySym *fieldSym;
3884
3915
bool isLdSlotThatWasNotProfiled = false ;
3885
- bool stableSlots = false ;
3916
+ bool stableSlotArray = false ;
3917
+ bool stableSlot = false ;
3886
3918
3887
3919
switch (newOpcode)
3888
3920
{
@@ -3916,19 +3948,26 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3916
3948
break ;
3917
3949
}
3918
3950
3951
+ case Js::OpCode::LdStableEnvSlot:
3952
+ stableSlotArray = true ;
3953
+ stableSlot = true ;
3954
+ goto EnvSlotCommon;
3955
+
3919
3956
case Js::OpCode::LdEnvSlot:
3920
3957
case Js::OpCode::StEnvSlot:
3921
3958
case Js::OpCode::StEnvSlotChkUndecl:
3922
- stableSlots = true ;
3923
- goto SlotsCommon;
3959
+ stableSlotArray = true ;
3960
+ stableSlot = false ;
3961
+ goto EnvSlotCommon;
3924
3962
3925
3963
case Js::OpCode::LdEnvObjSlot:
3926
3964
case Js::OpCode::StEnvObjSlot:
3927
3965
case Js::OpCode::StEnvObjSlotChkUndecl:
3928
- stableSlots = false ;
3966
+ stableSlotArray = false ;
3967
+ stableSlot = false ;
3929
3968
3930
- SlotsCommon :
3931
- fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::LdSlotArr, this ->GetEnvReg (), slotId1, (Js::PropertyIdIndexType)-1 , PropertyKindSlotArray, (uint )-1 , stableSlots );
3969
+ EnvSlotCommon :
3970
+ fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::LdSlotArr, this ->GetEnvReg (), slotId1, (Js::PropertyIdIndexType)-1 , PropertyKindSlotArray, (uint )-1 , stableSlotArray );
3932
3971
regOpnd = IR::RegOpnd::New (TyVar, m_func);
3933
3972
instr = IR::Instr::New (Js::OpCode::LdSlotArr, regOpnd, fieldOpnd, m_func);
3934
3973
this ->AddInstr (instr, offset);
@@ -3953,12 +3992,13 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3953
3992
break ;
3954
3993
}
3955
3994
3956
- fieldSym = PropertySym::New (regOpnd->m_sym , slotId2, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func);
3995
+ fieldSym = PropertySym::New (regOpnd->m_sym , slotId2, (uint32)-1 , (uint )-1 , PropertyKindSlots, m_func, stableSlot );
3957
3996
fieldOpnd = IR::SymOpnd::New (fieldSym, TyVar, m_func);
3958
3997
3959
3998
switch (newOpcode)
3960
3999
{
3961
4000
case Js::OpCode::LdEnvSlot:
4001
+ case Js::OpCode::LdStableEnvSlot:
3962
4002
case Js::OpCode::LdEnvObjSlot:
3963
4003
newOpcode = Js::OpCode::LdSlot;
3964
4004
regOpnd = this ->BuildDstOpnd (regSlot);
@@ -3992,10 +4032,18 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
3992
4032
}
3993
4033
break ;
3994
4034
4035
+ case Js::OpCode::StStableInnerSlot:
4036
+ case Js::OpCode::StStableInnerSlotChkUndecl:
4037
+ stableSlot = true ;
4038
+ goto StInnerSlotCommon;
4039
+
3995
4040
case Js::OpCode::StInnerObjSlot:
3996
4041
case Js::OpCode::StInnerObjSlotChkUndecl:
3997
4042
case Js::OpCode::StInnerSlot:
3998
4043
case Js::OpCode::StInnerSlotChkUndecl:
4044
+ stableSlot = false ;
4045
+
4046
+ StInnerSlotCommon:
3999
4047
if ((uint )slotId1 >= m_func->GetJITFunctionBody ()->GetInnerScopeCount ())
4000
4048
{
4001
4049
Js::Throw::FatalInternalError ();
@@ -4018,15 +4066,15 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
4018
4066
}
4019
4067
else
4020
4068
{
4021
- fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::StSlot, slotId1, slotId2, (Js::PropertyIdIndexType)-1 , PropertyKindSlots);
4069
+ fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::StSlot, slotId1, slotId2, (Js::PropertyIdIndexType)-1 , PropertyKindSlots, ( uint )- 1 , stableSlot );
4022
4070
if (!this ->DoSlotArrayCheck (fieldOpnd, IsLoopBody ()))
4023
4071
{
4024
4072
// Need a dynamic check on the size of the local slot array.
4025
4073
m_func->GetTopFunc ()->AddSlotArrayCheck (fieldOpnd);
4026
4074
}
4027
4075
}
4028
4076
newOpcode =
4029
- newOpcode == Js::OpCode::StInnerObjSlot || newOpcode == Js::OpCode::StInnerSlot ?
4077
+ newOpcode == Js::OpCode::StInnerObjSlot || newOpcode == Js::OpCode::StInnerSlot || newOpcode == Js::OpCode::StStableInnerSlot ?
4030
4078
Js::OpCode::StSlot : Js::OpCode::StSlotChkUndecl;
4031
4079
instr = IR::Instr::New (newOpcode, fieldOpnd, regOpnd, m_func);
4032
4080
if (newOpcode == Js::OpCode::StSlotChkUndecl)
@@ -4038,8 +4086,15 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
4038
4086
4039
4087
break ;
4040
4088
4089
+ case Js::OpCode::LdStableInnerSlot:
4090
+ stableSlot = true ;
4091
+ goto LdInnerSlotCommon;
4092
+
4041
4093
case Js::OpCode::LdInnerSlot:
4042
4094
case Js::OpCode::LdInnerObjSlot:
4095
+ stableSlot = false ;
4096
+
4097
+ LdInnerSlotCommon:
4043
4098
if ((uint )slotId1 >= m_func->GetJITFunctionBody ()->GetInnerScopeCount ())
4044
4099
{
4045
4100
Js::Throw::FatalInternalError ();
@@ -4061,7 +4116,7 @@ IRBuilder::BuildElementSlotI2(Js::OpCode newOpcode, uint32 offset, Js::RegSlot r
4061
4116
}
4062
4117
else
4063
4118
{
4064
- fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::LdSlot, slotId1, slotId2, (Js::PropertyIdIndexType)-1 , PropertyKindSlots);
4119
+ fieldOpnd = this ->BuildFieldOpnd (Js::OpCode::LdSlot, slotId1, slotId2, (Js::PropertyIdIndexType)-1 , PropertyKindSlots, ( uint )- 1 , stableSlot );
4065
4120
if (!this ->DoSlotArrayCheck (fieldOpnd, IsLoopBody ()))
4066
4121
{
4067
4122
// Need a dynamic check on the size of the local slot array.
0 commit comments