Changeset 255542 in webkit
- Timestamp:
- Jan 31, 2020, 10:18:18 PM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 19 edited
-
ChangeLog (modified) (1 diff)
-
bytecode/AccessCase.cpp (modified) (8 diffs)
-
bytecode/AccessCase.h (modified) (2 diffs)
-
bytecode/CodeBlock.cpp (modified) (3 diffs)
-
bytecode/GetByStatus.cpp (modified) (1 diff)
-
bytecode/InByIdStatus.cpp (modified) (4 diffs)
-
bytecode/InByIdStatus.h (modified) (1 diff)
-
bytecode/InstanceOfStatus.cpp (modified) (2 diffs)
-
bytecode/InstanceOfStatus.h (modified) (1 diff)
-
bytecode/PolyProtoAccessChain.cpp (modified) (3 diffs)
-
bytecode/PolyProtoAccessChain.h (modified) (4 diffs)
-
bytecode/PolymorphicAccess.cpp (modified) (1 diff)
-
bytecode/PutByIdStatus.cpp (modified) (1 diff)
-
bytecode/StructureStubInfo.cpp (modified) (3 diffs)
-
bytecode/StructureStubInfo.h (modified) (1 diff)
-
dfg/DFGCommonData.h (modified) (1 diff)
-
dfg/DFGDesiredWeakReferences.cpp (modified) (1 diff)
-
dfg/DFGPlan.cpp (modified) (1 diff)
-
jit/Repatch.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r255541 r255542 1 2020-01-31 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Hold StructureID instead of Structure* in PolyProtoAccessChain and DFG::CommonData 4 https://bugs.webkit.org/show_bug.cgi?id=207086 5 6 Reviewed by Mark Lam. 7 8 PolyProtoAccessChain and DFG::CommonData are kept alive so long as associated AccessCase / DFG/FTL CodeBlock 9 is alive. They hold Vector<Structure*> / Vector<WriteBarrier<Structure*>>, but access frequency is low. And 10 We should hold Vector<StructureID> instead to cut 50% of the size. 11 12 * bytecode/AccessCase.cpp: 13 (JSC::AccessCase::commit): 14 (JSC::AccessCase::forEachDependentCell const): 15 (JSC::AccessCase::doesCalls const): 16 (JSC::AccessCase::visitWeak const): 17 (JSC::AccessCase::propagateTransitions const): 18 (JSC::AccessCase::generateWithGuard): 19 * bytecode/AccessCase.h: 20 * bytecode/CodeBlock.cpp: 21 (JSC::CodeBlock::propagateTransitions): 22 (JSC::CodeBlock::determineLiveness): 23 (JSC::CodeBlock::stronglyVisitWeakReferences): 24 * bytecode/GetByStatus.cpp: 25 (JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback): 26 * bytecode/InByIdStatus.cpp: 27 (JSC::InByIdStatus::computeFor): 28 (JSC::InByIdStatus::computeForStubInfo): 29 (JSC::InByIdStatus::computeForStubInfoWithoutExitSiteFeedback): 30 * bytecode/InByIdStatus.h: 31 * bytecode/InstanceOfStatus.cpp: 32 (JSC::InstanceOfStatus::computeFor): 33 (JSC::InstanceOfStatus::computeForStubInfo): 34 * bytecode/InstanceOfStatus.h: 35 * bytecode/PolyProtoAccessChain.cpp: 36 (JSC::PolyProtoAccessChain::create): 37 (JSC::PolyProtoAccessChain::needImpurePropertyWatchpoint const): 38 (JSC::PolyProtoAccessChain::dump const): 39 * bytecode/PolyProtoAccessChain.h: 40 (JSC::PolyProtoAccessChain::chain const): 41 (JSC::PolyProtoAccessChain::forEach const): 42 (JSC::PolyProtoAccessChain::slotBaseStructure const): 43 (JSC::PolyProtoAccessChain:: const): Deleted. 44 * bytecode/PolymorphicAccess.cpp: 45 (JSC::PolymorphicAccess::regenerate): 46 * bytecode/PutByIdStatus.cpp: 47 (JSC::PutByIdStatus::computeForStubInfo): 48 * bytecode/StructureStubInfo.cpp: 49 (JSC::StructureStubInfo::summary const): 50 (JSC::StructureStubInfo::summary): 51 * bytecode/StructureStubInfo.h: 52 * dfg/DFGCommonData.h: 53 * dfg/DFGDesiredWeakReferences.cpp: 54 (JSC::DFG::DesiredWeakReferences::reallyAdd): 55 * dfg/DFGPlan.cpp: 56 (JSC::DFG::Plan::finalizeWithoutNotifyingCallback): 57 * jit/Repatch.cpp: 58 (JSC::tryCacheGetBy): 59 (JSC::tryCachePutByID): 60 (JSC::tryCacheInByID): 61 1 62 2020-01-31 Yusuke Suzuki <ysuzuki@apple.com> 2 63 -
trunk/Source/JavaScriptCore/bytecode/AccessCase.cpp
r254735 r255542 191 191 if ((structure && structure->needImpurePropertyWatchpoint()) 192 192 || m_conditionSet.needImpurePropertyWatchpoint() 193 || (m_polyProtoAccessChain && m_polyProtoAccessChain->needImpurePropertyWatchpoint( )))193 || (m_polyProtoAccessChain && m_polyProtoAccessChain->needImpurePropertyWatchpoint(vm))) 194 194 result.append(vm.ensureWatchpointSetForImpureProperty(m_identifier.uid())); 195 195 } … … 400 400 401 401 template<typename Functor> 402 void AccessCase::forEachDependentCell( const Functor& functor) const402 void AccessCase::forEachDependentCell(VM& vm, const Functor& functor) const 403 403 { 404 404 m_conditionSet.forEachDependentCell(functor); … … 406 406 functor(m_structure.get()); 407 407 if (m_polyProtoAccessChain) { 408 for (Structure * structure: m_polyProtoAccessChain->chain())409 functor( structure);408 for (StructureID structureID : m_polyProtoAccessChain->chain()) 409 functor(vm.getStructure(structureID)); 410 410 } 411 411 … … 478 478 } 479 479 480 bool AccessCase::doesCalls(V ector<JSCell*>* cellsToMarkIfDoesCalls) const480 bool AccessCase::doesCalls(VM& vm, Vector<JSCell*>* cellsToMarkIfDoesCalls) const 481 481 { 482 482 bool doesCalls = false; … … 529 529 530 530 if (doesCalls && cellsToMarkIfDoesCalls) { 531 forEachDependentCell( [&](JSCell* cell) {531 forEachDependentCell(vm, [&](JSCell* cell) { 532 532 cellsToMarkIfDoesCalls->append(cell); 533 533 }); … … 686 686 687 687 bool isValid = true; 688 forEachDependentCell( [&](JSCell* cell) {688 forEachDependentCell(vm, [&](JSCell* cell) { 689 689 isValid &= vm.heap.isMarked(cell); 690 690 }); … … 700 700 701 701 if (m_polyProtoAccessChain) { 702 for (Structure * structure: m_polyProtoAccessChain->chain())703 result &= structure->markIfCheap(visitor);702 for (StructureID structureID : m_polyProtoAccessChain->chain()) 703 result &= visitor.vm().getStructure(structureID)->markIfCheap(visitor); 704 704 } 705 705 … … 756 756 GPRReg baseForAccessGPR = state.scratchGPR; 757 757 jit.move(state.baseGPR, baseForAccessGPR); 758 m_polyProtoAccessChain->forEach( structure(), [&] (Structure* structure, bool atEnd) {758 m_polyProtoAccessChain->forEach(vm, structure(), [&] (Structure* structure, bool atEnd) { 759 759 fallThrough.append( 760 760 jit.branchStructure( -
trunk/Source/JavaScriptCore/bytecode/AccessCase.h
r254464 r255542 180 180 // If you supply the optional vector, this will append the set of cells that this will need to keep alive 181 181 // past the call. 182 bool doesCalls(V ector<JSCell*>* cellsToMark = nullptr) const;182 bool doesCalls(VM&, Vector<JSCell*>* cellsToMark = nullptr) const; 183 183 184 184 bool isCustom() const … … 269 269 270 270 template<typename Functor> 271 void forEachDependentCell( const Functor&) const;271 void forEachDependentCell(VM&, const Functor&) const; 272 272 273 273 void visitAggregate(SlotVisitor&) const; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r255541 r255542 1134 1134 dfgCommon->recordedStatuses.markIfCheap(visitor); 1135 1135 1136 for ( auto& weakReference: dfgCommon->weakStructureReferences)1137 weakReference->markIfCheap(visitor);1136 for (StructureID structureID : dfgCommon->weakStructureReferences) 1137 vm.getStructure(structureID)->markIfCheap(visitor); 1138 1138 1139 1139 for (auto& transition : dfgCommon->transitions) { … … 1194 1194 } 1195 1195 if (allAreLiveSoFar) { 1196 for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) { 1197 if (!vm.heap.isMarked(dfgCommon->weakStructureReferences[i].get())) { 1196 for (StructureID structureID : dfgCommon->weakStructureReferences) { 1197 Structure* structure = vm.getStructure(structureID); 1198 if (!vm.heap.isMarked(structure)) { 1198 1199 allAreLiveSoFar = false; 1199 1200 break; … … 1721 1722 visitor.append(weakReference); 1722 1723 1723 for ( auto& weakStructureReference: dfgCommon->weakStructureReferences)1724 visitor.append (weakStructureReference);1724 for (StructureID structureID : dfgCommon->weakStructureReferences) 1725 visitor.appendUnbarriered(visitor.vm().getStructure(structureID)); 1725 1726 1726 1727 dfgCommon->livenessHasBeenProved = true; -
trunk/Source/JavaScriptCore/bytecode/GetByStatus.cpp
r254464 r255542 169 169 const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CallLinkStatus::ExitSiteData callExitSiteData) 170 170 { 171 StubInfoSummary summary = StructureStubInfo::summary( stubInfo);171 StubInfoSummary summary = StructureStubInfo::summary(profiledBlock->vm(), stubInfo); 172 172 if (!isInlineable(summary)) 173 173 return GetByStatus(summary, *stubInfo); -
trunk/Source/JavaScriptCore/bytecode/InByIdStatus.cpp
r252684 r255542 51 51 52 52 #if ENABLE(DFG_JIT) 53 result = computeForStubInfoWithoutExitSiteFeedback(locker, map.get(CodeOrigin(bytecodeIndex)).stubInfo, uid);53 result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), map.get(CodeOrigin(bytecodeIndex)).stubInfo, uid); 54 54 55 55 if (!result.takesSlowPath() && didExit) … … 97 97 { 98 98 ConcurrentJSLocker locker(context->optimizedCodeBlock->m_lock); 99 result = computeForStubInfoWithoutExitSiteFeedback(locker, status.stubInfo, uid);99 result = computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), status.stubInfo, uid); 100 100 } 101 101 if (result.isSet()) … … 115 115 InByIdStatus InByIdStatus::computeForStubInfo(const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, CodeOrigin codeOrigin, UniquedStringImpl* uid) 116 116 { 117 InByIdStatus result = InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(locker, stubInfo, uid);117 InByIdStatus result = InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(locker, profiledBlock->vm(), stubInfo, uid); 118 118 119 119 if (!result.takesSlowPath() && hasBadCacheExitSite(profiledBlock, codeOrigin.bytecodeIndex())) … … 122 122 } 123 123 124 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, StructureStubInfo* stubInfo, UniquedStringImpl* uid)125 { 126 StubInfoSummary summary = StructureStubInfo::summary( stubInfo);124 InByIdStatus InByIdStatus::computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo, UniquedStringImpl* uid) 125 { 126 StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo); 127 127 if (!isInlineable(summary)) 128 128 return InByIdStatus(summary); -
trunk/Source/JavaScriptCore/bytecode/InByIdStatus.h
r253969 r255542 114 114 private: 115 115 #if ENABLE(DFG_JIT) 116 static InByIdStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, StructureStubInfo*, UniquedStringImpl* uid);116 static InByIdStatus computeForStubInfoWithoutExitSiteFeedback(const ConcurrentJSLocker&, VM&, StructureStubInfo*, UniquedStringImpl* uid); 117 117 #endif 118 118 bool appendVariant(const InByIdVariant&); -
trunk/Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp
r252684 r255542 47 47 InstanceOfStatus result; 48 48 #if ENABLE(DFG_JIT) 49 result = computeForStubInfo(locker, infoMap.get(CodeOrigin(bytecodeIndex)).stubInfo);49 result = computeForStubInfo(locker, codeBlock->vm(), infoMap.get(CodeOrigin(bytecodeIndex)).stubInfo); 50 50 51 51 if (!result.takesSlowPath()) { … … 67 67 68 68 #if ENABLE(DFG_JIT) 69 InstanceOfStatus InstanceOfStatus::computeForStubInfo(const ConcurrentJSLocker&, StructureStubInfo* stubInfo)69 InstanceOfStatus InstanceOfStatus::computeForStubInfo(const ConcurrentJSLocker&, VM& vm, StructureStubInfo* stubInfo) 70 70 { 71 71 // FIXME: We wouldn't have to bail for nonCell if we taught MatchStructure how to handle non 72 72 // cells. If we fixed that then we wouldn't be able to use summary(); 73 73 // https://bugs.webkit.org/show_bug.cgi?id=185784 74 StubInfoSummary summary = StructureStubInfo::summary( stubInfo);74 StubInfoSummary summary = StructureStubInfo::summary(vm, stubInfo); 75 75 if (!isInlineable(summary)) 76 76 return InstanceOfStatus(summary); -
trunk/Source/JavaScriptCore/bytecode/InstanceOfStatus.h
r253969 r255542 83 83 84 84 #if ENABLE(DFG_JIT) 85 static InstanceOfStatus computeForStubInfo(const ConcurrentJSLocker&, StructureStubInfo*);85 static InstanceOfStatus computeForStubInfo(const ConcurrentJSLocker&, VM&, StructureStubInfo*); 86 86 #endif 87 87 -
trunk/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.cpp
r255541 r255542 62 62 // AccessCase provide the base to us as needed. 63 63 if (iterationNumber) 64 result->m_chain.append(structure );64 result->m_chain.append(structure->id()); 65 65 else 66 66 RELEASE_ASSERT(current == base); … … 84 84 } 85 85 86 bool PolyProtoAccessChain::needImpurePropertyWatchpoint( ) const86 bool PolyProtoAccessChain::needImpurePropertyWatchpoint(VM& vm) const 87 87 { 88 for (Structure * structure: m_chain) {89 if ( structure->needImpurePropertyWatchpoint())88 for (StructureID structureID : m_chain) { 89 if (vm.getStructure(structureID)->needImpurePropertyWatchpoint()) 90 90 return true; 91 91 } … … 101 101 { 102 102 out.print("PolyPolyProtoAccessChain: [\n"); 103 forEach(baseStructure , [&] (Structure* structure, bool) {103 forEach(baseStructure->vm(), baseStructure, [&] (Structure* structure, bool) { 104 104 out.print("\t"); 105 105 structure->dump(out); -
trunk/Source/JavaScriptCore/bytecode/PolyProtoAccessChain.h
r251085 r255542 51 51 } 52 52 53 const Vector<Structure *>& chain() const { return m_chain; }53 const Vector<StructureID>& chain() const { return m_chain; } 54 54 55 55 void dump(Structure* baseStructure, PrintStream& out) const; … … 61 61 } 62 62 63 bool needImpurePropertyWatchpoint( ) const;63 bool needImpurePropertyWatchpoint(VM&) const; 64 64 65 65 template <typename Func> 66 void forEach( Structure* baseStructure, const Func& func) const66 void forEach(VM& vm, Structure* baseStructure, const Func& func) const 67 67 { 68 68 bool atEnd = !m_chain.size(); … … 70 70 for (unsigned i = 0; i < m_chain.size(); ++i) { 71 71 atEnd = i + 1 == m_chain.size(); 72 func( m_chain[i], atEnd);72 func(vm.getStructure(m_chain[i]), atEnd); 73 73 } 74 74 } 75 75 76 Structure* slotBaseStructure( Structure* baseStructure) const76 Structure* slotBaseStructure(VM& vm, Structure* baseStructure) const 77 77 { 78 78 if (m_chain.size()) 79 return m_chain.last();79 return vm.getStructure(m_chain.last()); 80 80 return baseStructure; 81 81 } … … 86 86 // This does not include the base. We rely on AccessCase providing it for us. That said, this data 87 87 // structure is tied to the base that it was created with. 88 Vector<Structure *> m_chain;88 Vector<StructureID> m_chain; 89 89 }; 90 90 -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r255541 r255542 726 726 Vector<JSCell*> cellsToMark; 727 727 for (auto& entry : cases) 728 doesCalls |= entry->doesCalls( &cellsToMark);728 doesCalls |= entry->doesCalls(vm, &cellsToMark); 729 729 730 730 m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls, cellsToMark, WTFMove(state.m_callLinkInfos), codeBlockThatOwnsExceptionHandlers, callSiteIndexForExceptionHandling); -
trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp
r252684 r255542 130 130 UniquedStringImpl* uid, CallLinkStatus::ExitSiteData callExitSiteData) 131 131 { 132 StubInfoSummary summary = StructureStubInfo::summary( stubInfo);132 StubInfoSummary summary = StructureStubInfo::summary(profiledBlock->vm(), stubInfo); 133 133 if (!isInlineable(summary)) 134 134 return PutByIdStatus(summary); -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
r254464 r255542 352 352 } 353 353 354 StubInfoSummary StructureStubInfo::summary( ) const354 StubInfoSummary StructureStubInfo::summary(VM& vm) const 355 355 { 356 356 StubInfoSummary takesSlowPath = StubInfoSummary::TakesSlowPath; … … 360 360 for (unsigned i = 0; i < list->size(); ++i) { 361 361 const AccessCase& access = list->at(i); 362 if (access.doesCalls( )) {362 if (access.doesCalls(vm)) { 363 363 takesSlowPath = StubInfoSummary::TakesSlowPathAndMakesCalls; 364 364 simple = StubInfoSummary::MakesCalls; … … 377 377 } 378 378 379 StubInfoSummary StructureStubInfo::summary( const StructureStubInfo* stubInfo)379 StubInfoSummary StructureStubInfo::summary(VM& vm, const StructureStubInfo* stubInfo) 380 380 { 381 381 if (!stubInfo) 382 382 return StubInfoSummary::NoInformation; 383 383 384 return stubInfo->summary( );384 return stubInfo->summary(vm); 385 385 } 386 386 -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r254464 r255542 167 167 } 168 168 169 StubInfoSummary summary( ) const;169 StubInfoSummary summary(VM&) const; 170 170 171 static StubInfoSummary summary( const StructureStubInfo*);171 static StubInfoSummary summary(VM&, const StructureStubInfo*); 172 172 173 173 bool containsPC(void* pc) const; -
trunk/Source/JavaScriptCore/dfg/DFGCommonData.h
r251468 r255542 126 126 Vector<WeakReferenceTransition> transitions; 127 127 Vector<WriteBarrier<JSCell>> weakReferences; 128 Vector< WriteBarrier<Structure>> weakStructureReferences;128 Vector<StructureID> weakStructureReferences; 129 129 Vector<CatchEntrypointData> catchEntrypoints; 130 130 Bag<CodeBlockJettisoningWatchpoint> watchpoints; -
trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp
r251321 r255542 68 68 void DesiredWeakReferences::reallyAdd(VM& vm, CommonData* common) 69 69 { 70 ASSERT(vm.heap.isDeferred()); 70 71 for (JSCell* target : m_references) { 71 72 if (Structure* structure = jsDynamicCast<Structure*>(vm, target)) { 72 73 ConcurrentJSLocker locker(m_codeBlock->m_lock); 73 common->weakStructureReferences.append(74 WriteBarrier<Structure>(vm, m_codeBlock, structure));74 // We do not emit WriteBarrier here since (1) GC is deferred and (2) we emit write-barrier on CodeBlock when finishing DFG::Plan::reallyAdd. 75 common->weakStructureReferences.append(structure->id()); 75 76 } else { 76 77 // There are weird relationships in how optimized CodeBlocks -
trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp
r255540 r255542 625 625 for (WriteBarrier<JSCell>& reference : m_codeBlock->jitCode()->dfgCommon()->weakReferences) 626 626 trackedReferences.add(reference.get()); 627 for ( WriteBarrier<Structure>& reference: m_codeBlock->jitCode()->dfgCommon()->weakStructureReferences)628 trackedReferences.add( reference.get());627 for (StructureID structureID : m_codeBlock->jitCode()->dfgCommon()->weakStructureReferences) 628 trackedReferences.add(m_vm->getStructure(structureID)); 629 629 for (WriteBarrier<Unknown>& constant : m_codeBlock->constants()) 630 630 trackedReferences.add(constant.get()); -
trunk/Source/JavaScriptCore/jit/Repatch.cpp
r255365 r255542 321 321 if (!prototypeAccessChain) 322 322 return GiveUpOnCache; 323 RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure( structure)->get(vm, propertyName.uid()) == offset);323 RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure(vm, structure)->get(vm, propertyName.uid()) == offset); 324 324 } else { 325 325 // We use ObjectPropertyConditionSet instead for faster accesses. … … 689 689 if (!prototypeAccessChain) 690 690 return GiveUpOnCache; 691 offset = prototypeAccessChain->slotBaseStructure( baseCell->structure(vm))->get(vm, ident.impl());691 offset = prototypeAccessChain->slotBaseStructure(vm, baseCell->structure(vm))->get(vm, ident.impl()); 692 692 } else { 693 693 prototypeAccessChain = nullptr; … … 791 791 if (!prototypeAccessChain) 792 792 return GiveUpOnCache; 793 RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure( structure)->get(vm, ident.impl()) == slot.cachedOffset());793 RELEASE_ASSERT(slot.isCacheableCustom() || prototypeAccessChain->slotBaseStructure(vm, structure)->get(vm, ident.impl()) == slot.cachedOffset()); 794 794 } else { 795 795 prototypeAccessChain = nullptr;
Note:
See TracChangeset
for help on using the changeset viewer.