Changeset 282565 in webkit for trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
- Timestamp:
- Sep 16, 2021, 11:14:24 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r282478 r282565 375 375 JSScope* scope) 376 376 { 377 // We can't finalize a GC while in here since we need to make sure to378 // make sure our ValueProfiles and ArrayProfiles all point to proper locations.379 RELEASE_ASSERT(vm.heap.isDeferred());380 381 377 Base::finishCreation(vm); 382 378 finishCreationCommon(vm); … … 388 384 389 385 ScriptExecutable* topLevelExecutable = ownerExecutable->topLevelExecutable(); 390 391 // We wait to initialize template objects until the end of finishCreation beecause it can 392 // throw. We rely on linking to put the CodeBlock into a coherent state, so we can't throw 393 // until we're all done linking. 394 Vector<unsigned> templateObjectIndices = setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation()); 386 setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation(), topLevelExecutable); 387 RETURN_IF_EXCEPTION(throwScope, false); 395 388 396 389 // We already have the cloned symbol table for the module environment since we need to instantiate … … 443 436 HashSet<JSModuleEnvironment*> stronglyReferencedModuleEnvironments; 444 437 445 auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& metadata) { 446 static_assert(std::is_same_v<ValueProfile*, decltype(metadata.m_profile)>); 438 auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& /*metadata*/) { 447 439 m_numberOfNonArgumentValueProfiles++; 448 440 }; … … 508 500 LINK(OpGetById, profile) 509 501 510 LINK(OpEnumeratorNext )511 LINK(OpEnumeratorInByVal )512 LINK(OpEnumeratorHasOwnProperty )502 LINK(OpEnumeratorNext, profile) 503 LINK(OpEnumeratorInByVal, profile) 504 LINK(OpEnumeratorHasOwnProperty, profile) 513 505 LINK(OpEnumeratorGetByVal, profile) 514 506 … … 572 564 573 565 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization); 566 RETURN_IF_EXCEPTION(throwScope, false); 574 567 575 568 metadata.m_resolveType = op.type; … … 606 599 const Identifier& ident = identifier(bytecode.m_var); 607 600 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_localScopeDepth, scope, ident, Get, bytecode.m_getPutInfo.resolveType(), InitializationMode::NotInitialization); 601 RETURN_IF_EXCEPTION(throwScope, false); 608 602 609 603 metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode()); … … 639 633 metadata.m_watchpointSet = nullptr; 640 634 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_symbolTableOrScopeDepth.scopeDepth(), scope, ident, Put, bytecode.m_getPutInfo.resolveType(), bytecode.m_getPutInfo.initializationMode()); 635 RETURN_IF_EXCEPTION(throwScope, false); 641 636 642 637 metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode()); … … 671 666 // we're abstractly "read"ing from a JSScope. 672 667 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization); 668 RETURN_IF_EXCEPTION(throwScope, false); 673 669 674 670 if (op.type == ClosureVar || op.type == ModuleVar) … … 766 762 #undef LINK 767 763 768 {769 unsigned index = numberOfArgumentValueProfiles(); // The first numberOfArgumentValueProfiles() profiles are argument value profiles770 771 if (m_metadata) {772 auto assign = [&] (ValueProfile*& profile) {773 profile = &unlinkedCodeBlock->valueProfile(index++);774 };775 776 #define VISIT(__op) \777 m_metadata->forEach<__op>([&] (auto& metadata) { assign(metadata.m_profile); });778 FOR_EACH_OPCODE_WITH_VALUE_PROFILE(VISIT)779 #undef VISIT780 781 m_metadata->forEach<OpIteratorOpen>([&] (auto& metadata) {782 assign(metadata.m_iterableProfile);783 assign(metadata.m_iteratorProfile);784 assign(metadata.m_nextProfile);785 });786 787 m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {788 assign(metadata.m_nextResultProfile);789 assign(metadata.m_doneProfile);790 assign(metadata.m_valueProfile);791 });792 }793 794 RELEASE_ASSERT(index == unlinkedCodeBlock->numValueProfiles());795 }796 797 if (m_metadata) {798 unsigned index = 0;799 800 auto assign = [&] (ArrayProfile*& profile) {801 profile = &unlinkedCodeBlock->arrayProfile(index++);802 };803 804 // We only share array profiles for the opcodes in FOR_EACH_OPCODE_WITH_ARRAY_PROFILE.805 // We don't yet share array profiles for things with LLInt CallLinkInfos.806 #define VISIT(__op) \807 m_metadata->forEach<__op>([&] (auto& metadata) { assign(metadata.m_arrayProfile); });808 FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(VISIT)809 #undef VISIT810 811 m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {812 assign(metadata.m_iterableProfile);813 });814 815 RELEASE_ASSERT(index == unlinkedCodeBlock->numArrayProfiles());816 }817 818 764 if (m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes()) 819 765 insertBasicBlockBoundariesForControlFlowProfiler(); … … 835 781 if (m_metadata) 836 782 vm.heap.reportExtraMemoryAllocated(m_metadata->sizeInBytes()); 837 838 initializeTemplateObjects(topLevelExecutable, templateObjectIndices);839 RETURN_IF_EXCEPTION(throwScope, false);840 783 841 784 return true; … … 927 870 } 928 871 929 Vector<unsigned> CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)872 void CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable) 930 873 { 931 874 VM& vm = *m_vm; 875 auto scope = DECLARE_THROW_SCOPE(vm); 932 876 JSGlobalObject* globalObject = m_globalObject.get(); 933 877 934 Vector<unsigned> templateObjectIndices;935 936 878 ASSERT(constants.size() == constantsSourceCodeRepresentation.size()); 937 unsignedcount = constants.size();879 size_t count = constants.size(); 938 880 { 939 881 ConcurrentJSLocker locker(m_lock); 940 882 m_constantRegisters.resizeToFit(count); 941 883 } 942 for ( unsignedi = 0; i < count; i++) {884 for (size_t i = 0; i < count; i++) { 943 885 JSValue constant = constants[i].get(); 944 886 SourceCodeRepresentation representation = constantsSourceCodeRepresentation[i]; … … 964 906 965 907 constant = clone; 966 } else if (jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) 967 templateObjectIndices.append(i); 908 } else if (auto* descriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) { 909 auto* templateObject = topLevelExecutable->createTemplateObject(globalObject, descriptor); 910 RETURN_IF_EXCEPTION(scope, void()); 911 constant = templateObject; 912 } 968 913 } 969 914 } … … 972 917 m_constantRegisters[i].set(vm, this, constant); 973 918 } 974 975 return templateObjectIndices;976 }977 978 void CodeBlock::initializeTemplateObjects(ScriptExecutable* topLevelExecutable, const Vector<unsigned>& templateObjectIndices)979 {980 auto scope = DECLARE_THROW_SCOPE(vm());981 for (unsigned i : templateObjectIndices) {982 auto* descriptor = jsCast<JSTemplateObjectDescriptor*>(m_constantRegisters[i].get());983 auto* templateObject = topLevelExecutable->createTemplateObject(globalObject(), descriptor);984 RETURN_IF_EXCEPTION(scope, void());985 m_constantRegisters[i].set(vm(), this, templateObject);986 }987 919 } 988 920 … … 997 929 { 998 930 m_numParameters = newValue; 931 932 m_argumentValueProfiles = FixedVector<ValueProfile>(Options::useJIT() ? newValue : 0); 999 933 } 1000 934 … … 1057 991 stronglyVisitWeakReferences(locker, visitor); 1058 992 1059 vm().codeBlockSpace.set.add(this);993 VM::SpaceAndSet::setFor(*subspace()).add(this); 1060 994 } 1061 995 … … 1584 1518 UNUSED_PARAM(vm); 1585 1519 1586 { 1587 // We only update the profiles that the UnlinkedCodeBlock doesn't own. 1588 1589 if (m_metadata) { 1590 #define UPDATE(__op) \ 1591 m_metadata->forEach<__op>([&] (auto& metadata) { metadata.m_callLinkInfo.m_arrayProfile.computeUpdatedPrediction(this); }); 1592 FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(UPDATE) 1593 #undef UPDATE 1594 1595 m_metadata->forEach<OpCatch>([&](auto& metadata) { 1596 if (metadata.m_buffer) { 1597 metadata.m_buffer->forEach([&](ValueProfileAndVirtualRegister& profile) { 1598 profile.computeUpdatedPrediction(); 1599 }); 1600 } 1601 }); 1602 } 1603 1604 { 1605 ConcurrentJSLocker locker(m_lock); 1606 #if ENABLE(DFG_JIT) 1607 lazyOperandValueProfiles(locker).computeUpdatedPredictions(locker); 1608 #endif 1609 } 1610 1611 forEachArrayAllocationProfile([&](ArrayAllocationProfile& profile) { 1612 profile.updateProfile(); 1613 }); 1614 } 1520 updateAllPredictions(); 1615 1521 1616 1522 #if ENABLE(JIT) … … 1698 1604 updateActivity(); 1699 1605 1700 vm.codeBlockSpace.set.remove(this);1606 VM::SpaceAndSet::setFor(*subspace()).remove(this); 1701 1607 1702 1608 // In CodeBlock::shouldVisitStrongly() we may have decided to skip visiting this … … 2868 2774 #define CASE1(Op) \ 2869 2775 case Op::opcodeID: \ 2870 return instruction->as<Op>().metadata(this).m_arrayProfile;2776 return &instruction->as<Op>().metadata(this).m_arrayProfile; 2871 2777 2872 2778 #define CASE2(Op) \ … … 2880 2786 #undef CASE2 2881 2787 2788 case OpGetById::opcodeID: { 2789 auto bytecode = instruction->as<OpGetById>(); 2790 auto& metadata = bytecode.metadata(this); 2791 if (metadata.m_modeMetadata.mode == GetByIdMode::ArrayLength) 2792 return &metadata.m_modeMetadata.arrayLengthMode.arrayProfile; 2793 break; 2794 } 2882 2795 default: 2883 2796 break; … … 2988 2901 numberOfSamplesInProfiles += numSamples; 2989 2902 if (isArgument) { 2990 profile.computeUpdatedPrediction( );2903 profile.computeUpdatedPrediction(locker); 2991 2904 return; 2992 2905 } 2993 2906 if (profile.numberOfSamples() || profile.isSampledBefore()) 2994 2907 numberOfLiveNonArgumentValueProfiles++; 2995 profile.computeUpdatedPrediction( );2908 profile.computeUpdatedPrediction(locker); 2996 2909 }); 2997 2910 … … 3000 2913 if (metadata.m_buffer) { 3001 2914 metadata.m_buffer->forEach([&](ValueProfileAndVirtualRegister& profile) { 3002 profile.computeUpdatedPrediction( );2915 profile.computeUpdatedPrediction(locker); 3003 2916 }); 3004 2917 } … … 3019 2932 void CodeBlock::updateAllArrayPredictions() 3020 2933 { 2934 ConcurrentJSLocker locker(m_lock); 2935 3021 2936 forEachArrayProfile([&](ArrayProfile& profile) { 3022 profile.computeUpdatedPrediction( this);2937 profile.computeUpdatedPrediction(locker, this); 3023 2938 }); 3024 2939 … … 3250 3165 #define CASE(Op) \ 3251 3166 case Op::opcodeID: \ 3252 return instruction->as<Op>().metadata(this).m_profile;3167 return &instruction->as<Op>().metadata(this).m_profile; 3253 3168 3254 3169 FOR_EACH_OPCODE_WITH_VALUE_PROFILE(CASE) … … 3267 3182 } 3268 3183 3269 SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex( BytecodeIndex bytecodeIndex)3184 SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex(const ConcurrentJSLocker& locker, BytecodeIndex bytecodeIndex) 3270 3185 { 3271 3186 if (ValueProfile* valueProfile = tryGetValueProfileForBytecodeIndex(bytecodeIndex)) 3272 return valueProfile->computeUpdatedPrediction( );3187 return valueProfile->computeUpdatedPrediction(locker); 3273 3188 return SpecNone; 3274 3189 }
Note:
See TracChangeset
for help on using the changeset viewer.