You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enabling Stack Args when there is presence of nested functions.
Premise:
The initial implementation of Stack Args was disabled when there is any
nested function.
We were missing a bunch of opportunities in the real world web pages - where nested function is a common thing.
This PR enables this optimization for nested function.
Summary:
Stack Args will work partially when nested functions are present. We will
attempt to remove only Heap Arguments Object creation instr and retain
scope object creation instr (whenever required).
Details:
ByteCodeGeneration:
- We track if there are any params being closure captured by any nested functions
- We give up the optimization if this is case.
- We track if there are any non-local references inside the nested
function.
- We do Stack Args partially here - i.e. we attempt to remove Heap Arguments Object creation but still create scope object - as scope
object is required for FrameDisplay.
IRBuilder:
- Scope object tracking has been moved from Forward pass (Globopt) to this phase.
- This enables us to mark the scope obj sym to be live during the
first backward pass.
Backward pass:
- Scope Object Sym is kept alive in all code paths.
- This is to facilitate Bailout to record the live Scope object Sym, whenever required.
- Reason for doing is this because - Scope object has to be implicitly live whenever Heap Arguments object is live.
- When we restore HeapArguments object in the bail out path, it expects the scope object also to be restored - if one was created.
- We do not know detailed information about Heap arguments obj syms(aliasing etc.) until we complete Forward Pass.
- And we want to avoid dead sym clean up (in this case, scope object though not explicitly live, it is live implicitly) during Block merging in the forward pass.
Globopt pass:
- Extra tracking for instrs having arguments object is done.
Dead Store pass:
- Scope obj creation instruction is not dead stored - It will be a MOV NULL instr in the Lowerer.
- All instrs related cached scope obj is deadstored. Reason is to dead
store the cached scope object creation instruction itself.
- InitCachedFuncs is deadstored.
- GetCachedFunc is replaced with NewScFunc instr.
Lowerer pass:
- If Stack Args optimization is still turned on and the parser has hinted that Scope obj creation is not required, then scope object creation instruction will be turned to a MOV NULL.
- We retain the instruction and not remove it because we want the value of the scope object to be restored
- That's when we can always rely on the bail out path to restore some
valid value (NULL or the scope object itself).
BailOut path:
- We use the restored scope object value (we track this by using a flag on the bailoutInfo) and copy the param values to it.
Added UT and some more traces
Fixing a bug with the Type of Scope object. Type wasn't being transitioned
correctly in cases where we remove LdHeapArguments opcode.
Took care of review comments.
Review Comments
* Scope Object Sym is kept alive in all code paths.
3104
+
* -This is to facilitate Bailout to record the live Scope object Sym, whenever required.
3105
+
* -Reason for doing is this because - Scope object has to be implicitly live whenever Heap Arguments object is live.
3106
+
* -When we restore HeapArguments object in the bail out path, it expects the scope object also to be restored - if one was created.
3107
+
* -We do not know detailed information about Heap arguments obj syms(aliasing etc.) until we complete Forward Pass.
3108
+
* -And we want to avoid dead sym clean up (in this case, scope object though not explicitly live, it is live implicitly) during Block merging in the forward pass.
3109
+
* -Hence this is the optimal spot to do this.
3110
+
*/
3111
+
3112
+
if (tag == Js::BackwardPhase && instr->m_func->GetScopeObjSym() != nullptr)
0 commit comments