@@ -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