Title: [283148] branches/safari-612-branch
Revision
283148
Author
[email protected]
Date
2021-09-27 15:49:47 -0700 (Mon, 27 Sep 2021)

Log Message

Cherry-pick r283098. rdar://problem/83584491

    [JSC] Optimize PutByVal with for-in
    https://bugs.webkit.org/show_bug.cgi?id=230801

    Reviewed by Saam Barati.

    JSTests:

    * stress/for-in-sentinel.js: Added.
    (shouldBe):
    (test):

    Source/_javascript_Core:

    We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
    And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
    The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
    forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
    the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.

    In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
    pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
    since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
    is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
    as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.

    To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
    not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
    for existing jneq_ptr bytecode.

    We also clean up DFG operation related to PutByVal.

    ----------------------------------------------------------------------------------------------------------------------------------
    |               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
    ----------------------------------------------------------------------------------------------------------------------------------
    | Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
    | VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
    | EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
    | BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
    | Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
    | AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
    | Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
    | Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
    | Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
    | Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
    | VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
    | jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
    | EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
    | React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
    | React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
    | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
    ----------------------------------------------------------------------------------------------------------------------------------
    a mean = 271.75873
    b mean = 272.45804
    pValue = 0.0263030803
    (Bigger means are better.)
    1.003 times better
    Results ARE significant

    * builtins/BuiltinNames.h:
    * bytecode/BytecodeList.rb:
    * bytecode/BytecodeUseDef.cpp:
    (JSC::computeUsesForBytecodeIndexImpl):
    (JSC::computeDefsForBytecodeIndexImpl):
    * bytecode/LinkTimeConstant.h:
    * bytecode/Opcode.h:
    (JSC::isBranch):
    * bytecode/PreciseJumpTargetsInlines.h:
    * bytecompiler/BytecodeGenerator.cpp:
    (JSC::GenericLabel<JSGeneratorTraits>::setLocation):
    (JSC::BytecodeGenerator::emitJumpIfSentinelString):
    * bytecompiler/BytecodeGenerator.h:
    * bytecompiler/NodesCodegen.cpp:
    (JSC::ForInNode::emitBytecode):
    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::parseBlock):
    * dfg/DFGCapabilities.cpp:
    (JSC::DFG::capabilityLevel):
    * dfg/DFGOperations.cpp:
    (JSC::DFG::putByVal):
    (JSC::DFG::putByValInternal):
    (JSC::DFG::putByValCellInternal):
    (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
    * dfg/DFGOperations.h:
    * dfg/DFGPredictionPropagationPhase.cpp:
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
    * ftl/FTLLowerDFGToB3.cpp:
    (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
    * jit/JIT.cpp:
    (JSC::JIT::privateCompileMainPass):
    * jit/JIT.h:
    * jit/JITOpcodes.cpp:
    (JSC::JIT::emit_op_jeq_ptr):
    * jit/JITOpcodes32_64.cpp:
    (JSC::JIT::emit_op_jeq_ptr):
    * jit/JITPropertyAccess.cpp:
    (JSC::JIT::emit_op_enumerator_next):
    * llint/LowLevelInterpreter32_64.asm:
    * llint/LowLevelInterpreter64.asm:
    * runtime/CommonSlowPaths.cpp:
    (JSC::JSC_DEFINE_COMMON_SLOW_PATH):
    * runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::init):
    * runtime/SmallStrings.cpp:
    (JSC::SmallStrings::initializeCommonStrings):
    (JSC::SmallStrings::visitStrongReferences):
    * runtime/SmallStrings.h:
    (JSC::SmallStrings::sentinelString const):

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-612-branch/JSTests/ChangeLog (283147 => 283148)


--- branches/safari-612-branch/JSTests/ChangeLog	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/JSTests/ChangeLog	2021-09-27 22:49:47 UTC (rev 283148)
@@ -1,3 +1,131 @@
+2021-09-27  Alan Coon  <[email protected]>
+
+        Cherry-pick r283098. rdar://problem/83584491
+
+    [JSC] Optimize PutByVal with for-in
+    https://bugs.webkit.org/show_bug.cgi?id=230801
+    
+    Reviewed by Saam Barati.
+    
+    JSTests:
+    
+    * stress/for-in-sentinel.js: Added.
+    (shouldBe):
+    (test):
+    
+    Source/_javascript_Core:
+    
+    We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
+    And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
+    The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
+    forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
+    the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.
+    
+    In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
+    pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
+    since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
+    is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
+    as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.
+    
+    To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
+    not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
+    for existing jneq_ptr bytecode.
+    
+    We also clean up DFG operation related to PutByVal.
+    
+    ----------------------------------------------------------------------------------------------------------------------------------
+    |               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
+    ----------------------------------------------------------------------------------------------------------------------------------
+    | Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
+    | VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
+    | EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
+    | BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
+    | Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
+    | AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
+    | Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
+    | Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
+    | Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
+    | Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
+    | VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
+    | jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
+    | EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
+    | React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
+    | React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
+    | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
+    ----------------------------------------------------------------------------------------------------------------------------------
+    a mean = 271.75873
+    b mean = 272.45804
+    pValue = 0.0263030803
+    (Bigger means are better.)
+    1.003 times better
+    Results ARE significant
+    
+    * builtins/BuiltinNames.h:
+    * bytecode/BytecodeList.rb:
+    * bytecode/BytecodeUseDef.cpp:
+    (JSC::computeUsesForBytecodeIndexImpl):
+    (JSC::computeDefsForBytecodeIndexImpl):
+    * bytecode/LinkTimeConstant.h:
+    * bytecode/Opcode.h:
+    (JSC::isBranch):
+    * bytecode/PreciseJumpTargetsInlines.h:
+    * bytecompiler/BytecodeGenerator.cpp:
+    (JSC::GenericLabel<JSGeneratorTraits>::setLocation):
+    (JSC::BytecodeGenerator::emitJumpIfSentinelString):
+    * bytecompiler/BytecodeGenerator.h:
+    * bytecompiler/NodesCodegen.cpp:
+    (JSC::ForInNode::emitBytecode):
+    * dfg/DFGAbstractInterpreterInlines.h:
+    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+    * dfg/DFGByteCodeParser.cpp:
+    (JSC::DFG::ByteCodeParser::parseBlock):
+    * dfg/DFGCapabilities.cpp:
+    (JSC::DFG::capabilityLevel):
+    * dfg/DFGOperations.cpp:
+    (JSC::DFG::putByVal):
+    (JSC::DFG::putByValInternal):
+    (JSC::DFG::putByValCellInternal):
+    (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+    * dfg/DFGOperations.h:
+    * dfg/DFGPredictionPropagationPhase.cpp:
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+    * jit/JIT.cpp:
+    (JSC::JIT::privateCompileMainPass):
+    * jit/JIT.h:
+    * jit/JITOpcodes.cpp:
+    (JSC::JIT::emit_op_jeq_ptr):
+    * jit/JITOpcodes32_64.cpp:
+    (JSC::JIT::emit_op_jeq_ptr):
+    * jit/JITPropertyAccess.cpp:
+    (JSC::JIT::emit_op_enumerator_next):
+    * llint/LowLevelInterpreter32_64.asm:
+    * llint/LowLevelInterpreter64.asm:
+    * runtime/CommonSlowPaths.cpp:
+    (JSC::JSC_DEFINE_COMMON_SLOW_PATH):
+    * runtime/JSGlobalObject.cpp:
+    (JSC::JSGlobalObject::init):
+    * runtime/SmallStrings.cpp:
+    (JSC::SmallStrings::initializeCommonStrings):
+    (JSC::SmallStrings::visitStrongReferences):
+    * runtime/SmallStrings.h:
+    (JSC::SmallStrings::sentinelString const):
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283098 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-26  Yusuke Suzuki  <[email protected]>
+
+            [JSC] Optimize PutByVal with for-in
+            https://bugs.webkit.org/show_bug.cgi?id=230801
+
+            Reviewed by Saam Barati.
+
+            * stress/for-in-sentinel.js: Added.
+            (shouldBe):
+            (test):
+
 2021-09-22  Alan Coon  <[email protected]>
 
         Cherry-pick r282707. rdar://problem/83429953

Added: branches/safari-612-branch/JSTests/stress/for-in-sentinel.js (0 => 283148)


--- branches/safari-612-branch/JSTests/stress/for-in-sentinel.js	                        (rev 0)
+++ branches/safari-612-branch/JSTests/stress/for-in-sentinel.js	2021-09-27 22:49:47 UTC (rev 283148)
@@ -0,0 +1,22 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var object = {
+    $: 32,
+    test: 33,
+    hey: 34,
+};
+
+function test(object) {
+    var count = 0;
+    for (var i in object) {
+        ++count;
+    }
+    return count;
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+    shouldBe(test(object), 3);

Added: branches/safari-612-branch/JSTests/stress/for-in-sentinel2.js (0 => 283148)


--- branches/safari-612-branch/JSTests/stress/for-in-sentinel2.js	                        (rev 0)
+++ branches/safari-612-branch/JSTests/stress/for-in-sentinel2.js	2021-09-27 22:49:47 UTC (rev 283148)
@@ -0,0 +1,26 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+var object = {
+    $: 32,
+    test: 33,
+    hey: 34,
+};
+
+function test(object) {
+    var string = '$';
+    var count = 0;
+    for (var i in object) {
+        ++count;
+    }
+    for (var i in object) {
+        ++count;
+    }
+    return count + string;
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i)
+    shouldBe(test(object), `6$`);

Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-09-27 22:49:47 UTC (rev 283148)
@@ -1,3 +1,225 @@
+2021-09-27  Alan Coon  <[email protected]>
+
+        Cherry-pick r283098. rdar://problem/83584491
+
+    [JSC] Optimize PutByVal with for-in
+    https://bugs.webkit.org/show_bug.cgi?id=230801
+    
+    Reviewed by Saam Barati.
+    
+    JSTests:
+    
+    * stress/for-in-sentinel.js: Added.
+    (shouldBe):
+    (test):
+    
+    Source/_javascript_Core:
+    
+    We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
+    And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
+    The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
+    forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
+    the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.
+    
+    In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
+    pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
+    since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
+    is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
+    as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.
+    
+    To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
+    not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
+    for existing jneq_ptr bytecode.
+    
+    We also clean up DFG operation related to PutByVal.
+    
+    ----------------------------------------------------------------------------------------------------------------------------------
+    |               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
+    ----------------------------------------------------------------------------------------------------------------------------------
+    | Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
+    | VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
+    | EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
+    | BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
+    | Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
+    | AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
+    | Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
+    | Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
+    | Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
+    | Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
+    | VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
+    | jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
+    | EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
+    | React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
+    | React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
+    | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
+    ----------------------------------------------------------------------------------------------------------------------------------
+    a mean = 271.75873
+    b mean = 272.45804
+    pValue = 0.0263030803
+    (Bigger means are better.)
+    1.003 times better
+    Results ARE significant
+    
+    * builtins/BuiltinNames.h:
+    * bytecode/BytecodeList.rb:
+    * bytecode/BytecodeUseDef.cpp:
+    (JSC::computeUsesForBytecodeIndexImpl):
+    (JSC::computeDefsForBytecodeIndexImpl):
+    * bytecode/LinkTimeConstant.h:
+    * bytecode/Opcode.h:
+    (JSC::isBranch):
+    * bytecode/PreciseJumpTargetsInlines.h:
+    * bytecompiler/BytecodeGenerator.cpp:
+    (JSC::GenericLabel<JSGeneratorTraits>::setLocation):
+    (JSC::BytecodeGenerator::emitJumpIfSentinelString):
+    * bytecompiler/BytecodeGenerator.h:
+    * bytecompiler/NodesCodegen.cpp:
+    (JSC::ForInNode::emitBytecode):
+    * dfg/DFGAbstractInterpreterInlines.h:
+    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+    * dfg/DFGByteCodeParser.cpp:
+    (JSC::DFG::ByteCodeParser::parseBlock):
+    * dfg/DFGCapabilities.cpp:
+    (JSC::DFG::capabilityLevel):
+    * dfg/DFGOperations.cpp:
+    (JSC::DFG::putByVal):
+    (JSC::DFG::putByValInternal):
+    (JSC::DFG::putByValCellInternal):
+    (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+    * dfg/DFGOperations.h:
+    * dfg/DFGPredictionPropagationPhase.cpp:
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+    * jit/JIT.cpp:
+    (JSC::JIT::privateCompileMainPass):
+    * jit/JIT.h:
+    * jit/JITOpcodes.cpp:
+    (JSC::JIT::emit_op_jeq_ptr):
+    * jit/JITOpcodes32_64.cpp:
+    (JSC::JIT::emit_op_jeq_ptr):
+    * jit/JITPropertyAccess.cpp:
+    (JSC::JIT::emit_op_enumerator_next):
+    * llint/LowLevelInterpreter32_64.asm:
+    * llint/LowLevelInterpreter64.asm:
+    * runtime/CommonSlowPaths.cpp:
+    (JSC::JSC_DEFINE_COMMON_SLOW_PATH):
+    * runtime/JSGlobalObject.cpp:
+    (JSC::JSGlobalObject::init):
+    * runtime/SmallStrings.cpp:
+    (JSC::SmallStrings::initializeCommonStrings):
+    (JSC::SmallStrings::visitStrongReferences):
+    * runtime/SmallStrings.h:
+    (JSC::SmallStrings::sentinelString const):
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283098 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-26  Yusuke Suzuki  <[email protected]>
+
+            [JSC] Optimize PutByVal with for-in
+            https://bugs.webkit.org/show_bug.cgi?id=230801
+
+            Reviewed by Saam Barati.
+
+            We found that some of Speedometer2 subtests are heavily using for-in with PutByVal or the other DFG nodes.
+            And we also found that we are using polluted non-good type for the property names from for-in: String | Other.
+            The reason is that we are returning null when op_enumerator_next finishes instead of string. And this design
+            forces DFG and FTL to return null from EnumeratorNextUpdatePropertyName at the end of iteration. This pollutes
+            the type of property names as String | Other instead of String, and leading to suboptimal DFG nodes.
+
+            In this patch, we add special sentinel string in vm.smallString.sentinelString(). We know that this string cell
+            pointer will be never returned from EnumeratorNextUpdatePropertyName in the normal for-in iteration. This is easy
+            since we are always allocating a JSString when creating JSPropertyNameEnumerator. So this string cell (not the content)
+            is always different from pre-allocated vm.smallString.sentinelString(). So, we use this special string pointer
+            as a sentinel instead of null so that we can avoid polluting return type of EnumeratorNextUpdatePropertyName.
+
+            To check the sentinel in LLInt / Baseline, this patch adds jeq_ptr, which performs cell pointer comparison and do
+            not check string content equality. We do not need to have an implementation in DFG since we already have CompareEqPtr
+            for existing jneq_ptr bytecode.
+
+            We also clean up DFG operation related to PutByVal.
+
+            ----------------------------------------------------------------------------------------------------------------------------------
+            |               subtest                |     ms      |     ms      |  b / a   | pValue (significance using False Discovery Rate) |
+            ----------------------------------------------------------------------------------------------------------------------------------
+            | Elm-TodoMVC                          |116.010000   |112.701667   |0.971482  | 0.000000 (significant)                           |
+            | VueJS-TodoMVC                        |22.995000    |23.023333    |1.001232  | 0.907086                                         |
+            | EmberJS-TodoMVC                      |125.498333   |125.525000   |1.000212  | 0.932546                                         |
+            | BackboneJS-TodoMVC                   |45.700000    |45.975000    |1.006018  | 0.084799                                         |
+            | Preact-TodoMVC                       |16.681667    |16.610000    |0.995704  | 0.722758                                         |
+            | AngularJS-TodoMVC                    |123.753333   |123.740000   |0.999892  | 0.971431                                         |
+            | Vanilla-ES2015-TodoMVC               |61.255000    |61.380000    |1.002041  | 0.300654                                         |
+            | Inferno-TodoMVC                      |58.646667    |58.948333    |1.005144  | 0.267611                                         |
+            | Flight-TodoMVC                       |73.283333    |72.801667    |0.993427  | 0.207389                                         |
+            | Angular2-TypeScript-TodoMVC          |39.746667    |40.015000    |1.006751  | 0.449821                                         |
+            | VanillaJS-TodoMVC                    |50.096667    |49.823333    |0.994544  | 0.162020                                         |
+            | jQuery-TodoMVC                       |212.870000   |213.196667   |1.001535  | 0.371944                                         |
+            | EmberJS-Debug-TodoMVC                |331.878333   |332.710000   |1.002506  | 0.094499                                         |
+            | React-TodoMVC                        |83.078333    |82.726667    |0.995767  | 0.076143                                         |
+            | React-Redux-TodoMVC                  |136.018333   |133.935000   |0.984683  | 0.000000 (significant)                           |
+            | Vanilla-ES2015-Babel-Webpack-TodoMVC |59.743333    |59.643333    |0.998326  | 0.393671                                         |
+            ----------------------------------------------------------------------------------------------------------------------------------
+            a mean = 271.75873
+            b mean = 272.45804
+            pValue = 0.0263030803
+            (Bigger means are better.)
+            1.003 times better
+            Results ARE significant
+
+            * builtins/BuiltinNames.h:
+            * bytecode/BytecodeList.rb:
+            * bytecode/BytecodeUseDef.cpp:
+            (JSC::computeUsesForBytecodeIndexImpl):
+            (JSC::computeDefsForBytecodeIndexImpl):
+            * bytecode/LinkTimeConstant.h:
+            * bytecode/Opcode.h:
+            (JSC::isBranch):
+            * bytecode/PreciseJumpTargetsInlines.h:
+            * bytecompiler/BytecodeGenerator.cpp:
+            (JSC::GenericLabel<JSGeneratorTraits>::setLocation):
+            (JSC::BytecodeGenerator::emitJumpIfSentinelString):
+            * bytecompiler/BytecodeGenerator.h:
+            * bytecompiler/NodesCodegen.cpp:
+            (JSC::ForInNode::emitBytecode):
+            * dfg/DFGAbstractInterpreterInlines.h:
+            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+            * dfg/DFGByteCodeParser.cpp:
+            (JSC::DFG::ByteCodeParser::parseBlock):
+            * dfg/DFGCapabilities.cpp:
+            (JSC::DFG::capabilityLevel):
+            * dfg/DFGOperations.cpp:
+            (JSC::DFG::putByVal):
+            (JSC::DFG::putByValInternal):
+            (JSC::DFG::putByValCellInternal):
+            (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+            * dfg/DFGOperations.h:
+            * dfg/DFGPredictionPropagationPhase.cpp:
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::compileEnumeratorNextUpdatePropertyName):
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
+            * jit/JIT.cpp:
+            (JSC::JIT::privateCompileMainPass):
+            * jit/JIT.h:
+            * jit/JITOpcodes.cpp:
+            (JSC::JIT::emit_op_jeq_ptr):
+            * jit/JITOpcodes32_64.cpp:
+            (JSC::JIT::emit_op_jeq_ptr):
+            * jit/JITPropertyAccess.cpp:
+            (JSC::JIT::emit_op_enumerator_next):
+            * llint/LowLevelInterpreter32_64.asm:
+            * llint/LowLevelInterpreter64.asm:
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::JSC_DEFINE_COMMON_SLOW_PATH):
+            * runtime/JSGlobalObject.cpp:
+            (JSC::JSGlobalObject::init):
+            * runtime/SmallStrings.cpp:
+            (JSC::SmallStrings::initializeCommonStrings):
+            (JSC::SmallStrings::visitStrongReferences):
+            * runtime/SmallStrings.h:
+            (JSC::SmallStrings::sentinelString const):
+
 2021-09-23  Russell Epstein  <[email protected]>
 
         Cherry-pick r281910. rdar://problem/83429926

Modified: branches/safari-612-branch/Source/_javascript_Core/builtins/BuiltinNames.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/builtins/BuiltinNames.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/builtins/BuiltinNames.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -182,7 +182,8 @@
     macro(createPrivateSymbol) \
     macro(entries) \
     macro(outOfLineReactionCounts) \
-    macro(emptyPropertyNameEnumerator)
+    macro(emptyPropertyNameEnumerator) \
+    macro(sentinelString) \
 
 
 namespace Symbols {

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeList.rb (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeList.rb	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeList.rb	2021-09-27 22:49:47 UTC (rev 283148)
@@ -762,6 +762,13 @@
         targetLabel: BoundLabel,
     }
 
+op :jeq_ptr,
+    args: {
+        value: VirtualRegister,
+        specialPointer: VirtualRegister,
+        targetLabel: BoundLabel,
+    }
+
 op :jneq_ptr,
     args: {
         value: VirtualRegister,

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -80,7 +80,6 @@
     // No uses.
     case op_new_regexp:
     case op_debug:
-    case op_jneq_ptr:
     case op_loop_hint:
     case op_jmp:
     case op_new_object:
@@ -135,6 +134,9 @@
     USES(OpJnstricteq, lhs, rhs)
     USES(OpJbelow, lhs, rhs)
     USES(OpJbeloweq, lhs, rhs)
+    USES(OpJeqPtr, value, specialPointer)
+    USES(OpJneqPtr, value, specialPointer)
+
     USES(OpSetFunctionName, function, name)
     USES(OpLogShadowChickenTail, thisValue, scope)
 
@@ -365,6 +367,7 @@
     case op_jneq_null:
     case op_jundefined_or_null:
     case op_jnundefined_or_null:
+    case op_jeq_ptr:
     case op_jneq_ptr:
     case op_jless:
     case op_jlesseq:

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/LinkTimeConstant.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/LinkTimeConstant.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/LinkTimeConstant.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -112,6 +112,7 @@
     v(hasOwnPropertyFunction, nullptr) \
     v(createPrivateSymbol, nullptr) \
     v(emptyPropertyNameEnumerator, nullptr) \
+    v(sentinelString, nullptr) \
 
 
 #define DECLARE_LINK_TIME_CONSTANT(name, code) name,

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/Opcode.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/Opcode.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/Opcode.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -199,6 +199,7 @@
     case op_jneq_null:
     case op_jundefined_or_null:
     case op_jnundefined_or_null:
+    case op_jeq_ptr:
     case op_jneq_ptr:
     case op_jless:
     case op_jlesseq:

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/PreciseJumpTargetsInlines.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -43,6 +43,7 @@
     CASE_OP(OpJneqNull) \
     CASE_OP(OpJundefinedOrNull) \
     CASE_OP(OpJnundefinedOrNull) \
+    CASE_OP(OpJeqPtr) \
     CASE_OP(OpJneqPtr) \
     \
     CASE_OP(OpJless) \

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -105,6 +105,7 @@
         CASE(OpJeq)
         CASE(OpJstricteq)
         CASE(OpJneq)
+        CASE(OpJeqPtr)
         CASE(OpJneqPtr)
         CASE(OpJnstricteq)
         CASE(OpJless)
@@ -1497,6 +1498,11 @@
     OpJneqPtr::emit(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::applyFunction), target.bind(this));
 }
 
+void BytecodeGenerator::emitJumpIfSentinelString(RegisterID* cond, Label& target)
+{
+    OpJeqPtr::emit(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::sentinelString), target.bind(this));
+}
+
 unsigned BytecodeGenerator::emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target)
 {
     OpJneqPtr::emit<OpcodeSize::Wide32>(this, cond, moveLinkTimeConstant(nullptr, LinkTimeConstant::hasOwnPropertyFunction), target.bind(this));

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -858,6 +858,7 @@
         void emitJumpIfFalse(RegisterID* cond, Label& target);
         void emitJumpIfNotFunctionCall(RegisterID* cond, Label& target);
         void emitJumpIfNotFunctionApply(RegisterID* cond, Label& target);
+        void emitJumpIfSentinelString(RegisterID* cond, Label& target);
         unsigned emitWideJumpIfNotFunctionHasOwnProperty(RegisterID* cond, Label& target);
         void recordHasOwnPropertyInForInLoop(ForInContext&, unsigned branchOffset, Label& genericPath);
 

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -4227,10 +4227,8 @@
 
         // FIXME: We should have a way to see if anyone is actually using the propertyName for something other than a get_by_val. If not, we could eliminate the toString in this opcode.
         generator.emitEnumeratorNext(propertyName.get(), mode.get(), index.get(), base.get(), enumerator.get());
+        generator.emitJumpIfSentinelString(propertyName.get(), scope->breakTarget());
 
-        // Note, choosing undefined or null helps please DFG's Abstract Interpreter as it doesn't distinguish null and undefined as types (via SpecOther).
-        generator.emitJumpIfTrue(generator.emitIsUndefinedOrNull(generator.newTemporary(), propertyName.get()), scope->breakTarget());
-
         this->emitLoopHeader(generator, propertyName.get());
 
         generator.emitProfileControlFlow(profilerStartOffset);

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -4323,7 +4323,7 @@
     }
 
     case EnumeratorNextUpdatePropertyName: {
-        setTypeForNode(node, SpecString | SpecOther);
+        setTypeForNode(node, SpecStringIdent);
         break;
     }
 

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -7632,6 +7632,18 @@
             NEXT_OPCODE(op_iterator_next);
         }
 
+        case op_jeq_ptr: {
+            auto bytecode = currentInstruction->as<OpJeqPtr>();
+            JSValue constant = m_inlineStackTop->m_codeBlock->getConstant(bytecode.m_specialPointer);
+            FrozenValue* frozenPointer = m_graph.freezeStrong(constant);
+            ASSERT(frozenPointer->cell() == constant);
+            unsigned relativeOffset = jumpTarget(bytecode.m_targetLabel);
+            Node* child = get(bytecode.m_value);
+            Node* condition = addToGraph(CompareEqPtr, OpInfo(frozenPointer), child);
+            addToGraph(Branch, OpInfo(branchData(m_currentIndex.offset() + relativeOffset, m_currentIndex.offset() + currentInstruction->size())), condition);
+            LAST_OPCODE(op_jeq_ptr);
+        }
+
         case op_jneq_ptr: {
             auto bytecode = currentInstruction->as<OpJneqPtr>();
             FrozenValue* frozenPointer = m_graph.freezeStrong(m_inlineStackTop->m_codeBlock->getConstant(bytecode.m_specialPointer));

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -240,6 +240,7 @@
     case op_get_from_arguments:
     case op_put_to_arguments:
     case op_get_argument:
+    case op_jeq_ptr:
     case op_jneq_ptr:
     case op_typeof:
     case op_to_number:

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -86,10 +86,10 @@
 namespace JSC { namespace DFG {
 
 template<bool strict, bool direct>
-static inline void putByVal(JSGlobalObject* globalObject, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
+static ALWAYS_INLINE void putByVal(JSGlobalObject* globalObject, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
 {
     ASSERT(isIndex(index));
-    if (direct) {
+    if constexpr (direct) {
         RELEASE_ASSERT(baseValue.isObject());
         asObject(baseValue)->putDirectIndex(globalObject, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
         return;
@@ -128,7 +128,7 @@
     RETURN_IF_EXCEPTION(scope, void());
 
     PutPropertySlot slot(baseValue, strict);
-    if (direct) {
+    if constexpr (direct) {
         RELEASE_ASSERT(baseValue.isObject());
         JSObject* baseObject = asObject(baseValue);
         if (std::optional<uint32_t> index = parseIndex(propertyName)) {
@@ -148,7 +148,7 @@
 ALWAYS_INLINE static void putByValCellInternal(JSGlobalObject* globalObject, VM& vm, JSCell* base, PropertyName propertyName, JSValue value)
 {
     PutPropertySlot slot(base, strict);
-    if (direct) {
+    if constexpr (direct) {
         RELEASE_ASSERT(base->isObject());
         JSObject* baseObject = asObject(base);
         if (std::optional<uint32_t> index = parseIndex(propertyName)) {
@@ -2486,7 +2486,7 @@
     return JSValue::encode(result);
 }
 
-JSC_DEFINE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, EncodedJSValue, (JSGlobalObject* globalObject, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator))
+JSC_DEFINE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject* globalObject, uint32_t index, int32_t modeNumber, JSPropertyNameEnumerator* enumerator))
 {
     VM& vm = globalObject->vm();
     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
@@ -2494,15 +2494,15 @@
 
     if (modeNumber == JSPropertyNameEnumerator::IndexedMode) {
         if (index < enumerator->indexedLength())
-            return JSValue::encode(jsString(vm, Identifier::from(vm, index).string()));
-        return JSValue::encode(jsNull());
+            return jsString(vm, Identifier::from(vm, index).string());
+        return vm.smallStrings.sentinelString();
     }
 
     JSString* result = enumerator->propertyNameAtIndex(index);
     if (!result)
-        return JSValue::encode(jsNull());
+        return vm.smallStrings.sentinelString();
 
-    return JSValue::encode(result);
+    return result;
 }
 
 JSC_DEFINE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject* globalObject, JSCell* base, uint32_t index, JSPropertyNameEnumerator* enumerator))

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGOperations.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -108,7 +108,7 @@
 JSC_DECLARE_JIT_OPERATION(operationGetPropertyEnumerator, JSCell*, (JSGlobalObject*, EncodedJSValue));
 JSC_DECLARE_JIT_OPERATION(operationGetPropertyEnumeratorCell, JSCell*, (JSGlobalObject*, JSCell*));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdateIndexAndMode, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, uint32_t, int32_t, JSPropertyNameEnumerator*));
-JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, EncodedJSValue, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
+JSC_DECLARE_JIT_OPERATION(operationEnumeratorNextUpdatePropertyName, JSString*, (JSGlobalObject*, uint32_t, int32_t, JSPropertyNameEnumerator*));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorInByVal, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorHasOwnProperty, EncodedJSValue, (JSGlobalObject*, EncodedJSValue, EncodedJSValue, uint32_t, int32_t));
 JSC_DECLARE_JIT_OPERATION(operationEnumeratorRecoverNameAndGetByVal, EncodedJSValue, (JSGlobalObject*, JSCell*, uint32_t, JSPropertyNameEnumerator*));

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -1233,7 +1233,7 @@
         }
 
         case EnumeratorNextUpdatePropertyName: {
-            setPrediction(SpecString | SpecOther);
+            setPrediction(SpecStringIdent);
             break;
         }
 

Modified: branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -13582,12 +13582,12 @@
     SpeculateStrictInt32Operand indexOperand(this, node->child1());
     SpeculateStrictInt32Operand modeOperand(this, node->child2());
     SpeculateCellOperand enumeratorOperand(this, node->child3());
-    JSValueRegsTemporary resultTemp(this);
+    GPRTemporary result(this);
 
     GPRReg index = indexOperand.gpr();
     GPRReg mode = modeOperand.gpr();
     GPRReg enumerator = enumeratorOperand.gpr();
-    JSValueRegs resultRegs = resultTemp.regs();
+    GPRReg resultGPR = result.gpr();
 
     OptionSet seenModes = node->enumeratorMetadata();
 
@@ -13603,24 +13603,21 @@
 
         auto outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, index, MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::endGenericPropertyIndexOffset()));
 
-        m_jit.loadPtr(MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), resultRegs.payloadGPR());
-        m_jit.loadPtr(MacroAssembler::BaseIndex(resultRegs.payloadGPR(), index, MacroAssembler::ScalePtr), resultRegs.payloadGPR());
-#if USE(JSVALUE32_64)
-        m_jit.move(TrustedImm32(JSValue::CellTag), resultRegs.tagGPR());
-#endif
+        m_jit.loadPtr(MacroAssembler::Address(enumerator, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()), resultGPR);
+        m_jit.loadPtr(MacroAssembler::BaseIndex(resultGPR, index, MacroAssembler::ScalePtr), resultGPR);
         doneCases.append(m_jit.jump());
 
         outOfBounds.link(&m_jit);
-        m_jit.moveTrustedValue(jsNull(), resultRegs);
+        m_jit.move(TrustedImmPtr::weakPointer(m_graph, vm().smallStrings.sentinelString()), resultGPR);
         doneCases.append(m_jit.jump());
         operationCall.link(&m_jit);
     }
 
-    callOperation(operationEnumeratorNextUpdatePropertyName, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), index, mode, enumerator);
+    callOperation(operationEnumeratorNextUpdatePropertyName, resultGPR, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), index, mode, enumerator);
     m_jit.exceptionCheck();
 
     doneCases.link(&m_jit);
-    jsValueResult(resultRegs, node);
+    cellResult(resultGPR, node);
 }
 
 void SpeculativeJIT::compileEnumeratorGetByVal(Node* node)

Modified: branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -13428,7 +13428,7 @@
 
             {
                 m_out.appendTo(outOfBoundsBlock);
-                results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsNull()))));
+                results.append(m_out.anchor(weakPointer(vm().smallStrings.sentinelString())));
                 m_out.jump(continuation);
             }
 
@@ -13435,7 +13435,7 @@
             {
                 m_out.appendTo(loadPropertyNameBlock);
                 LValue namesVector = m_out.loadPtr(enumerator, m_heaps.JSPropertyNameEnumerator_cachedPropertyNamesVector);
-                results.append(m_out.anchor(m_out.zeroExtPtr(m_out.loadPtr(m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents.atAnyIndex(), namesVector, m_out.zeroExt(index, Int64), ScalePtr)))));
+                results.append(m_out.anchor(m_out.loadPtr(m_out.baseIndex(m_heaps.WriteBarrierBuffer_bufferContents.atAnyIndex(), namesVector, m_out.zeroExt(index, Int64), ScalePtr))));
                 m_out.jump(continuation);
             }
         }
@@ -13443,7 +13443,7 @@
         if (operationBlock)
             m_out.appendTo(operationBlock);
         // Note: We can't omit the operation because we have no guarantee that the mode will match what we profiled.
-        results.append(m_out.anchor(vmCall(Int64, operationEnumeratorNextUpdatePropertyName, weakPointer(globalObject), index, mode, enumerator)));
+        results.append(m_out.anchor(vmCall(pointerType(), operationEnumeratorNextUpdatePropertyName, weakPointer(globalObject), index, mode, enumerator)));
         if (continuation) {
             m_out.jump(continuation);
             m_out.appendTo(continuation);
@@ -13450,7 +13450,7 @@
         }
 
         ASSERT(results.size());
-        LValue result = m_out.phi(Int64, results);
+        LValue result = m_out.phi(pointerType(), results);
         setJSValue(result);
     }
 

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/JIT.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/jit/JIT.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/JIT.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -387,6 +387,7 @@
         DEFINE_OP(op_jneq_null)
         DEFINE_OP(op_jundefined_or_null)
         DEFINE_OP(op_jnundefined_or_null)
+        DEFINE_OP(op_jeq_ptr)
         DEFINE_OP(op_jneq_ptr)
         DEFINE_OP(op_jless)
         DEFINE_OP(op_jlesseq)

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/JIT.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/jit/JIT.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/JIT.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -461,6 +461,7 @@
         void emit_op_jneq_null(const Instruction*);
         void emit_op_jundefined_or_null(const Instruction*);
         void emit_op_jnundefined_or_null(const Instruction*);
+        void emit_op_jeq_ptr(const Instruction*);
         void emit_op_jneq_ptr(const Instruction*);
         void emit_op_jless(const Instruction*);
         void emit_op_jlesseq(const Instruction*);

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -579,6 +579,18 @@
     addJump(branch64(NotEqual, regT0, TrustedImm64(JSValue::encode(jsNull()))), target);
 }
 
+void JIT::emit_op_jeq_ptr(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpJeqPtr>();
+    VirtualRegister src = ""
+    JSValue specialPointer = getConstantOperand(bytecode.m_specialPointer);
+    ASSERT(specialPointer.isCell());
+    unsigned target = jumpTarget(currentInstruction, bytecode.m_targetLabel);
+
+    emitGetVirtualRegister(src, regT0);
+    addJump(branchPtr(Equal, regT0, TrustedImmPtr(specialPointer.asCell())), target);
+}
+
 void JIT::emit_op_jneq_ptr(const Instruction* currentInstruction)
 {
     auto bytecode = currentInstruction->as<OpJneqPtr>();

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/JITOpcodes32_64.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -501,6 +501,21 @@
     addJump(branchIfNotNull(regT0), target);
 }
 
+void JIT::emit_op_jeq_ptr(const Instruction* currentInstruction)
+{
+    auto bytecode = currentInstruction->as<OpJeqPtr>();
+    auto& metadata = bytecode.metadata(m_profiledCodeBlock);
+    VirtualRegister src = ""
+    JSValue specialPointer = getConstantOperand(bytecode.m_specialPointer);
+    ASSERT(specialPointer.isCell());
+    unsigned target = jumpTarget(currentInstruction, bytecode.m_targetLabel);
+
+    emitLoad(src, regT1, regT0);
+    Jump notCell = branchIfNotCell(regT1);
+    addJump(branchPtr(Equal, regT0, TrustedImmPtr(specialPointer.asCell())), target);
+    notCell.link(this);
+}
+
 void JIT::emit_op_jneq_ptr(const Instruction* currentInstruction)
 {
     auto bytecode = currentInstruction->as<OpJneqPtr>();

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/JITPropertyAccess.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -2866,7 +2866,7 @@
         done.append(jump());
 
         outOfBounds.link(this);
-        storeTrustedValue(jsNull(), addressFor(propertyName));
+        storeTrustedValue(vm().smallStrings.sentinelString(), addressFor(propertyName));
         done.append(jump());
     }
 

Modified: branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2021-09-27 22:49:47 UTC (rev 283148)
@@ -1944,6 +1944,20 @@
 undefinedOrNullJumpOp(jnundefined_or_null, OpJnundefinedOrNull,
     macro (value, target) bineq value, NullTag, target end)
 
+llintOpWithReturn(op_jeq_ptr, OpJeqPtr, macro (size, get, dispatch, return)
+    get(m_value, t0)
+    get(m_specialPointer, t1)
+    loadConstant(size, t1, t3, t2)
+    bineq TagOffset[cfr, t0, 8], CellTag, .opJeqPtrFallThrough
+    bpneq PayloadOffset[cfr, t0, 8], t2, .opJeqPtrFallThrough
+.opJeqPtrBranch:
+    get(m_targetLabel, t0)
+    jumpImpl(dispatchIndirect, t0)
+.opJeqPtrFallThrough:
+    dispatch()
+end)
+
+
 llintOpWithMetadata(op_jneq_ptr, OpJneqPtr, macro (size, get, dispatch, metadata, return)
     get(m_value, t0)
     get(m_specialPointer, t1)

Modified: branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2021-09-27 22:49:47 UTC (rev 283148)
@@ -2072,6 +2072,19 @@
 undefinedOrNullJumpOp(jnundefined_or_null, OpJnundefinedOrNull,
     macro (value, target) bqneq value, ValueNull, target end)
 
+llintOpWithReturn(op_jeq_ptr, OpJeqPtr, macro (size, get, dispatch, return)
+    get(m_value, t0)
+    get(m_specialPointer, t1)
+    loadConstant(size, t1, t2)
+    bpeq t2, [cfr, t0, 8], .opJeqPtrTarget
+    dispatch()
+
+.opJeqPtrTarget:
+    get(m_targetLabel, t0)
+    jumpImpl(dispatchIndirect, t0)
+end)
+
+
 llintOpWithMetadata(op_jneq_ptr, OpJneqPtr, macro (size, get, dispatch, metadata, return)
     get(m_value, t0)
     get(m_specialPointer, t1)

Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -1001,7 +1001,7 @@
     metadata.m_enumeratorMetadata |= static_cast<uint8_t>(mode);
     modeRegister = jsNumber(static_cast<uint8_t>(mode));
     indexRegister = jsNumber(index);
-    nameRegister = name ? name : jsNull();
+    nameRegister = name ? name : vm.smallStrings.sentinelString();
     END();
 }
 

Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -973,6 +973,8 @@
     m_setIteratorPrototype.set(vm, this, setIteratorPrototype);
     m_setIteratorStructure.set(vm, this, JSSetIterator::createStructure(vm, this, setIteratorPrototype));
 
+    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::sentinelString)].set(vm, this, vm.smallStrings.sentinelString());
+
     JSFunction* defaultPromiseThen = JSFunction::create(vm, promisePrototypeThenCodeGenerator(vm), this);
     m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::defaultPromiseThen)].set(vm, this, defaultPromiseThen);
 

Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.cpp (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.cpp	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.cpp	2021-09-27 22:49:47 UTC (rev 283148)
@@ -62,6 +62,7 @@
     initialize(&vm, m_notEqualString, "not-equal");
     initialize(&vm, m_timedOutString, "timed-out");
     initialize(&vm, m_okString, "ok");
+    initialize(&vm, m_sentinelString, "$");
 
     setIsInitialized(true);
 }
@@ -83,6 +84,7 @@
     visitor.appendUnbarriered(m_notEqualString);
     visitor.appendUnbarriered(m_timedOutString);
     visitor.appendUnbarriered(m_okString);
+    visitor.appendUnbarriered(m_sentinelString);
 }
 
 template void SmallStrings::visitStrongReferences(AbstractSlotVisitor&);

Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.h (283147 => 283148)


--- branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.h	2021-09-27 22:49:38 UTC (rev 283147)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/SmallStrings.h	2021-09-27 22:49:47 UTC (rev 283148)
@@ -119,6 +119,7 @@
     JSString* notEqualString() const { return m_notEqualString; }
     JSString* timedOutString() const { return m_timedOutString; }
     JSString* okString() const { return m_okString; }
+    JSString* sentinelString() const { return m_sentinelString; }
 
     bool needsToBeVisited(CollectionScope scope) const
     {
@@ -143,6 +144,7 @@
     JSString* m_notEqualString { nullptr };
     JSString* m_timedOutString { nullptr };
     JSString* m_okString { nullptr };
+    JSString* m_sentinelString { nullptr };
     JSString* m_singleCharacterStrings[singleCharacterStringCount] { nullptr };
     bool m_needsToBeVisited { true };
     bool m_isInitialized { false };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to