Bläddra i källkod

Phase Two Changes

Jeffrey Lin 7 år sedan
förälder
incheckning
8aa44c3662
4 ändrade filer med 46 tillägg och 8 borttagningar
  1. 2 0
      lib/Backend/Func.cpp
  2. 2 0
      lib/Backend/Func.h
  3. 17 4
      lib/Backend/GlobOpt.cpp
  4. 25 4
      lib/Backend/GlobOptBailOut.cpp

+ 2 - 0
lib/Backend/Func.cpp

@@ -66,6 +66,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
     m_hasCalls(false),
     m_hasInlineArgsOpt(false),
     m_canDoInlineArgsOpt(true),
+    unoptableInlineArgCount(0),
     m_doFastPaths(false),
     hasBailout(false),
     firstIRTemp(0),
@@ -108,6 +109,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
     loopCount(0),
     callSiteIdInParentFunc(callSiteIdInParentFunc),
     isGetterSetter(isGetterSetter),
+    cachedInlineeFrameInfo(nullptr),
     frameInfo(nullptr),
     isTJLoopBody(false),
     m_nativeCodeDataSym(nullptr),

+ 2 - 0
lib/Backend/Func.h

@@ -725,7 +725,9 @@ public:
     StackSym *          tempSymDouble;
     StackSym *          tempSymBool;
     uint32              loopCount;
+    uint32              unoptableInlineArgCount;
     Js::ProfileId       callSiteIdInParentFunc;
+    InlineeFrameInfo*   cachedInlineeFrameInfo;
     bool                m_hasCalls: 1; // This is more accurate compared to m_isLeaf
     bool                m_hasInlineArgsOpt : 1;
     bool                m_doFastPaths : 1;

+ 17 - 4
lib/Backend/GlobOpt.cpp

@@ -1588,6 +1588,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
         if (CurrentBlockData()->IsArgumentsOpnd(src1))
         {
             instr->usesStackArgumentsObject = true;
+            instr->m_func->unoptableInlineArgCount++;
         }
 
         if (CurrentBlockData()->IsArgumentsOpnd(src1) &&
@@ -1607,6 +1608,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
                     if (builtinFunction == Js::BuiltinFunction::JavascriptFunction_Apply)
                     {
                         CurrentBlockData()->ClearArgumentsSym(src1->AsRegOpnd());
+                        instr->m_func->unoptableInlineArgCount--;
                     }
                 }
                 else if (builtinOpnd->IsRegOpnd())
@@ -1614,6 +1616,7 @@ GlobOpt::OptArguments(IR::Instr *instr)
                     if (builtinOpnd->AsRegOpnd()->m_sym->m_builtInIndex == Js::BuiltinFunction::JavascriptFunction_Apply)
                     {
                         CurrentBlockData()->ClearArgumentsSym(src1->AsRegOpnd());
+                        instr->m_func->unoptableInlineArgCount--;
                     }
                 }
             }
@@ -13208,10 +13211,10 @@ GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
     if (instr->usesStackArgumentsObject && instr->IsInlined())
     {
         IR::Opnd* src1 = instr->GetSrc1();
-        auto replaceInstr = [&](IR::Opnd* newopnd)
+        auto replaceInstr = [&](IR::Opnd* newopnd, Js::OpCode opCode = Js::OpCode::Ld_A)
         {
             this->CaptureByteCodeSymUses(instr);
-            instr->m_opcode = Js::OpCode::Ld_A;
+            instr->m_opcode = opCode;
             instr->ReplaceSrc1(newopnd);
             if (instr->HasBailOutInfo())
             {
@@ -13231,6 +13234,7 @@ GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
             }
     
             case Js::OpCode::LdElemI_A:
+            case Js::OpCode::TypeofElem:
             {
                 IR::IndirOpnd* indirOpndSrc1 = src1->AsIndirOpnd();
                 if (!indirOpndSrc1->GetIndexOpnd())
@@ -13256,8 +13260,17 @@ GlobOpt::OptArgLenAndConst(IR::Instr* instr, Value** src1Val)
                     }
                     else
                     {
-                        replaceInstr(defInstr->GetSrc1());
-                    }
+                        if (instr->m_opcode == Js::OpCode::TypeofElem) {
+                            replaceInstr(defInstr->GetSrc1(), Js::OpCode::Typeof);
+                        }
+                        else {
+                            replaceInstr(defInstr->GetSrc1());
+                        }
+                    }   
+                }
+                else
+                {
+                    instr->m_func->unoptableInlineArgCount++;
                 }
                 break;
             }

+ 25 - 4
lib/Backend/GlobOptBailOut.cpp

@@ -482,6 +482,16 @@ GlobOpt::CaptureByteCodeSymUses(IR::Instr * instr)
 void
 GlobOpt::ProcessInlineeEnd(IR::Instr* instr)
 {
+    if (instr->m_func->hasArgLenAndConstOpt && instr->m_func->unoptableInlineArgCount == 0)
+    {
+        instr->m_func->hasUnoptimizedArgumentsAccess = false;
+        if (DoInlineArgsOpt(instr->m_func))
+        {
+            instr->m_func->m_hasInlineArgsOpt = true;
+            instr->m_func->frameInfo = instr->m_func->cachedInlineeFrameInfo;
+        }
+    }
+
     if (instr->m_func->m_hasInlineArgsOpt)
     {
         RecordInlineeFrameInfo(instr);
@@ -570,6 +580,7 @@ GlobOpt::TrackCalls(IR::Instr * instr)
     }
 
     case Js::OpCode::InlineeStart:
+    {
         Assert(instr->m_func->GetParentFunc() == this->currentBlock->globOptData.curFunc);
         Assert(instr->m_func->GetParentFunc());
         this->currentBlock->globOptData.curFunc = instr->m_func;
@@ -577,16 +588,26 @@ GlobOpt::TrackCalls(IR::Instr * instr)
         this->func->UpdateMaxInlineeArgOutSize(this->currentBlock->globOptData.inlinedArgOutSize);
         this->EndTrackCall(instr);
 
-        if (DoInlineArgsOpt(instr->m_func))
+        auto createFrameInfo = [&](Func* inlineeFunc)
         {
-            instr->m_func->m_hasInlineArgsOpt = true;
-            InlineeFrameInfo* frameInfo = InlineeFrameInfo::New(func->m_alloc);
-            instr->m_func->frameInfo = frameInfo;
+            InlineeFrameInfo* frameInfo = InlineeFrameInfo::New(inlineeFunc->m_alloc);
             frameInfo->floatSyms = CurrentBlockData()->liveFloat64Syms->CopyNew(this->alloc);
             frameInfo->intSyms = CurrentBlockData()->liveInt32Syms->MinusNew(CurrentBlockData()->liveLossyInt32Syms, this->alloc);
             frameInfo->varSyms = CurrentBlockData()->liveVarSyms->CopyNew(this->alloc);
+            return frameInfo;
+        };
+
+        if (DoInlineArgsOpt(instr->m_func))
+        {
+            instr->m_func->m_hasInlineArgsOpt = true;
+            instr->m_func->frameInfo = createFrameInfo(func);
+        }
+        else
+        {
+            instr->m_func->cachedInlineeFrameInfo = createFrameInfo(instr->m_func);
         }
         break;
+    }    
 
     case Js::OpCode::EndCallForPolymorphicInlinee:
         // Have this opcode mimic the functions of both InlineeStart and InlineeEnd in the bailout block of a polymorphic call inlined using fixed methods.