Title: [246553] trunk
Revision
246553
Author
tzaga...@apple.com
Date
2019-06-18 11:56:50 -0700 (Tue, 18 Jun 2019)

Log Message

DFG code should not reify the names of builtin functions with private names
https://bugs.webkit.org/show_bug.cgi?id=198849
<rdar://problem/51733890>

Reviewed by Filip Pizlo.

JSTests:

* stress/builtin-private-function-name.js: Added.
(then):
(PromiseLike):

Source/_javascript_Core:

Builtin functions that have a private name call setHasReifiedName from finishCreation.
When compiled with DFG and FTL, that does not get called and the function ends up reifying
its name. In order to fix that, we initialize FunctionRareData and set m_hasReifiedName to
true from compileNewFunction in both DFG and FTL.

* bytecode/InternalFunctionAllocationProfile.h:
(JSC::InternalFunctionAllocationProfile::offsetOfStructure):
* bytecode/ObjectAllocationProfile.h:
(JSC::ObjectAllocationProfileWithPrototype::offsetOfPrototype):
* bytecode/UnlinkedFunctionExecutable.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewFunctionCommon):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):
* runtime/FunctionExecutable.h:
* runtime/FunctionRareData.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::finishCreation):
* runtime/JSFunction.h:
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::isAnonymousBuiltinFunction const):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (246552 => 246553)


--- trunk/JSTests/ChangeLog	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/JSTests/ChangeLog	2019-06-18 18:56:50 UTC (rev 246553)
@@ -1,3 +1,15 @@
+2019-06-18  Tadeu Zagallo  <tzaga...@apple.com>
+
+        DFG code should not reify the names of builtin functions with private names
+        https://bugs.webkit.org/show_bug.cgi?id=198849
+        <rdar://problem/51733890>
+
+        Reviewed by Filip Pizlo.
+
+        * stress/builtin-private-function-name.js: Added.
+        (then):
+        (PromiseLike):
+
 2019-06-18  Keith Miller  <keith_mil...@apple.com>
 
         MaybeParseAsGeneratorForScope sometimes loses track of its scope ref

Added: trunk/JSTests/stress/builtin-private-function-name.js (0 => 246553)


--- trunk/JSTests/stress/builtin-private-function-name.js	                        (rev 0)
+++ trunk/JSTests/stress/builtin-private-function-name.js	2019-06-18 18:56:50 UTC (rev 246553)
@@ -0,0 +1,15 @@
+let resolve;
+function then(resolveElement) {
+    resolve = resolveElement;
+}
+
+function PromiseLike(executor) {
+    executor(()=>{}, ()=>{});
+}
+
+PromiseLike.resolve = x => x;
+
+for (let i = 0; i < 1e5; i++) {
+    Promise.all.call(PromiseLike, [{ then }]);
+    resolve.hasOwnProperty('name');
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (246552 => 246553)


--- trunk/Source/_javascript_Core/ChangeLog	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-06-18 18:56:50 UTC (rev 246553)
@@ -1,3 +1,34 @@
+2019-06-18  Tadeu Zagallo  <tzaga...@apple.com>
+
+        DFG code should not reify the names of builtin functions with private names
+        https://bugs.webkit.org/show_bug.cgi?id=198849
+        <rdar://problem/51733890>
+
+        Reviewed by Filip Pizlo.
+
+        Builtin functions that have a private name call setHasReifiedName from finishCreation.
+        When compiled with DFG and FTL, that does not get called and the function ends up reifying
+        its name. In order to fix that, we initialize FunctionRareData and set m_hasReifiedName to
+        true from compileNewFunction in both DFG and FTL.
+
+        * bytecode/InternalFunctionAllocationProfile.h:
+        (JSC::InternalFunctionAllocationProfile::offsetOfStructure):
+        * bytecode/ObjectAllocationProfile.h:
+        (JSC::ObjectAllocationProfileWithPrototype::offsetOfPrototype):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):
+        * runtime/FunctionExecutable.h:
+        * runtime/FunctionRareData.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::finishCreation):
+        * runtime/JSFunction.h:
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::isAnonymousBuiltinFunction const):
+
 2019-06-18  Keith Miller  <keith_mil...@apple.com>
 
         MaybeParseAsGeneratorForScope sometimes loses track of its scope ref

Modified: trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h (246552 => 246553)


--- trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/bytecode/InternalFunctionAllocationProfile.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -33,6 +33,8 @@
 
 class InternalFunctionAllocationProfile {
 public:
+    static inline ptrdiff_t offsetOfStructure() { return OBJECT_OFFSETOF(InternalFunctionAllocationProfile, m_structure); }
+
     Structure* structure() { return m_structure.get(); }
     Structure* createAllocationStructureFromBase(VM&, JSGlobalObject*, JSCell* owner, JSObject* prototype, Structure* base);
 

Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h (246552 => 246553)


--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfile.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -92,6 +92,8 @@
 public:
     using Base = ObjectAllocationProfileBase<ObjectAllocationProfileWithPrototype>;
 
+    static ptrdiff_t offsetOfPrototype() { return OBJECT_OFFSETOF(ObjectAllocationProfileWithPrototype, m_prototype); }
+
     ObjectAllocationProfileWithPrototype() = default;
 
     JSObject* prototype()

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h (246552 => 246553)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -145,6 +145,7 @@
     static void destroy(JSCell*);
 
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
+    bool isAnonymousBuiltinFunction() const { return isBuiltinFunction() && name().isPrivateName(); }
     ConstructAbility constructAbility() const { return static_cast<ConstructAbility>(m_constructAbility); }
     JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
     bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (246552 => 246553)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-06-18 18:56:50 UTC (rev 246553)
@@ -7182,7 +7182,27 @@
     m_jit.storePtr(TrustedImmPtr::weakPointer(m_jit.graph(), executable), JITCompiler::Address(resultGPR, JSFunction::offsetOfExecutable()));
     m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(resultGPR, JSFunction::offsetOfRareData()));
     
-    m_jit.mutatorFence(*m_jit.vm());
+    if (executable->isAnonymousBuiltinFunction()) {
+        VM& vm = *m_jit.vm();
+        GPRTemporary allocator(this);
+        Allocator allocatorValue = allocatorForNonVirtualConcurrently<FunctionRareData>(vm, sizeof(FunctionRareData), AllocatorForMode::AllocatorIfExists);
+        emitAllocateJSCell(scratch1GPR, JITAllocator::constant(allocatorValue), allocator.gpr(), TrustedImmPtr(m_jit.graph().registerStructure(vm.functionRareDataStructure.get())), scratch2GPR, slowPath);
+
+        ptrdiff_t objectAllocationProfileOffset = FunctionRareData::offsetOfObjectAllocationProfile();
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfAllocator()));
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfStructure()));
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfPrototype()));
+        m_jit.storePtr(TrustedImmPtr(0x1), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfObjectAllocationProfileWatchpoint()));
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure()));
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfBoundFunctionStructure()));
+        m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfAllocationProfileClearingWatchpoint()));
+        m_jit.store8(TrustedImm32(0), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfHasReifiedLength()));
+        m_jit.store8(TrustedImm32(1), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfHasReifiedName()));
+        m_jit.mutatorFence(vm);
+        m_jit.storePtr(scratch1GPR, JITCompiler::Address(resultGPR, JSFunction::offsetOfRareData()));
+    } else
+        m_jit.mutatorFence(*m_jit.vm());
+
 }
 
 void SpeculativeJIT::compileNewFunction(Node* node)

Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (246552 => 246553)


--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -59,6 +59,13 @@
     macro(DirectArguments_modifiedArgumentsDescriptor, DirectArguments::offsetOfModifiedArgumentsDescriptor()) \
     macro(FunctionRareData_allocator, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfileWithPrototype::offsetOfAllocator()) \
     macro(FunctionRareData_structure, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfileWithPrototype::offsetOfStructure()) \
+    macro(FunctionRareData_prototype, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfileWithPrototype::offsetOfPrototype()) \
+    macro(FunctionRareData_objectAllocationProfileWatchpoint, FunctionRareData::offsetOfObjectAllocationProfileWatchpoint()) \
+    macro(FunctionRareData_internalFunctionAllocationProfile_structure, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure()) \
+    macro(FunctionRareData_boundFunctionStructure, FunctionRareData::offsetOfBoundFunctionStructure()) \
+    macro(FunctionRareData_allocationProfileClearingWatchpoint, FunctionRareData::offsetOfAllocationProfileClearingWatchpoint()) \
+    macro(FunctionRareData_hasReifiedLength, FunctionRareData::offsetOfHasReifiedLength()) \
+    macro(FunctionRareData_hasReifiedName, FunctionRareData::offsetOfHasReifiedName()) \
     macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
     macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
     macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (246552 => 246553)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-06-18 18:56:50 UTC (rev 246553)
@@ -5547,8 +5547,24 @@
         m_out.storePtr(weakPointer(executable), fastObject, m_heaps.JSFunction_executable);
         m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.JSFunction_rareData);
         
-        mutatorFence();
-        
+        VM& vm = this->vm();
+        if (executable->isAnonymousBuiltinFunction()) {
+            Allocator allocator = allocatorForNonVirtualConcurrently<FunctionRareData>(vm, sizeof(FunctionRareData), AllocatorForMode::AllocatorIfExists);
+            LValue rareData = allocateCell(m_out.constIntPtr(allocator.localAllocator()), vm.functionRareDataStructure.get(), slowPath);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_allocator);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_structure);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_prototype);
+            m_out.storePtr(m_out.intPtrOne, rareData, m_heaps.FunctionRareData_objectAllocationProfileWatchpoint);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_boundFunctionStructure);
+            m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_allocationProfileClearingWatchpoint);
+            m_out.store32As8(m_out.int32One, rareData, m_heaps.FunctionRareData_hasReifiedName);
+            m_out.store32As8(m_out.int32Zero, rareData, m_heaps.FunctionRareData_hasReifiedLength);
+            mutatorFence();
+            m_out.storePtr(rareData, fastObject, m_heaps.JSFunction_rareData);
+        } else
+            mutatorFence();
+
         ValueFromBlock fastResult = m_out.anchor(fastObject);
         m_out.jump(continuation);
         
@@ -5556,7 +5572,6 @@
 
         Vector<LValue> slowPathArguments;
         slowPathArguments.append(scope);
-        VM& vm = this->vm();
         LValue callResult = lazySlowPath(
             [=, &vm] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
                 auto* operation = operationNewFunctionWithInvalidatedReallocationWatchpoint;

Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.h (246552 => 246553)


--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -131,6 +131,7 @@
         
     FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
     bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); }
+    bool isAnonymousBuiltinFunction() const { return m_unlinkedExecutable->isAnonymousBuiltinFunction(); }
     ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }
     bool isClass() const { return m_unlinkedExecutable->isClass(); }
     bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }

Modified: trunk/Source/_javascript_Core/runtime/FunctionRareData.h (246552 => 246553)


--- trunk/Source/_javascript_Core/runtime/FunctionRareData.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/runtime/FunctionRareData.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -61,10 +61,13 @@
 
     DECLARE_INFO;
 
-    static inline ptrdiff_t offsetOfObjectAllocationProfile()
-    {
-        return OBJECT_OFFSETOF(FunctionRareData, m_objectAllocationProfile);
-    }
+    static inline ptrdiff_t offsetOfObjectAllocationProfile() { return OBJECT_OFFSETOF(FunctionRareData, m_objectAllocationProfile); }
+    static inline ptrdiff_t offsetOfObjectAllocationProfileWatchpoint() { return OBJECT_OFFSETOF(FunctionRareData, m_objectAllocationProfileWatchpoint); }
+    static inline ptrdiff_t offsetOfInternalFunctionAllocationProfile() { return OBJECT_OFFSETOF(FunctionRareData, m_internalFunctionAllocationProfile); }
+    static inline ptrdiff_t offsetOfBoundFunctionStructure() { return OBJECT_OFFSETOF(FunctionRareData, m_boundFunctionStructure); }
+    static inline ptrdiff_t offsetOfAllocationProfileClearingWatchpoint() { return OBJECT_OFFSETOF(FunctionRareData, m_allocationProfileClearingWatchpoint); }
+    static inline ptrdiff_t offsetOfHasReifiedLength() { return OBJECT_OFFSETOF(FunctionRareData, m_hasReifiedLength); }
+    static inline ptrdiff_t offsetOfHasReifiedName() { return OBJECT_OFFSETOF(FunctionRareData, m_hasReifiedName); }
 
     ObjectAllocationProfileWithPrototype* objectAllocationProfile()
     {

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (246552 => 246553)


--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2019-06-18 18:56:50 UTC (rev 246553)
@@ -112,7 +112,7 @@
     Base::finishCreation(vm);
     ASSERT(jsDynamicCast<JSFunction*>(vm, this));
     ASSERT(type() == JSFunctionType);
-    if (isBuiltinFunction() && jsExecutable()->name().isPrivateName()) {
+    if (isAnonymousBuiltinFunction()) {
         // This is anonymous builtin function.
         rareData(vm)->setHasReifiedName();
     }

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.h (246552 => 246553)


--- trunk/Source/_javascript_Core/runtime/JSFunction.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -145,6 +145,7 @@
 
     bool isHostOrBuiltinFunction() const;
     bool isBuiltinFunction() const;
+    bool isAnonymousBuiltinFunction() const;
     JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
     bool isClassConstructorFunction() const;
 

Modified: trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h (246552 => 246553)


--- trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h	2019-06-18 18:10:08 UTC (rev 246552)
+++ trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h	2019-06-18 18:56:50 UTC (rev 246553)
@@ -68,6 +68,11 @@
     return !isHostFunction() && jsExecutable()->isBuiltinFunction();
 }
 
+inline bool JSFunction::isAnonymousBuiltinFunction() const
+{
+    return !isHostFunction() && jsExecutable()->isAnonymousBuiltinFunction();
+}
+
 inline bool JSFunction::isHostOrBuiltinFunction() const
 {
     return isHostFunction() || isBuiltinFunction();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to