Changeset 249650 in webkit
- Timestamp:
- Sep 9, 2019 10:52:07 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r249644 r249650 1 2019-09-09 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Promise resolve/reject functions should be created more efficiently 4 https://bugs.webkit.org/show_bug.cgi?id=201488 5 6 Reviewed by Mark Lam. 7 8 * microbenchmarks/promise-creation-many.js: Added. 9 (executor): 10 1 11 2019-09-09 Zan Dobersek <zdobersek@igalia.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r249613 r249650 1 2019-09-09 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Promise resolve/reject functions should be created more efficiently 4 https://bugs.webkit.org/show_bug.cgi?id=201488 5 6 Reviewed by Mark Lam. 7 8 While r246553 fixed an important issue, it makes anonymous-builtin-function creation costly since it enforces FunctionRareData allocations. 9 Unfortunately, anonymous-builtin-function function can be created frequently since this type of function is used 10 for `resolve` and `reject` arguments of Promise's executor (e.g. `new Promise((resolve, reject) => ...)`'s resolve and reject). 11 Since we are now always creating FunctionRareData for these functions, this additional allocation makes promise creation slower. 12 13 In this patch, we use `isAnonymousBuiltinFunction` information for `hasReifiedName` correctly. And we propagate `isAnonymousBuiltinFunction` information 14 to FunctionRareData to initialize `m_hasReifiedName` correctly. Then we can avoid unnecessary FunctionRareData allocation, which makes 15 anonymous-builtin-function creation faster. 16 17 We can ensure that this patch does not revert r246553's fix by running JSTests/stress/builtin-private-function-name.js test. 18 The simple microbenchmark shows 1.7x improvement. 19 20 ToT Patched 21 22 promise-creation-many 45.6701+-0.1488 ^ 26.8663+-1.8336 ^ definitely 1.6999x faster 23 24 * dfg/DFGSpeculativeJIT.cpp: 25 (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon): 26 * ftl/FTLLowerDFGToB3.cpp: 27 (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction): 28 * runtime/FunctionRareData.cpp: 29 (JSC::FunctionRareData::create): 30 (JSC::FunctionRareData::FunctionRareData): 31 * runtime/FunctionRareData.h: 32 * runtime/JSFunction.cpp: 33 (JSC::JSFunction::finishCreation): 34 (JSC::JSFunction::allocateRareData): 35 (JSC::JSFunction::allocateAndInitializeRareData): 36 * runtime/JSFunctionInlines.h: 37 (JSC::JSFunction::hasReifiedName const): 38 1 39 2019-09-07 Mark Lam <mark.lam@apple.com> 2 40 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r249597 r249650 7213 7213 m_jit.storePtr(TrustedImmPtr::weakPointer(m_jit.graph(), executable), JITCompiler::Address(resultGPR, JSFunction::offsetOfExecutable())); 7214 7214 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(resultGPR, JSFunction::offsetOfRareData())); 7215 7216 if (executable->isAnonymousBuiltinFunction()) { 7217 VM& vm = this->vm(); 7218 m_jit.mutatorFence(vm); 7219 GPRTemporary allocator(this); 7220 Allocator allocatorValue = allocatorForNonVirtualConcurrently<FunctionRareData>(vm, sizeof(FunctionRareData), AllocatorForMode::AllocatorIfExists); 7221 emitAllocateJSCell(scratch1GPR, JITAllocator::constant(allocatorValue), allocator.gpr(), TrustedImmPtr(m_jit.graph().registerStructure(vm.functionRareDataStructure.get())), scratch2GPR, slowPath); 7222 7223 ptrdiff_t objectAllocationProfileOffset = FunctionRareData::offsetOfObjectAllocationProfile(); 7224 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfAllocator())); 7225 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfStructure())); 7226 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, objectAllocationProfileOffset + ObjectAllocationProfileWithPrototype::offsetOfPrototype())); 7227 m_jit.storePtr(TrustedImmPtr(0x1), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfAllocationProfileWatchpointSet())); 7228 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfInternalFunctionAllocationProfile() + InternalFunctionAllocationProfile::offsetOfStructure())); 7229 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfBoundFunctionStructure())); 7230 m_jit.storePtr(TrustedImmPtr(nullptr), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfAllocationProfileClearingWatchpoint())); 7231 m_jit.store8(TrustedImm32(0), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfHasReifiedLength())); 7232 m_jit.store8(TrustedImm32(1), JITCompiler::Address(scratch1GPR, FunctionRareData::offsetOfHasReifiedName())); 7233 m_jit.mutatorFence(vm); 7234 m_jit.storePtr(scratch1GPR, JITCompiler::Address(resultGPR, JSFunction::offsetOfRareData())); 7235 } else 7236 m_jit.mutatorFence(vm()); 7237 7215 m_jit.mutatorFence(vm()); 7238 7216 } 7239 7217 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r249597 r249650 5576 5576 m_out.storePtr(weakPointer(executable), fastObject, m_heaps.JSFunction_executable); 5577 5577 m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.JSFunction_rareData); 5578 5579 VM& vm = this->vm(); 5580 if (executable->isAnonymousBuiltinFunction()) { 5581 mutatorFence(); 5582 Allocator allocator = allocatorForNonVirtualConcurrently<FunctionRareData>(vm, sizeof(FunctionRareData), AllocatorForMode::AllocatorIfExists); 5583 LValue rareData = allocateCell(m_out.constIntPtr(allocator.localAllocator()), vm.functionRareDataStructure.get(), slowPath); 5584 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_allocator); 5585 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_structure); 5586 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_prototype); 5587 m_out.storePtr(m_out.intPtrOne, rareData, m_heaps.FunctionRareData_allocationProfileWatchpointSet); 5588 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_internalFunctionAllocationProfile_structure); 5589 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_boundFunctionStructure); 5590 m_out.storePtr(m_out.intPtrZero, rareData, m_heaps.FunctionRareData_allocationProfileClearingWatchpoint); 5591 m_out.store32As8(m_out.int32One, rareData, m_heaps.FunctionRareData_hasReifiedName); 5592 m_out.store32As8(m_out.int32Zero, rareData, m_heaps.FunctionRareData_hasReifiedLength); 5593 mutatorFence(); 5594 m_out.storePtr(rareData, fastObject, m_heaps.JSFunction_rareData); 5595 } else 5596 mutatorFence(); 5578 mutatorFence(); 5597 5579 5598 5580 ValueFromBlock fastResult = m_out.anchor(fastObject); … … 5603 5585 Vector<LValue> slowPathArguments; 5604 5586 slowPathArguments.append(scope); 5587 VM& vm = this->vm(); 5605 5588 LValue callResult = lazySlowPath( 5606 5589 [=, &vm] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> { -
trunk/Source/JavaScriptCore/runtime/FunctionRareData.cpp
r249509 r249650 34 34 const ClassInfo FunctionRareData::s_info = { "FunctionRareData", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(FunctionRareData) }; 35 35 36 FunctionRareData* FunctionRareData::create(VM& vm )36 FunctionRareData* FunctionRareData::create(VM& vm, JSFunction* function) 37 37 { 38 FunctionRareData* rareData = new (NotNull, allocateCell<FunctionRareData>(vm.heap)) FunctionRareData(vm );38 FunctionRareData* rareData = new (NotNull, allocateCell<FunctionRareData>(vm.heap)) FunctionRareData(vm, function); 39 39 rareData->finishCreation(vm); 40 40 return rareData; … … 63 63 } 64 64 65 FunctionRareData::FunctionRareData(VM& vm )65 FunctionRareData::FunctionRareData(VM& vm, JSFunction* function) 66 66 : Base(vm, vm.functionRareDataStructure.get()) 67 67 , m_objectAllocationProfile() … … 70 70 // function is unlikely to allocate a rare data until the first allocation anyway. 71 71 , m_allocationProfileWatchpointSet(ClearWatchpoint) 72 , m_hasReifiedName(function->isAnonymousBuiltinFunction()) 72 73 { 73 74 } -
trunk/Source/JavaScriptCore/runtime/FunctionRareData.h
r249509 r249650 51 51 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 52 52 53 static FunctionRareData* create(VM& );53 static FunctionRareData* create(VM&, JSFunction*); 54 54 55 55 static const bool needsDestruction = true; … … 120 120 121 121 protected: 122 FunctionRareData(VM& );122 FunctionRareData(VM&, JSFunction*); 123 123 ~FunctionRareData(); 124 124 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r249175 r249650 126 126 ASSERT(jsDynamicCast<JSFunction*>(vm, this)); 127 127 ASSERT(type() == JSFunctionType); 128 if (isAnonymousBuiltinFunction()) {129 // This is anonymous builtin function.130 rareData(vm)->setHasReifiedName();131 }132 128 } 133 129 … … 147 143 { 148 144 ASSERT(!m_rareData); 149 FunctionRareData* rareData = FunctionRareData::create(vm );145 FunctionRareData* rareData = FunctionRareData::create(vm, this); 150 146 151 147 // A DFG compilation thread may be trying to read the rare data … … 187 183 VM& vm = exec->vm(); 188 184 JSObject* prototype = prototypeForConstruction(vm, exec); 189 FunctionRareData* rareData = FunctionRareData::create(vm );185 FunctionRareData* rareData = FunctionRareData::create(vm, this); 190 186 rareData->initializeObjectAllocationProfile(vm, globalObject(vm), prototype, inlineCapacity, this); 191 187 -
trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h
r246553 r249650 111 111 inline bool JSFunction::hasReifiedName() const 112 112 { 113 return m_rareData ? m_rareData->hasReifiedName() : false; 113 if (m_rareData) 114 return m_rareData->hasReifiedName(); 115 if (isAnonymousBuiltinFunction()) 116 return true; 117 return false; 114 118 } 115 119
Note: See TracChangeset
for help on using the changeset viewer.