ソースを参照

[MERGE #5140 @dilijev] Add ChakraEngine for GlobalObject lifetime management

Merge pull request #5140 from dilijev:ChakraEngine
Doug Ilijev 7 年 前
コミット
cdba1599f9

+ 2 - 0
lib/Common/ConfigFlagsList.h

@@ -1271,10 +1271,12 @@ FLAGNR(Phases,  Memspect,              "Enables memspect tracking to perform mem
 FLAGNR(Number,  PolymorphicInlineThreshold     , "Maximum size in bytecodes of a polymorphic inline candidate", DEFAULT_CONFIG_PolymorphicInlineThreshold)
 FLAGNR(Boolean, PrimeRecycler         , "Prime the recycler first", DEFAULT_CONFIG_PrimeRecycler)
 FLAGNR(Boolean, PrivateHeap           , "Use HeapAlloc with a private heap", DEFAULT_CONFIG_PrivateHeap)
+FLAGNR(Boolean, TraceEngineRefcount   , "Output traces for ScriptEngine AddRef/Release to debug lifetime management", false)
 #if defined(CHECK_MEMORY_LEAK) || defined(LEAK_REPORT)
 FLAGNR(Boolean, LeakStackTrace ,        "Include stack trace on leaked pinned object and heap objects", false)
 FLAGNR(Boolean, ForceMemoryLeak ,       "Fake leak some memory to test leak report and check memory leak", false)
 #endif
+FLAGNR(Boolean, DumpAfterFinalGC, "Collect a process dump after calling finalgc", false)
 FLAGNR(Boolean, ForceOldDateAPI       , "Force Chakra to use old dates API regardless of availability of a new one", DEFAULT_CONFIG_ForceOldDateAPI)
 
 FLAGNR(Number,  JitLoopBodyHotLoopThreshold    , "Number of times loop has to be iterated in jitloopbody before it is determined as hot", DEFAULT_CONFIG_JitLoopBodyHotLoopThreshold)

+ 0 - 1
lib/Common/Memory/HeapAllocator.cpp

@@ -582,7 +582,6 @@ MemoryLeakCheck::~MemoryLeakCheck()
         LeakRecord * current = head;
         do
         {
-
             if (enableOutput)
             {
                 Output::PrintBuffer(current->dump, wcslen(current->dump));

+ 22 - 11
lib/Parser/RegexPattern.cpp

@@ -24,31 +24,42 @@ namespace UnifiedRegex
                 program,
                 isLiteral);
     }
+
     void RegexPattern::Finalize(bool isShutdown)
     {
-        if(isShutdown)
+        if (isShutdown)
+        {
             return;
+        }
 
         const auto scriptContext = GetScriptContext();
-        if(!scriptContext)
+        if (!scriptContext)
+        {
             return;
+        }
 
 #if DBG
-        // In JSRT, we might not have a chance to close at finalize time.
-        if(!isLiteral && !scriptContext->IsClosed() && !scriptContext->GetThreadContext()->IsJSRT())
+        // In JSRT or ChakraEngine, we might not have a chance to close at finalize time
+        if (!isLiteral && !scriptContext->IsClosed() &&
+            !scriptContext->GetThreadContext()->IsJSRT() &&
+            !scriptContext->GetLibrary()->IsChakraEngine())
         {
             const auto source = GetSource();
-            RegexPattern *p;
-            Assert(
-                !GetScriptContext()->GetDynamicRegexMap()->TryGetValue(
-                    RegexKey(source.GetBuffer(), source.GetLength(), GetFlags()),
-                    &p) || ( source.GetLength() == 0 ) ||
-                p != this);
+            RegexPattern *p = nullptr;
+
+            bool hasRegexPatternForSourceKey = GetScriptContext()->GetDynamicRegexMap()->TryGetValue(
+                RegexKey(source.GetBuffer(), source.GetLength(), GetFlags()), &p);
+            bool isSourceLengthZero = source.GetLength() == 0;
+            bool isUniquePattern = p != this;
+
+            Assert(!hasRegexPatternForSourceKey || isSourceLengthZero || isUniquePattern);
         }
 #endif
 
-        if(isShallowClone)
+        if (isShallowClone)
+        {
             return;
+        }
 
         rep.unified.program->FreeBody(scriptContext->RegexAllocator());
     }

+ 7 - 3
lib/Runtime/Base/ScriptContext.cpp

@@ -474,7 +474,7 @@ namespace Js
         if (javascriptLibrary != nullptr)
         {
             javascriptLibrary->scriptContext = nullptr;
-            javascriptLibrary = nullptr;
+
             if (closed)
             {
                 // if we just closed, we haven't unpin the object yet.
@@ -484,11 +484,13 @@ namespace Js
 #if ENABLE_NATIVE_CODEGEN
                 Assert(this->IsClosedNativeCodeGenerator());
 #endif
-                if (!GetThreadContext()->IsJSRT())
+                if (globalObject && !GetThreadContext()->IsJSRT() && !GetLibrary()->IsChakraEngine())
                 {
                     this->recycler->RootRelease(globalObject);
                 }
             }
+
+            javascriptLibrary = nullptr;
         }
 
         // Normally the JavascriptLibraryBase will unregister the scriptContext from the threadContext.
@@ -824,7 +826,9 @@ namespace Js
     bool ScriptContext::Close(bool inDestructor)
     {
         if (isScriptContextActuallyClosed)
+        {
             return false;
+        }
 
         InternalClose();
 
@@ -835,7 +839,7 @@ namespace Js
 #if ENABLE_NATIVE_CODEGEN
             Assert(this->IsClosedNativeCodeGenerator());
 #endif
-            if (!GetThreadContext()->IsJSRT())
+            if (!GetThreadContext()->IsJSRT() && !GetLibrary()->IsChakraEngine())
             {
                 GetRecycler()->RootRelease(globalObject);
             }

+ 7 - 1
lib/Runtime/Library/JavascriptLibraryBase.h

@@ -8,6 +8,8 @@
 // if the size changed here.
 #pragma once
 
+class ChakraEngine;
+
 namespace Js
 {
     class EngineInterfaceObject;
@@ -19,7 +21,8 @@ namespace Js
 
     public:
         JavascriptLibraryBase(GlobalObject* globalObject):
-            globalObject(globalObject)
+            globalObject(globalObject),
+            chakraEngine(nullptr)
         {
         }
         Var GetPI() { return pi; }
@@ -147,6 +150,8 @@ namespace Js
         PropertyId GetPropertyIdSymbolIterator() { return PropertyIds::_symbolIterator; };
         PropertyId GetPropertyIdSymbolToStringTag() { return PropertyIds::_symbolToStringTag; };
 
+        bool IsChakraEngine() const { return chakraEngine != nullptr; }
+
     protected:
         Field(GlobalObject*) globalObject;
         Field(RuntimeFunction*) mapConstructor;
@@ -314,6 +319,7 @@ namespace Js
 
     public:
         Field(ScriptContext*) scriptContext;
+        Field(ChakraEngine*) chakraEngine;
 
     private:
         virtual void Dispose(bool isShutdown) override;