Quellcode durchsuchen

Force SharedBailOutKind to be true on the BailOutInfo of CheckFuncInfo instrs; stop GC of BailOutInfo with SharedBailOutKind.

wyrichte vor 6 Jahren
Ursprung
Commit
aa85680700

+ 1 - 1
lib/Backend/IR.cpp

@@ -1281,7 +1281,7 @@ Instr::ReplaceBailOutInfo(BailOutInfo *newBailOutInfo)
         __assume(UNREACHED);
     }
     
-    if (oldBailOutInfo->bailOutInstr == this)
+    if (oldBailOutInfo->bailOutInstr == this && !oldBailOutInfo->sharedBailOutKind)
     {
         Assert(!oldBailOutInfo->wasCloned && !oldBailOutInfo->wasCopied);
         JitArenaAllocator * alloc = this->m_func->m_alloc;

+ 5 - 1
lib/Backend/Inline.cpp

@@ -4632,7 +4632,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
     Assert(insertBeforeInstr);
     Assert(insertBeforeInstr->m_func == callInstr->m_func);
 
-    IR::Instr *checkFuncInfo = IR::BailOutInstr::New(Js::OpCode::CheckFuncInfo, IR::BailOutOnInlineFunction, insertBeforeInstr, callInstr->m_func);
+    IR::Instr* checkFuncInfo = IR::BailOutInstr::New(Js::OpCode::CheckFuncInfo, IR::BailOutOnInlineFunction, insertBeforeInstr, callInstr->m_func);
     checkFuncInfo->SetSrc1(callInstr->GetSrc1()->AsRegOpnd());
 
     IR::AddrOpnd* inlinedFuncInfo = IR::AddrOpnd::New(funcInfo->GetFunctionInfoAddr(), IR::AddrOpndKindDynamicFunctionInfo, insertBeforeInstr->m_func);
@@ -4641,6 +4641,10 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
     checkFuncInfo->SetByteCodeOffset(insertBeforeInstr);
     insertBeforeInstr->InsertBefore(checkFuncInfo);
 
+    // checkFuncInfo can be hoisted later and then have its BailOutInfo garbage collected. Other instructions (ex: BailOnNotStackArgs) share
+    // checkFuncInfo's BailOutInfo. Explicitly force sharedBailOutKind to be true to stop this BailOutInfo from being garbage collected.
+    checkFuncInfo->ShareBailOut();
+
     return checkFuncInfo;
 }
 

+ 39 - 0
test/FixedFields/NonFixedFieldHoist.js

@@ -42,3 +42,42 @@ catch(e)
 {
     WScript.Echo(e);
 }
+
+// Will hoist CheckFuncInfo instr
+// and then GC its BailOutInfo.
+function test0() {
+    var obj0 = {};
+    var obj1 = {};
+    var func2 = function () {
+    };
+    var func4 = function () {
+        for (var _strvar2 in ary) {
+            function v0() {
+                throw '';
+            }
+            function v2() {
+                var v3 = 0;
+                for (var _strvar0 in f32) {
+                    if (v3++) {
+                        func2.apply(obj1, arguments);
+                        v0();
+                    }
+                }
+            }
+            try {
+                v2();
+            } catch (ex) {
+            }
+        }
+    };
+    obj0.method0 = func4;
+    var ary = Array();
+    var f32 = new Float32Array(256);
+    ary[0] = 1;
+    ary[1] = 1;
+    function v14() {
+        var v15 = obj0.method0();
+    }
+    v14();
+}
+test0();

+ 1 - 1
test/inlining/InlineCallbackCallBailout.baseline

@@ -8,7 +8,7 @@ foo
 INLINING : Found callback def instr for call/apply target callback at	CallSite: 0	Caller: Dispatch ( (#1.5), #6)
 INLINING CALLBACK : Inlining callback for call/apply target : 	foo ( (#1.4), #5)
 foo
-BailOut: function Dispatch, Opcode: BailOnNotEqual Kind: BailOutOnInlineFunction
+BailOut: function Dispatch, Opcode: BailTarget Kind: BailOutOnInlineFunction
 bar
 BailOut: function CallDispatch, Opcode: InlineeEnd Kind: BailOutOnInlineFunction
 foo