فهرست منبع

[MERGE #1938 @satheeshravi] Enabling StackArgs optimization for strict mode with writes to formals

Merge pull request #1938 from satheeshravi:StackArgsPartial

- Strict mode doesn't maintain mapping between named formals and arguments
  object elements.
- All named formals will have ArgIn instructions and are local registers -
  Hence we can let write to formals to happen.
Satheesh Ravindranath 9 سال پیش
والد
کامیت
3daecc403b

+ 8 - 6
lib/Backend/BailOut.h

@@ -466,12 +466,14 @@ struct GlobalBailOutRecordDataTable
     int32  firstActualStackOffset;
     int forInEnumeratorArrayRestoreOffset;
     Js::RegSlot returnValueRegSlot;
-    bool isInlinedFunction;
-    bool isInlinedConstructor;
-    bool isLoopBody;
-    bool hasNonSimpleParams;
-    bool hasStackArgOpt;
-    bool isScopeObjRestored;
+
+    bool isInlinedFunction      : 1;
+    bool isInlinedConstructor   : 1;
+    bool isLoopBody             : 1;
+    bool hasNonSimpleParams     : 1;
+    bool hasStackArgOpt         : 1;
+    bool isScopeObjRestored     : 1;
+
     void Finalize(NativeCodeData::Allocator *allocator, JitArenaAllocator *tempAlloc);
     void AddOrUpdateRow(JitArenaAllocator *allocator, uint32 bailOutRecordId, uint32 regSlot, bool isFloat, bool isInt,
         bool isSimd128F4, bool isSimd128I4, bool isSimd128I8, bool isSimd128I16, bool isSimd128U4, bool isSimd128U8, bool isSimd128U16, bool isSimd128B4, bool isSimd128B8, bool isSimd128B16,

+ 2 - 3
lib/Runtime/ByteCode/ByteCodeGenerator.cpp

@@ -2345,16 +2345,15 @@ FuncInfo* PreVisitFunction(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerato
             funcInfo->GetParsedFunctionBody()->SetUsesArgumentsObject(true);
             if (pnode->sxFnc.HasHeapArguments())
             {
-                bool doStackArgsOpt = !pnode->sxFnc.HasAnyWriteToFormals();
+                bool doStackArgsOpt = (!pnode->sxFnc.HasAnyWriteToFormals() || funcInfo->GetIsStrictMode());
 #ifdef PERF_HINT
                 if (PHASE_TRACE1(Js::PerfHintPhase) && !doStackArgsOpt)
                 {
                     WritePerfHint(PerfHints::HeapArgumentsDueToWriteToFormals, funcInfo->GetParsedFunctionBody(), 0);
                 }
 #endif
-                //Go conservative if it has any nested functions, or any non-local references.
+                
                 //With statements - need scope object to be present.
-                //Nested funtions - need scope object to be present - LdEnv/LdFrameDisplay needs it.
                 if ((doStackArgsOpt && pnode->sxFnc.funcInfo->GetParamScope()->Count() > 1) && (pnode->sxFnc.funcInfo->HasDeferredChild() || (byteCodeGenerator->GetFlags() & fscrEval) ||
                     pnode->sxFnc.HasWithStmt() || byteCodeGenerator->IsInDebugMode() || PHASE_OFF1(Js::StackArgFormalsOptPhase) || PHASE_OFF1(Js::StackArgOptPhase)))
                 {

+ 1 - 0
test/Function/StackArgsWithFormals.baseline

@@ -20,4 +20,5 @@ StackArgFormals : test16 (22) :Removing Scope object creation in Lowerer and rep
 StackArgFormals : test16 (22) :Attaching the scope object with the heap arguments object in the bail out path. 
 StackArgFormals : test17 (23) :Removing Heap Arguments object creation in Lowerer. 
 StackArgFormals : test17 (23) :Attaching the scope object with the heap arguments object in the bail out path. 
+StackArgFormals : test19 (25) :Removing Heap Arguments object creation in Lowerer. 
 PASSED

+ 11 - 0
test/Function/StackArgsWithFormals.js

@@ -280,6 +280,17 @@ function test18()
 test18();
 verify([2, 6], "TEST18");
 
+function test19(a, b)
+{
+    'use strict';
+    b++;
+    actuals.push(arguments[0] + b);
+}
+
+test19(1, 2);
+test19(3, 4);
+verify([4, 8], "TEST 19");
+
 if(hasAllPassed)
 {
     print("PASSED");