OSR exit shouldn't bother updating get_by_id array profiles that have changed modes
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2019 19:30:07 +0000 (19:30 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 27 Sep 2019 19:30:07 +0000 (19:30 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202324
<rdar://problem/52669110>

Reviewed by Yusuke Suzuki.

This is an optimization that avoids polluting the array profile.

* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::executeOSRExit):
(JSC::DFG::OSRExit::compileExit):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@250440 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOSRExit.cpp

index 7ef3484..b5860a0 100644 (file)
@@ -1,3 +1,17 @@
+2019-09-27  Keith Miller  <keith_miller@apple.com>
+
+        OSR exit shouldn't bother updating get_by_id array profiles that have changed modes
+        https://bugs.webkit.org/show_bug.cgi?id=202324
+        <rdar://problem/52669110>
+
+        Reviewed by Yusuke Suzuki.
+
+        This is an optimization that avoids polluting the array profile.
+
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::executeOSRExit):
+        (JSC::DFG::OSRExit::compileExit):
+
 2019-09-27  Alexey Shvayka  <shvaikalesh@gmail.com>
 
         Non-standard Error properties should not be enumerable
index 04692ec..aea9e8f 100644 (file)
@@ -515,13 +515,17 @@ void OSRExit::executeOSRExit(Context& context)
             break;
 
         // Begin extra initilization level: ArrayProfileUpdate
-        ArrayProfile* arrayProfile = exitState.arrayProfile;
-        if (arrayProfile) {
+        if (ArrayProfile* arrayProfile = exitState.arrayProfile) {
             ASSERT(!!exit.m_jsValueSource);
             ASSERT(exit.m_kind == BadCache || exit.m_kind == BadIndexingType);
-            Structure* structure = profiledValue.asCell()->structure(vm);
-            arrayProfile->observeStructure(structure);
-            arrayProfile->observeArrayMode(arrayModesFromStructure(structure));
+            CodeBlock* profiledCodeBlock = baselineCodeBlockForOriginAndBaselineCodeBlock(exit.m_codeOriginForExitProfile, baselineCodeBlock);
+            const Instruction* instruction = profiledCodeBlock->instructions().at(exit.m_codeOriginForExitProfile.bytecodeIndex()).ptr();
+            bool doProfile = !instruction->is<OpGetById>() || instruction->as<OpGetById>().metadata(profiledCodeBlock).m_modeMetadata.mode == GetByIdMode::ArrayLength;
+            if (doProfile) {
+                Structure* structure = profiledValue.asCell()->structure(vm);
+                arrayProfile->observeStructure(structure);
+                arrayProfile->observeArrayMode(arrayModesFromStructure(structure));
+            }
         }
         if (extraInitializationLevel <= ExtraInitializationLevel::ArrayProfileUpdate)
             break;
@@ -1166,7 +1170,15 @@ void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const
             // property access, or due to an array profile).
 
             CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile;
-            if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex())) {
+            CodeBlock* codeBlock = jit.baselineCodeBlockFor(codeOrigin);
+            if (ArrayProfile* arrayProfile = codeBlock->getArrayProfile(codeOrigin.bytecodeIndex())) {
+                const Instruction* instruction = codeBlock->instructions().at(codeOrigin.bytecodeIndex()).ptr();
+                CCallHelpers::Jump skipProfile;
+                if (instruction->is<OpGetById>()) {
+                    auto& metadata = instruction->as<OpGetById>().metadata(codeBlock);
+                    skipProfile = jit.branch8(CCallHelpers::NotEqual, CCallHelpers::AbsoluteAddress(&metadata.m_modeMetadata.mode), CCallHelpers::TrustedImm32(static_cast<uint8_t>(GetByIdMode::ArrayLength)));
+                }
+
 #if USE(JSVALUE64)
                 GPRReg usedRegister;
                 if (exit.m_jsValueSource.isAddress())
@@ -1242,6 +1254,9 @@ void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const
                     jit.pop(scratch2);
                     jit.pop(scratch1);
                 }
+
+                if (skipProfile.isSet())
+                    skipProfile.link(&jit);
             }
         }