Title: [285315] branches/safari-612-branch
Revision
285315
Author
[email protected]
Date
2021-11-04 14:43:02 -0700 (Thu, 04 Nov 2021)

Log Message

Cherry-pick r283512. rdar://problem/85034084

    IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
    https://bugs.webkit.org/show_bug.cgi?id=229951
    <rdar://problem/82787527>

    Reviewed by Yusuke Suzuki.

    JSTests:

    * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
    (assert):
    (main.v37):
    (main):

    Source/_javascript_Core:

    The whole point of get_by_id_with_this is to have different
    slot base values for |this| vs the slot base when invoking
    getters. However, our intrinsic getter inlining wasn't respecting
    this. This patch makes the __proto__ intrinsic getter do the right
    thing. For typed array intrinsic getters, if they have different
    |this| value vs slot base, we chose not to inline them, because
    the type checks are not on the |this| value, so they're not guaranteed
    to be typed arrays. We can improve upon this in the future.

    * bytecode/IntrinsicGetterAccessCase.h:
    * jit/AssemblyHelpers.cpp:
    (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
    * jit/AssemblyHelpers.h:
    * jit/IntrinsicEmitter.cpp:
    (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
    (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
    * jit/Repatch.cpp:
    (JSC::tryCacheGetBy):

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-612-branch/JSTests/ChangeLog (285314 => 285315)


--- branches/safari-612-branch/JSTests/ChangeLog	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/JSTests/ChangeLog	2021-11-04 21:43:02 UTC (rev 285315)
@@ -1,5 +1,59 @@
 2021-11-04  Russell Epstein  <[email protected]>
 
+        Cherry-pick r283512. rdar://problem/85034084
+
+    IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+    https://bugs.webkit.org/show_bug.cgi?id=229951
+    <rdar://problem/82787527>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    JSTests:
+    
+    * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+    (assert):
+    (main.v37):
+    (main):
+    
+    Source/_javascript_Core:
+    
+    The whole point of get_by_id_with_this is to have different
+    slot base values for |this| vs the slot base when invoking
+    getters. However, our intrinsic getter inlining wasn't respecting
+    this. This patch makes the __proto__ intrinsic getter do the right
+    thing. For typed array intrinsic getters, if they have different
+    |this| value vs slot base, we chose not to inline them, because
+    the type checks are not on the |this| value, so they're not guaranteed
+    to be typed arrays. We can improve upon this in the future.
+    
+    * bytecode/IntrinsicGetterAccessCase.h:
+    * jit/AssemblyHelpers.cpp:
+    (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+    * jit/AssemblyHelpers.h:
+    * jit/IntrinsicEmitter.cpp:
+    (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+    (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+    * jit/Repatch.cpp:
+    (JSC::tryCacheGetBy):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-10-04  Saam Barati  <[email protected]>
+
+            IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+            https://bugs.webkit.org/show_bug.cgi?id=229951
+            <rdar://problem/82787527>
+
+            Reviewed by Yusuke Suzuki.
+
+            * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+            (assert):
+            (main.v37):
+            (main):
+
+2021-11-04  Russell Epstein  <[email protected]>
+
         Cherry-pick r285117. rdar://problem/84402043
 
     JSGenericTypedArrayView<Adaptor>::set crashes if the length + objectOffset is > UINT32_MAX

Added: branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js (0 => 285315)


--- branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js	                        (rev 0)
+++ branches/safari-612-branch/JSTests/stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js	2021-11-04 21:43:02 UTC (rev 285315)
@@ -0,0 +1,25 @@
+//@ runDefault("--forcePolyProto=true", "--validateOptions=true", "--useConcurrentJIT=false", "--useConcurrentGC=false", "--thresholdForJITSoon=10", "--thresholdForJITAfterWarmUp=10", "--thresholdForOptimizeAfterWarmUp=100", "--thresholdForOptimizeAfterLongWarmUp=100", "--thresholdForOptimizeSoon=100", "--thresholdForFTLOptimizeAfterWarmUp=1000", "--thresholdForFTLOptimizeSoon=1000", "--validateBCE=true", "--useFTLJIT=true")
+
+function assert(b) {
+    if (!b)
+        throw new Error;
+}
+
+function main() {
+    let v41;
+
+    v37 = class V37 {
+        constructor() {
+            v41 = super.__proto__;
+        }
+    };
+
+    for (let v70 = 0; v70 < 100; v70++) {
+        new v37();
+        assert(v41 !== null);
+    }
+
+}
+noDFG(main);
+noFTL(main);
+main();

Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-11-04 21:43:02 UTC (rev 285315)
@@ -1,5 +1,73 @@
 2021-11-04  Russell Epstein  <[email protected]>
 
+        Cherry-pick r283512. rdar://problem/85034084
+
+    IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+    https://bugs.webkit.org/show_bug.cgi?id=229951
+    <rdar://problem/82787527>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    JSTests:
+    
+    * stress/run-proto-intrinsic-getter-with-this-value-in-get-by-id-with-this.js: Added.
+    (assert):
+    (main.v37):
+    (main):
+    
+    Source/_javascript_Core:
+    
+    The whole point of get_by_id_with_this is to have different
+    slot base values for |this| vs the slot base when invoking
+    getters. However, our intrinsic getter inlining wasn't respecting
+    this. This patch makes the __proto__ intrinsic getter do the right
+    thing. For typed array intrinsic getters, if they have different
+    |this| value vs slot base, we chose not to inline them, because
+    the type checks are not on the |this| value, so they're not guaranteed
+    to be typed arrays. We can improve upon this in the future.
+    
+    * bytecode/IntrinsicGetterAccessCase.h:
+    * jit/AssemblyHelpers.cpp:
+    (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+    * jit/AssemblyHelpers.h:
+    * jit/IntrinsicEmitter.cpp:
+    (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+    (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+    * jit/Repatch.cpp:
+    (JSC::tryCacheGetBy):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@283512 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-10-04  Saam Barati  <[email protected]>
+
+            IntrinsicGetterAccessCase implementation of __proto__ needs to handle get_by_id_with_this
+            https://bugs.webkit.org/show_bug.cgi?id=229951
+            <rdar://problem/82787527>
+
+            Reviewed by Yusuke Suzuki.
+
+            The whole point of get_by_id_with_this is to have different
+            slot base values for |this| vs the slot base when invoking
+            getters. However, our intrinsic getter inlining wasn't respecting
+            this. This patch makes the __proto__ intrinsic getter do the right
+            thing. For typed array intrinsic getters, if they have different
+            |this| value vs slot base, we chose not to inline them, because
+            the type checks are not on the |this| value, so they're not guaranteed
+            to be typed arrays. We can improve upon this in the future.
+
+            * bytecode/IntrinsicGetterAccessCase.h:
+            * jit/AssemblyHelpers.cpp:
+            (JSC::AssemblyHelpers::emitLoadPrototypeWithoutCheck):
+            * jit/AssemblyHelpers.h:
+            * jit/IntrinsicEmitter.cpp:
+            (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
+            (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
+            * jit/Repatch.cpp:
+            (JSC::tryCacheGetBy):
+
+2021-11-04  Russell Epstein  <[email protected]>
+
         Cherry-pick r285149. rdar://problem/81217357
 
     [JSC] LLIntCallee should have two replacements

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/IntrinsicGetterAccessCase.h	2021-11-04 21:43:02 UTC (rev 285315)
@@ -39,7 +39,7 @@
     JSFunction* intrinsicFunction() const { return m_intrinsicFunction.get(); }
     Intrinsic intrinsic() const { return m_intrinsicFunction->intrinsic(); }
 
-    static bool canEmitIntrinsicGetter(JSFunction*, Structure*);
+    static bool canEmitIntrinsicGetter(StructureStubInfo&, JSFunction*, Structure*);
     void emitIntrinsicGetter(AccessGenerationState&);
 
     static Ref<AccessCase> create(VM&, JSCell*, CacheableIdentifier, PropertyOffset, Structure*, const ObjectPropertyConditionSet&, JSFunction* intrinsicFunction, RefPtr<PolyProtoAccessChain>&&);

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp	2021-11-04 21:43:02 UTC (rev 285315)
@@ -413,6 +413,36 @@
     hasMonoProto.link(this);
 }
 
+void AssemblyHelpers::emitLoadPrototypeWithoutCheck(VM& vm, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, GPRReg scratch2GPR)
+{
+    ASSERT(objectGPR != scratchGPR);
+    ASSERT(objectGPR != scratch2GPR);
+    ASSERT(resultRegs.payloadGPR() != scratchGPR);
+    ASSERT(resultRegs.payloadGPR() != scratch2GPR);
+#if USE(JSVALUE32_64)
+    ASSERT(resultRegs.tagGPR() != scratchGPR);
+    ASSERT(resultRegs.tagGPR() != scratch2GPR);
+#endif
+
+    emitLoadStructure(vm, objectGPR, scratchGPR, scratch2GPR);
+#if USE(JSVALUE64)
+    loadValue(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset()), JSValueRegs(scratch2GPR));
+#else
+    load32(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset() + TagOffset), scratch2GPR);
+#endif
+    auto hasMonoProto = branchIfNotEmpty(scratch2GPR);
+    loadValue(MacroAssembler::Address(objectGPR, offsetRelativeToBase(knownPolyProtoOffset)), resultRegs);
+    auto done = jump();
+    hasMonoProto.link(this);
+#if USE(JSVALUE64)
+    move(scratch2GPR, resultRegs.payloadGPR());
+#else
+    load32(MacroAssembler::Address(scratchGPR, Structure::prototypeOffset() + PayloadOffset), resultRegs.payloadGPR());
+    move(scratch2GPR, resultRegs.tagGPR());
+#endif
+    done.link(this);
+}
+
 void AssemblyHelpers::makeSpaceOnStackForCCall()
 {
     unsigned stackOffset = WTF::roundUpToMultipleOf(stackAlignmentBytes(), maxFrameExtentForSlowPathCall);

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2021-11-04 21:43:02 UTC (rev 285315)
@@ -1518,6 +1518,7 @@
     
     void emitLoadStructure(VM&, RegisterID source, RegisterID dest, RegisterID scratch);
     void emitLoadPrototype(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, JumpList& slowPath);
+    void emitLoadPrototypeWithoutCheck(VM&, GPRReg objectGPR, JSValueRegs resultRegs, GPRReg scratchGPR, GPRReg scratch2GPR);
 
     void emitStoreStructureWithTypeInfo(TrustedImmPtr structure, RegisterID dest, RegisterID)
     {

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/IntrinsicEmitter.cpp	2021-11-04 21:43:02 UTC (rev 285315)
@@ -46,7 +46,7 @@
 typedef CCallHelpers::TrustedImm64 TrustedImm64;
 typedef CCallHelpers::Imm64 Imm64;
 
-bool IntrinsicGetterAccessCase::canEmitIntrinsicGetter(JSFunction* getter, Structure* structure)
+bool IntrinsicGetterAccessCase::canEmitIntrinsicGetter(StructureStubInfo& stubInfo, JSFunction* getter, Structure* structure)
 {
 
     switch (getter->intrinsic()) {
@@ -53,6 +53,10 @@
     case TypedArrayByteOffsetIntrinsic:
     case TypedArrayByteLengthIntrinsic:
     case TypedArrayLengthIntrinsic: {
+        // We aren't structure checking the this value, so we don't know it's a typed array.
+        if (stubInfo.thisValueIsInThisGPR())
+            return false;
+
         TypedArrayType type = structure->classInfo()->typedArrayStorageType;
 
         if (!isTypedView(type))
@@ -146,10 +150,34 @@
     }
 
     case UnderscoreProtoIntrinsic: {
-        if (structure()->hasPolyProto())
-            jit.loadValue(CCallHelpers::Address(baseGPR, offsetRelativeToBase(knownPolyProtoOffset)), valueRegs);
-        else
-            jit.moveValue(structure()->storedPrototype(), valueRegs);
+        StructureStubInfo& stubInfo = *state.stubInfo;
+        if (stubInfo.thisValueIsInThisGPR()) {
+            ScratchRegisterAllocator allocator(stubInfo.usedRegisters);
+            allocator.lock(state.scratchGPR);
+            allocator.lock(state.baseGPR);
+            allocator.lock(state.u.thisGPR);
+            allocator.lock(valueRegs);
+#if USE(JSVALUE32_64)
+            allocator.lock(stubInfo.baseTagGPR);
+            allocator.lock(stubInfo.v.thisTagGPR);
+#endif
+            if (stubInfo.m_stubInfoGPR != InvalidGPRReg)
+                allocator.lock(stubInfo.m_stubInfoGPR);
+            if (stubInfo.m_arrayProfileGPR != InvalidGPRReg)
+                allocator.lock(stubInfo.m_arrayProfileGPR);
+
+            GPRReg scratch2GPR = allocator.allocateScratchGPR();
+            auto preservedState = allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
+
+            jit.emitLoadPrototypeWithoutCheck(state.m_vm, state.u.thisGPR, valueRegs, state.scratchGPR, scratch2GPR);
+
+            allocator.restoreReusedRegistersByPopping(jit, preservedState);
+        } else {
+            if (structure()->hasPolyProto())
+                jit.loadValue(CCallHelpers::Address(baseGPR, offsetRelativeToBase(knownPolyProtoOffset)), valueRegs);
+            else
+                jit.moveValue(structure()->storedPrototype(), valueRegs);
+        }
         state.succeed();
         return;
     }

Modified: branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp (285314 => 285315)


--- branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp	2021-11-04 21:42:57 UTC (rev 285314)
+++ branches/safari-612-branch/Source/_javascript_Core/jit/Repatch.cpp	2021-11-04 21:43:02 UTC (rev 285315)
@@ -404,7 +404,7 @@
                     RELEASE_ASSERT_NOT_REACHED();
 
                 newCase = ProxyableAccessCase::create(vm, codeBlock, type, propertyName, offset, structure, conditionSet, loadTargetFromProxy, slot.watchpointSet(), WTFMove(prototypeAccessChain));
-            } else if (!loadTargetFromProxy && getter && IntrinsicGetterAccessCase::canEmitIntrinsicGetter(getter, structure))
+            } else if (!loadTargetFromProxy && getter && IntrinsicGetterAccessCase::canEmitIntrinsicGetter(stubInfo, getter, structure))
                 newCase = IntrinsicGetterAccessCase::create(vm, codeBlock, propertyName, slot.cachedOffset(), structure, conditionSet, getter, WTFMove(prototypeAccessChain));
             else {
                 if (isPrivate) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to