@@ -180,187 +180,6 @@ LinearScanMD::GenerateBailOut(IR::Instr * instr, __in_ecount(registerSaveSymsCou
180
180
}
181
181
}
182
182
183
- IR::Instr *
184
- LinearScanMD::GenerateBailInForGeneratorYield (IR::Instr * resumeLabelInstr, BailOutInfo * bailOutInfo)
185
- {
186
- BailOutRecord * bailOutRecord = bailOutInfo->bailOutRecord ;
187
- IR::Instr * instrAfter = resumeLabelInstr->m_next ;
188
- IR::Instr * newInstr;
189
-
190
- // if (argOuts) {
191
- // sub esp, numArgOutsTimesMachSizeMachAligned
192
- // }
193
- // mov eax, prm1
194
- // mov eax, [eax + offset of JavascriptGenerator::frame]
195
- // <restore live stack syms, out params, and registers directly from InterpreterStackFrame registers (use ecx as temporary for mov IndirOpnd, IndirOpnd before restoring registers)>
196
-
197
- IntConstType stackAdjustSize = 0 ;
198
- bailOutRecord->MapStartCallParamCounts ([&stackAdjustSize](uint startCallParamCount) {
199
- IntConstType sizeValue = startCallParamCount;
200
- int32 stackAlignment = Math::Align<int32>(sizeValue*MachPtr, MachStackAlignment) - sizeValue*MachPtr;
201
- if (stackAlignment != 0 )
202
- {
203
- sizeValue += 1 ;
204
- }
205
- sizeValue *= MachPtr;
206
- stackAdjustSize += sizeValue;
207
- });
208
-
209
- if (stackAdjustSize != 0 )
210
- {
211
- if ((uint32)stackAdjustSize > AutoSystemInfo::PageSize)
212
- {
213
- // mov eax, sizeOpnd->m_value
214
- // call _chkstk
215
- IR::RegOpnd *eaxOpnd = IR::RegOpnd::New (nullptr , RegEAX, TyMachReg, this ->func );
216
- newInstr = IR::Instr::New (Js::OpCode::MOV, eaxOpnd, IR::IntConstOpnd::New (stackAdjustSize, TyInt32, this ->func ), this ->func );
217
- instrAfter->InsertBefore (newInstr);
218
-
219
- newInstr = IR::Instr::New (Js::OpCode::CALL, this ->func );
220
- newInstr->SetSrc1 (IR::HelperCallOpnd::New (IR::HelperCRT_chkstk, this ->func ));
221
- instrAfter->InsertBefore (newInstr);
222
- this ->func ->SetHasCallsOnSelfAndParents ();
223
- }
224
- else
225
- {
226
- // lea esp, [esp - sizeValue]
227
- IR::RegOpnd * espOpnd = IR::RegOpnd::New (nullptr , LowererMD::GetRegStackPointer (), TyMachReg, this ->func );
228
- newInstr = IR::Instr::New (Js::OpCode::LEA, espOpnd, IR::IndirOpnd::New (espOpnd, -stackAdjustSize, TyMachReg, this ->func ), this ->func );
229
- instrAfter->InsertBefore (newInstr);
230
- }
231
- }
232
-
233
- IR::RegOpnd * eaxRegOpnd = IR::RegOpnd::New (nullptr , RegEAX, TyMachPtr, this ->func );
234
- IR::RegOpnd * ecxRegOpnd = IR::RegOpnd::New (nullptr , RegECX, TyVar, this ->func );
235
-
236
- StackSym * sym = StackSym::NewParamSlotSym (1 , this ->func );
237
- this ->func ->SetArgOffset (sym, LowererMD::GetFormalParamOffset () * MachPtr);
238
- IR::SymOpnd * symOpnd = IR::SymOpnd::New (sym, TyMachPtr, this ->func );
239
- newInstr = IR::Instr::New (Js::OpCode::MOV, eaxRegOpnd, symOpnd, this ->func );
240
- instrAfter->InsertBefore (newInstr);
241
-
242
- IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New (eaxRegOpnd, Js::JavascriptGenerator::GetFrameOffset (), TyMachPtr, this ->func );
243
- newInstr = IR::Instr::New (Js::OpCode::MOV, eaxRegOpnd, indirOpnd, this ->func );
244
- instrAfter->InsertBefore (newInstr);
245
-
246
-
247
- // eax points to the frame, restore stack syms and registers except eax, restore eax last
248
-
249
- IR::Instr * eaxRestoreInstr = nullptr ;
250
- IR::Instr * instrInsertStackSym = instrAfter;
251
- IR::Instr * instrInsertRegSym = instrAfter;
252
-
253
- Assert (bailOutInfo->capturedValues ->constantValues .Empty ());
254
- Assert (bailOutInfo->capturedValues ->copyPropSyms .Empty ());
255
-
256
- auto restoreSymFn = [this , &eaxRegOpnd, &ecxRegOpnd, &eaxRestoreInstr, &instrInsertStackSym, &instrInsertRegSym](SymID symId)
257
- {
258
- StackSym * stackSym = this ->func ->m_symTable ->FindStackSym (symId);
259
- Assert (stackSym->IsVar ());
260
-
261
- Assert (stackSym->HasByteCodeRegSlot ());
262
- Js::RegSlot byteCodeReg = stackSym->GetByteCodeRegSlot ();
263
- int32 offset = byteCodeReg * sizeof (Js::Var) + Js::InterpreterStackFrame::GetOffsetOfLocals ();
264
-
265
- IR::Opnd * srcOpnd = IR::IndirOpnd::New (eaxRegOpnd, offset, stackSym->GetType (), this ->func );
266
- Lifetime * lifetime = stackSym->scratch .linearScan .lifetime ;
267
-
268
- if (lifetime->isSpilled )
269
- {
270
- // stack restores require an extra register since we can't move an indir directly to an indir on x86
271
- IR::Instr * instr = IR::Instr::New (Js::OpCode::MOV, ecxRegOpnd, srcOpnd, this ->func );
272
- instrInsertStackSym->InsertBefore (instr);
273
-
274
- IR::SymOpnd * dstOpnd = IR::SymOpnd::New (stackSym, stackSym->GetType (), this ->func );
275
- instr = IR::Instr::New (Js::OpCode::MOV, dstOpnd, ecxRegOpnd, this ->func );
276
- instrInsertStackSym->InsertBefore (instr);
277
- }
278
- else
279
- {
280
- // register restores must come after stack restores so that we have EAX and ECX free to
281
- // use for stack restores and further EAX must be restored last since it holds the
282
- // pointer to the InterpreterStackFrame from which we are restoring values.
283
- // We must also track these restores using RecordDef in case the symbols are spilled.
284
-
285
- IR::RegOpnd * dstRegOpnd = IR::RegOpnd::New (stackSym, stackSym->GetType (), this ->func );
286
- dstRegOpnd->SetReg (lifetime->reg );
287
-
288
- IR::Instr * instr = IR::Instr::New (Js::OpCode::MOV, dstRegOpnd, srcOpnd, this ->func );
289
- instrInsertRegSym->InsertBefore (instr);
290
-
291
- if (instrInsertRegSym == instrInsertStackSym)
292
- {
293
- // this is the first register sym, make sure we don't insert stack stores
294
- // after this instruction so we can ensure eax and ecx remain free to use
295
- // for restoring spilled stack syms.
296
- instrInsertStackSym = instr;
297
- }
298
-
299
- if (lifetime->reg == RegEAX)
300
- {
301
- // ensure eax is restored last
302
- Assert (instrInsertRegSym != instrInsertStackSym);
303
-
304
- instrInsertRegSym = instr;
305
-
306
- if (eaxRestoreInstr != nullptr )
307
- {
308
- AssertMsg (false , " this is unexpected until copy prop is enabled" );
309
- // eax was mapped to multiple bytecode registers. Obviously only the first
310
- // restore we do will work so change all following stores to `mov eax, eax`.
311
- // We still need to keep them around for RecordDef in case the corresponding
312
- // dst sym is spilled later on.
313
- eaxRestoreInstr->FreeSrc1 ();
314
- eaxRestoreInstr->SetSrc1 (eaxRegOpnd);
315
- }
316
-
317
- eaxRestoreInstr = instr;
318
- }
319
-
320
- this ->linearScan ->RecordDef (lifetime, instr, 0 );
321
- }
322
- };
323
-
324
- FOREACH_BITSET_IN_SPARSEBV (symId, bailOutInfo->byteCodeUpwardExposedUsed )
325
- {
326
- restoreSymFn (symId);
327
- }
328
- NEXT_BITSET_IN_SPARSEBV;
329
-
330
- if (bailOutInfo->capturedValues ->argObjSyms )
331
- {
332
- FOREACH_BITSET_IN_SPARSEBV (symId, bailOutInfo->capturedValues ->argObjSyms )
333
- {
334
- restoreSymFn (symId);
335
- }
336
- NEXT_BITSET_IN_SPARSEBV;
337
- }
338
-
339
- // Restore out params.
340
- // Would be nice to use restoreSymFn on a walk of the SymIds where the walk matches
341
- // the logic in LinearScan::FillBailOutRecord, but the walk is very complicated and
342
- // requires state to enumerate the exact syms that are actually mapped in the bail
343
- // out record. So instead, since we have disabled most of GlobOpt for the time
344
- // being, just enumerate the argouts from the BailOutRecord and ignore the syms.
345
- // This may need to be improved to use the syms when the optimizations are brought
346
- // online.
347
- bailOutRecord->MapArgOutOffsets ([this , &eaxRegOpnd, &ecxRegOpnd, &instrInsertStackSym](Js::RegSlot regSlot, int32 stackOffset) {
348
- // mov ecx, [eax + bytecode reg offset]
349
- // mov [ebp + native stack offset], ecx
350
- int32 regSlotOffset = Js::InterpreterStackFrame::GetOffsetOfLocals () + (this ->func ->GetJITFunctionBody ()->GetLocalsCount () + regSlot) * sizeof (Js::Var);
351
- IR::IndirOpnd * indirOpnd = IR::IndirOpnd::New (eaxRegOpnd, regSlotOffset, TyVar, this ->func );
352
- IR::Instr * instr = IR::Instr::New (Js::OpCode::MOV, ecxRegOpnd, indirOpnd, this ->func );
353
- instrInsertStackSym->InsertBefore (instr);
354
-
355
- IR::RegOpnd* ebpRegOpnd = IR::RegOpnd::New (nullptr , RegEBP, TyMachPtr, this ->func );
356
- indirOpnd = IR::IndirOpnd::New (ebpRegOpnd, stackOffset, TyVar, this ->func );
357
- instr = IR::Instr::New (Js::OpCode::RestoreOutParam, indirOpnd, ecxRegOpnd, this ->func );
358
- instrInsertStackSym->InsertBefore (instr);
359
- });
360
-
361
- return instrAfter;
362
- }
363
-
364
183
__declspec (naked) void LinearScanMD::SaveAllRegisters(BailOutRecord *const bailOutRecord)
365
184
{
366
185
__asm
0 commit comments