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();