@@ -5400,11 +5400,10 @@ Lowerer::LoadFunctionBodyAsArgument(IR::Instr *instr, IR::IntConstOpnd * functio
5400
5400
// At which point the deferred function proxy may be collect.
5401
5401
// Just pass it the address where we will find the function proxy/body
5402
5402
5403
- intptr_t proxyRef = instr->m_func->GetJITFunctionBody()->GetNestedFuncRef((uint)functionBodySlotOpnd->GetValue());
5404
- AssertMsg(proxyRef, "Expected FunctionProxy for index of NewScFunc or NewScGenFunc opnd");
5405
- //AssertMsg(*proxyRef, "Expected FunctionProxy for index of NewScFunc or NewScGenFunc opnd");
5403
+ Js::FunctionInfoPtrPtr infoRef = instr->m_func->GetJITFunctionBody()->GetNestedFuncRef((uint)functionBodySlotOpnd->GetValue());
5404
+ AssertMsg(infoRef, "Expected FunctionProxy for index of NewScFunc or NewScGenFunc opnd");
5406
5405
5407
- IR::AddrOpnd * indexOpnd = IR::AddrOpnd::New((Js::Var)proxyRef , IR::AddrOpndKindDynamicMisc, m_func);
5406
+ IR::AddrOpnd * indexOpnd = IR::AddrOpnd::New((Js::Var)infoRef , IR::AddrOpndKindDynamicMisc, m_func);
5408
5407
instrPrev = m_lowererMD.LoadHelperArgument(instr, indexOpnd);
5409
5408
5410
5409
m_lowererMD.LoadHelperArgument(instr, envOpnd);
@@ -6090,7 +6089,7 @@ Lowerer::LowerIsInst(IR::Instr * isInstInstr, IR::JnHelperMethod helperMethod)
6090
6089
}
6091
6090
6092
6091
void
6093
- Lowerer::GenerateStackScriptFunctionInit(StackSym * stackSym, intptr_t nestedProxy )
6092
+ Lowerer::GenerateStackScriptFunctionInit(StackSym * stackSym, Js::FunctionInfoPtrPtr nestedInfo )
6094
6093
{
6095
6094
Func * func = this->m_func;
6096
6095
Assert(func->HasAnyStackNestedFunc());
@@ -6104,7 +6103,7 @@ Lowerer::GenerateStackScriptFunctionInit(StackSym * stackSym, intptr_t nestedPro
6104
6103
6105
6104
// Currently we don't initialize the environment until we actually allocate the function, we also
6106
6105
// walk the list of stack function when we need to box them. so we should use initialize it to NullFrameDisplay
6107
- GenerateStackScriptFunctionInit(addressOpnd, nestedProxy ,
6106
+ GenerateStackScriptFunctionInit(addressOpnd, nestedInfo ,
6108
6107
IR::AddrOpnd::New(func->GetThreadContextInfo()->GetNullFrameDisplayAddr(), IR::AddrOpndKindDynamicMisc, func), insertBeforeInstr);
6109
6108
6110
6109
// Establish the next link
@@ -6114,26 +6113,28 @@ Lowerer::GenerateStackScriptFunctionInit(StackSym * stackSym, intptr_t nestedPro
6114
6113
6115
6114
void
6116
6115
Lowerer::GenerateScriptFunctionInit(IR::RegOpnd * regOpnd, IR::Opnd * vtableAddressOpnd,
6117
- intptr_t nestedProxy , IR::Opnd * envOpnd, IR::Instr * insertBeforeInstr, bool isZeroed)
6116
+ Js::FunctionInfoPtrPtr nestedInfo , IR::Opnd * envOpnd, IR::Instr * insertBeforeInstr, bool isZeroed)
6118
6117
{
6119
6118
Func * func = this->m_func;
6120
6119
IR::Opnd * functionProxyOpnd;
6120
+ IR::Opnd * functionInfoOpnd = nullptr;
6121
6121
IR::Opnd * typeOpnd = nullptr;
6122
6122
bool doCheckTypeOpnd = true;
6123
- if (m_func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts) || (*(Js::FunctionProxy **)nestedProxy )->IsDeferred())
6123
+ if (m_func->IsOOPJIT() || !CONFIG_FLAG(OOPJITMissingOpts) || (*nestedInfo )->IsDeferred())
6124
6124
{
6125
+ functionInfoOpnd = IR::RegOpnd::New(TyMachPtr, func);
6126
+ InsertMove(functionInfoOpnd, IR::MemRefOpnd::New(nestedInfo, TyMachPtr, func), insertBeforeInstr);
6125
6127
functionProxyOpnd = IR::RegOpnd::New(TyMachPtr, func);
6126
- InsertMove(functionProxyOpnd, IR::MemRefOpnd ::New(nestedProxy , TyMachPtr, func), insertBeforeInstr);
6128
+ InsertMove(functionProxyOpnd, IR::IndirOpnd ::New(functionInfoOpnd->AsRegOpnd(), Js::FunctionInfo::GetOffsetOfFunctionProxy() , TyMachPtr, func), insertBeforeInstr);
6127
6129
typeOpnd = IR::RegOpnd::New(TyMachPtr, func);
6128
6130
InsertMove(typeOpnd, IR::IndirOpnd::New(functionProxyOpnd->AsRegOpnd(), Js::FunctionProxy::GetOffsetOfDeferredPrototypeType(),
6129
6131
TyMachPtr, func), insertBeforeInstr);
6130
6132
}
6131
6133
else
6132
6134
{
6133
- Js::FunctionProxy * functionProxy = *(Js::FunctionProxy **)nestedProxy;
6134
- Js::FunctionBody * functionBody = functionProxy->GetFunctionBody();
6135
+ Js::FunctionBody * functionBody = (*nestedInfo)->GetFunctionBody();
6135
6136
functionProxyOpnd = CreateFunctionBodyOpnd(functionBody);
6136
- Js::ScriptFunctionType * type = functionProxy ->GetDeferredPrototypeType();
6137
+ Js::ScriptFunctionType * type = functionBody ->GetDeferredPrototypeType();
6137
6138
if (type != nullptr)
6138
6139
{
6139
6140
typeOpnd = IR::AddrOpnd::New(type, IR::AddrOpndKindDynamicType, func);
@@ -6171,14 +6172,16 @@ Lowerer::GenerateScriptFunctionInit(IR::RegOpnd * regOpnd, IR::Opnd * vtableAddr
6171
6172
GenerateMemInit(regOpnd, Js::ScriptFunction::GetOffsetOfConstructorCache(),
6172
6173
LoadLibraryValueOpnd(insertBeforeInstr, LibraryValue::ValueConstructorCacheDefaultInstance),
6173
6174
insertBeforeInstr, isZeroed);
6174
- IR::Opnd *functionInfoOpnd;
6175
- if (functionProxyOpnd->IsRegOpnd())
6175
+ if (!functionInfoOpnd)
6176
6176
{
6177
- functionInfoOpnd = IR::IndirOpnd::New(functionProxyOpnd->AsRegOpnd(), Js::FunctionProxy::GetOffsetOfFunctionInfo(), TyMachReg, func);
6178
- }
6179
- else
6180
- {
6181
- functionInfoOpnd = IR::MemRefOpnd::New((BYTE*)functionProxyOpnd->AsAddrOpnd()->m_address + Js::FunctionProxy::GetOffsetOfFunctionInfo(), TyMachReg, func);
6177
+ if (functionProxyOpnd->IsRegOpnd())
6178
+ {
6179
+ functionInfoOpnd = IR::IndirOpnd::New(functionProxyOpnd->AsRegOpnd(), Js::FunctionProxy::GetOffsetOfFunctionInfo(), TyMachReg, func);
6180
+ }
6181
+ else
6182
+ {
6183
+ functionInfoOpnd = IR::MemRefOpnd::New((BYTE*)functionProxyOpnd->AsAddrOpnd()->m_address + Js::FunctionProxy::GetOffsetOfFunctionInfo(), TyMachReg, func);
6184
+ }
6182
6185
}
6183
6186
GenerateMemInit(regOpnd, Js::ScriptFunction::GetOffsetOfFunctionInfo(), functionInfoOpnd, insertBeforeInstr, isZeroed);
6184
6187
GenerateMemInit(regOpnd, Js::ScriptFunction::GetOffsetOfEnvironment(), envOpnd, insertBeforeInstr, isZeroed);
@@ -6187,12 +6190,12 @@ Lowerer::GenerateScriptFunctionInit(IR::RegOpnd * regOpnd, IR::Opnd * vtableAddr
6187
6190
}
6188
6191
6189
6192
void
6190
- Lowerer::GenerateStackScriptFunctionInit(IR::RegOpnd * regOpnd, intptr_t nestedProxy , IR::Opnd * envOpnd, IR::Instr * insertBeforeInstr)
6193
+ Lowerer::GenerateStackScriptFunctionInit(IR::RegOpnd * regOpnd, Js::FunctionInfoPtrPtr nestedInfo , IR::Opnd * envOpnd, IR::Instr * insertBeforeInstr)
6191
6194
{
6192
6195
Func * func = this->m_func;
6193
6196
GenerateScriptFunctionInit(regOpnd,
6194
6197
LoadVTableValueOpnd(insertBeforeInstr, VTableValue::VtableStackScriptFunction),
6195
- nestedProxy , envOpnd, insertBeforeInstr);
6198
+ nestedInfo , envOpnd, insertBeforeInstr);
6196
6199
InsertMove(IR::IndirOpnd::New(regOpnd, Js::StackScriptFunction::GetOffsetOfBoxedScriptFunction(), TyMachPtr, func),
6197
6200
IR::AddrOpnd::NewNull(func), insertBeforeInstr);
6198
6201
}
@@ -6245,7 +6248,7 @@ Lowerer::GenerateNewStackScFunc(IR::Instr * newScFuncInstr, IR::RegOpnd ** ppEnv
6245
6248
IR::IntConstOpnd::New(Js::FunctionBody::Flags_StackNestedFunc, TyInt8, func, true),
6246
6249
Js::OpCode::BrEq_A, labelNoStackFunc, newScFuncInstr);
6247
6250
6248
- intptr_t nestedProxy = func->GetJITFunctionBody()->GetNestedFuncRef(index);
6251
+ Js::FunctionInfoPtrPtr nestedInfo = func->GetJITFunctionBody()->GetNestedFuncRef(index);
6249
6252
IR::Instr * instrAssignDst;
6250
6253
IR::RegOpnd * envOpnd = *ppEnvOpnd;
6251
6254
if (!func->IsLoopBody())
@@ -6254,7 +6257,7 @@ Lowerer::GenerateNewStackScFunc(IR::Instr * newScFuncInstr, IR::RegOpnd ** ppEnv
6254
6257
StackSym * stackSym = StackSym::New(TyMisc, func);
6255
6258
// ScriptFunction and it's next pointer
6256
6259
this->m_func->StackAllocate(stackSym, sizeof(Js::StackScriptFunction) + sizeof(Js::StackScriptFunction *));
6257
- GenerateStackScriptFunctionInit(stackSym, nestedProxy );
6260
+ GenerateStackScriptFunctionInit(stackSym, nestedInfo );
6258
6261
6259
6262
InsertMove(IR::SymOpnd::New(stackSym, Js::ScriptFunction::GetOffsetOfEnvironment(), TyMachPtr, func),
6260
6263
envOpnd,
@@ -14283,22 +14286,65 @@ IR::Instr *Lowerer::InsertConvertFloat64ToFloat32(
14283
14286
return instr;
14284
14287
}
14285
14288
14286
- void Lowerer::InsertIncUInt8PreventOverflow (
14289
+ void Lowerer::InsertDecUInt32PreventOverflow (
14287
14290
IR::Opnd *const dst,
14288
14291
IR::Opnd *const src,
14289
14292
IR::Instr *const insertBeforeInstr,
14290
14293
IR::Instr * *const onOverflowInsertBeforeInstrRef)
14291
14294
{
14292
- LowererMD::InsertIncUInt8PreventOverflow(dst, src, insertBeforeInstr, onOverflowInsertBeforeInstrRef);
14293
- }
14295
+ Assert(dst);
14296
+ Assert(dst->GetType() == TyUint32);
14297
+ Assert(src);
14298
+ Assert(src->GetType() == TyUint32);
14299
+ Assert(insertBeforeInstr);
14294
14300
14295
- void Lowerer::InsertDecUInt8PreventOverflow(
14296
- IR::Opnd *const dst,
14297
- IR::Opnd *const src,
14298
- IR::Instr *const insertBeforeInstr,
14299
- IR::Instr * *const onOverflowInsertBeforeInstrRef)
14300
- {
14301
- LowererMD::InsertDecUInt8PreventOverflow(dst, src, insertBeforeInstr, onOverflowInsertBeforeInstrRef);
14301
+ Func *const func = insertBeforeInstr->m_func;
14302
+
14303
+ // Generate:
14304
+ // subs temp, src, 1
14305
+ // bcs $overflow
14306
+ // mov dst, temp
14307
+ // b $continue
14308
+ // $overflow:
14309
+ // mov dst, 0
14310
+ // $continue:
14311
+
14312
+ IR::LabelInstr *const overflowLabel = Lowerer::InsertLabel(false, insertBeforeInstr);
14313
+
14314
+ // subs temp, src, 1
14315
+ IR::RegOpnd *const tempOpnd = IR::RegOpnd::New(StackSym::New(TyUint32, func), TyUint32, func);
14316
+ const IR::AutoReuseOpnd autoReuseTempOpnd(tempOpnd, func);
14317
+ Lowerer::InsertSub(true, tempOpnd, src, IR::IntConstOpnd::New(1, TyUint32, func, true), overflowLabel);
14318
+
14319
+ // bcs $overflow
14320
+ Lowerer::InsertBranch(Js::OpCode::BrLt_A, true, overflowLabel, overflowLabel);
14321
+
14322
+ // mov dst, temp
14323
+ Lowerer::InsertMove(dst, tempOpnd, overflowLabel);
14324
+
14325
+ const bool dstEqualsSrc = dst->IsEqual(src);
14326
+ if(!dstEqualsSrc || onOverflowInsertBeforeInstrRef)
14327
+ {
14328
+ // b $continue
14329
+ // $overflow:
14330
+ // mov dst, 0
14331
+ // $continue:
14332
+ IR::LabelInstr *const continueLabel = Lowerer::InsertLabel(false, insertBeforeInstr);
14333
+ Lowerer::InsertBranch(Js::OpCode::Br, continueLabel, overflowLabel);
14334
+ if(!dstEqualsSrc)
14335
+ {
14336
+ Lowerer::InsertMove(dst, IR::IntConstOpnd::New(0, TyUint32, func, true), continueLabel);
14337
+ }
14338
+
14339
+ if(onOverflowInsertBeforeInstrRef)
14340
+ {
14341
+ *onOverflowInsertBeforeInstrRef = continueLabel;
14342
+ }
14343
+ }
14344
+ else
14345
+ {
14346
+ // $overflow:
14347
+ }
14302
14348
}
14303
14349
14304
14350
void Lowerer::InsertFloatCheckForZeroOrNanBranch(
@@ -21619,18 +21665,16 @@ void Lowerer::LowerFunctionBodyCallCountChange(IR::Instr *const insertBeforeInst
21619
21665
IR::AddrOpnd::New((Js::Var)func->GetWorkItem()->GetCallsCountAddress(), IR::AddrOpndKindDynamicMisc, func, true),
21620
21666
insertBeforeInstr);
21621
21667
21622
- IR::IndirOpnd *const countOpnd = IR::IndirOpnd::New(countAddressOpnd, 0, TyUint8 , func);
21668
+ IR::IndirOpnd *const countOpnd = IR::IndirOpnd::New(countAddressOpnd, 0, TyUint32 , func);
21623
21669
const IR::AutoReuseOpnd autoReuseCountOpnd(countOpnd, func);
21624
21670
if(!isSimpleJit)
21625
21671
{
21626
- // InsertIncUint8PreventOverflow [countAddress]
21627
- InsertIncUInt8PreventOverflow(countOpnd, countOpnd, insertBeforeInstr);
21672
+ InsertAdd(false, countOpnd, countOpnd, IR::IntConstOpnd::New(1, TyUint32, func), insertBeforeInstr);
21628
21673
return;
21629
21674
}
21630
21675
21631
- // InsertDecUint8PreventOverflow [countAddress]
21632
21676
IR::Instr *onOverflowInsertBeforeInstr;
21633
- InsertDecUInt8PreventOverflow (
21677
+ InsertDecUInt32PreventOverflow (
21634
21678
countOpnd,
21635
21679
countOpnd,
21636
21680
insertBeforeInstr,
0 commit comments