Kaynağa Gözat

Disable auto-profiling interpreter mode for generator (always collect profiling data)

Nhat Nguyen 6 yıl önce
ebeveyn
işleme
7e08c4a086

+ 2 - 0
bin/NativeTests/FunctionExecutionTest.h

@@ -127,6 +127,8 @@ namespace Js
         FunctionEntryPointInfo* GetDefaultFunctionEntryPointInfo() { return &defaultInfo; }
         FunctionEntryPointInfo *GetSimpleJitEntryPointInfo() { return &simpleInfo; }
         void TraceExecutionMode(const char *const eventDescription = nullptr) const { UNREFERENCED_PARAMETER(eventDescription); }
+        // Dummy implementation to match the real FunctionBody's method
+        bool SkipAutoProfileForCoroutine() const { return false; }
         
         FunctionBody(bool interpreterProfile, bool interpreterAutoProfile, bool simpleJit):
             doInterpreterProfile(interpreterProfile),

+ 6 - 0
lib/Runtime/Base/FunctionBody.cpp

@@ -333,6 +333,12 @@ namespace Js
         return FALSE;
     }
 
+    bool
+    FunctionBody::SkipAutoProfileForCoroutine() const
+    {
+        return this->IsCoroutine() && CONFIG_ISENABLED(Js::JitES6GeneratorsFlag);
+    }
+
     bool
     FunctionBody::IsGeneratorAndJitIsDisabled() const
     {

+ 2 - 0
lib/Runtime/Base/FunctionBody.h

@@ -3408,6 +3408,8 @@ namespace Js
             return IsJitLoopBodyPhaseForced() && !this->GetHasTry();
         }
 
+        bool SkipAutoProfileForCoroutine() const;
+
         bool IsGeneratorAndJitIsDisabled() const;
 
         FunctionBodyFlags * GetAddressOfFlags() { return &this->flags; }

+ 10 - 4
lib/Runtime/Base/FunctionExecutionStateMachine.cpp

@@ -50,10 +50,16 @@ namespace Js
 
         const ConfigFlagsTable &configFlags = Configuration::Global.flags;
 
+        // AutoProfilingInterpreter might decide to not profile on the first run. For generator
+        // functions, that means we will miss the profiling information on the first run when we resume
+        // back to the function. This might result in lots of BailOnNoProfile even though we should have
+        // profiling information. So always collect profile data for generators
+        const bool skipAutoProfileForGenerator = functionBody->SkipAutoProfileForCoroutine();
+
         interpreterLimit = 0;
-        autoProfilingInterpreter0Limit = static_cast<uint16>(configFlags.AutoProfilingInterpreter0Limit);
+        autoProfilingInterpreter0Limit = skipAutoProfileForGenerator ? 0 : static_cast<uint16>(configFlags.AutoProfilingInterpreter0Limit);
         profilingInterpreter0Limit = static_cast<uint16>(configFlags.ProfilingInterpreter0Limit);
-        autoProfilingInterpreter1Limit = static_cast<uint16>(configFlags.AutoProfilingInterpreter1Limit);
+        autoProfilingInterpreter1Limit = skipAutoProfileForGenerator ? 0 : static_cast<uint16>(configFlags.AutoProfilingInterpreter1Limit);
         simpleJitLimit = static_cast<uint16>(configFlags.SimpleJitLimit);
         profilingInterpreter1Limit = static_cast<uint16>(configFlags.ProfilingInterpreter1Limit);
 
@@ -105,9 +111,9 @@ namespace Js
 
         uint16 fullJitThresholdConfig =
             static_cast<uint16>(
-                configFlags.AutoProfilingInterpreter0Limit +
+                (skipAutoProfileForGenerator ? 0 : configFlags.AutoProfilingInterpreter0Limit) +
                 configFlags.ProfilingInterpreter0Limit +
-                configFlags.AutoProfilingInterpreter1Limit +
+                (skipAutoProfileForGenerator ? 0 : configFlags.AutoProfilingInterpreter1Limit) +
                 configFlags.SimpleJitLimit +
                 configFlags.ProfilingInterpreter1Limit);
         if (!configFlags.EnforceExecutionModeLimits)