Changeset 282478 in webkit for trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
- Timestamp:
- Sep 15, 2021, 3:18:52 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r281684 r282478 375 375 JSScope* scope) 376 376 { 377 // We can't finalize a GC while in here since we need to make sure to 378 // make sure our ValueProfiles and ArrayProfiles all point to proper locations. 379 RELEASE_ASSERT(vm.heap.isDeferred()); 380 377 381 Base::finishCreation(vm); 378 382 finishCreationCommon(vm); … … 384 388 385 389 ScriptExecutable* topLevelExecutable = ownerExecutable->topLevelExecutable(); 386 setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation(), topLevelExecutable); 387 RETURN_IF_EXCEPTION(throwScope, false); 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()); 388 395 389 396 // We already have the cloned symbol table for the module environment since we need to instantiate … … 436 443 HashSet<JSModuleEnvironment*> stronglyReferencedModuleEnvironments; 437 444 438 auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& /*metadata*/) { 445 auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& metadata) { 446 static_assert(std::is_same_v<ValueProfile*, decltype(metadata.m_profile)>); 439 447 m_numberOfNonArgumentValueProfiles++; 440 448 }; … … 500 508 LINK(OpGetById, profile) 501 509 502 LINK(OpEnumeratorNext , profile)503 LINK(OpEnumeratorInByVal , profile)504 LINK(OpEnumeratorHasOwnProperty , profile)510 LINK(OpEnumeratorNext) 511 LINK(OpEnumeratorInByVal) 512 LINK(OpEnumeratorHasOwnProperty) 505 513 LINK(OpEnumeratorGetByVal, profile) 506 514 … … 564 572 565 573 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization); 566 RETURN_IF_EXCEPTION(throwScope, false);567 574 568 575 metadata.m_resolveType = op.type; … … 599 606 const Identifier& ident = identifier(bytecode.m_var); 600 607 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);602 608 603 609 metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode()); … … 633 639 metadata.m_watchpointSet = nullptr; 634 640 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);636 641 637 642 metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode()); … … 666 671 // we're abstractly "read"ing from a JSScope. 667 672 ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization); 668 RETURN_IF_EXCEPTION(throwScope, false);669 673 670 674 if (op.type == ClosureVar || op.type == ModuleVar) … … 762 766 #undef LINK 763 767 768 { 769 unsigned index = numberOfArgumentValueProfiles(); // The first numberOfArgumentValueProfiles() profiles are argument value profiles 770 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 VISIT 780 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 VISIT 810 811 m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) { 812 assign(metadata.m_iterableProfile); 813 }); 814 815 RELEASE_ASSERT(index == unlinkedCodeBlock->numArrayProfiles()); 816 } 817 764 818 if (m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes()) 765 819 insertBasicBlockBoundariesForControlFlowProfiler(); … … 781 835 if (m_metadata) 782 836 vm.heap.reportExtraMemoryAllocated(m_metadata->sizeInBytes()); 837 838 initializeTemplateObjects(topLevelExecutable, templateObjectIndices); 839 RETURN_IF_EXCEPTION(throwScope, false); 783 840 784 841 return true; … … 870 927 } 871 928 872 void CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)929 Vector<unsigned> CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation) 873 930 { 874 931 VM& vm = *m_vm; 875 auto scope = DECLARE_THROW_SCOPE(vm);876 932 JSGlobalObject* globalObject = m_globalObject.get(); 877 933 934 Vector<unsigned> templateObjectIndices; 935 878 936 ASSERT(constants.size() == constantsSourceCodeRepresentation.size()); 879 size_tcount = constants.size();937 unsigned count = constants.size(); 880 938 { 881 939 ConcurrentJSLocker locker(m_lock); 882 940 m_constantRegisters.resizeToFit(count); 883 941 } 884 for ( size_ti = 0; i < count; i++) {942 for (unsigned i = 0; i < count; i++) { 885 943 JSValue constant = constants[i].get(); 886 944 SourceCodeRepresentation representation = constantsSourceCodeRepresentation[i]; … … 906 964 907 965 constant = clone; 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 } 966 } else if (jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) 967 templateObjectIndices.append(i); 913 968 } 914 969 } … … 917 972 m_constantRegisters[i].set(vm, this, constant); 918 973 } 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 } 919 987 } 920 988 … … 929 997 { 930 998 m_numParameters = newValue; 931 932 m_argumentValueProfiles = FixedVector<ValueProfile>(Options::useJIT() ? newValue : 0);933 999 } 934 1000 … … 991 1057 stronglyVisitWeakReferences(locker, visitor); 992 1058 993 VM::SpaceAndSet::setFor(*subspace()).add(this);1059 vm().codeBlockSpace.set.add(this); 994 1060 } 995 1061 … … 1518 1584 UNUSED_PARAM(vm); 1519 1585 1520 updateAllPredictions(); 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 } 1521 1615 1522 1616 #if ENABLE(JIT) … … 1604 1698 updateActivity(); 1605 1699 1606 VM::SpaceAndSet::setFor(*subspace()).remove(this);1700 vm.codeBlockSpace.set.remove(this); 1607 1701 1608 1702 // In CodeBlock::shouldVisitStrongly() we may have decided to skip visiting this … … 2774 2868 #define CASE1(Op) \ 2775 2869 case Op::opcodeID: \ 2776 return &instruction->as<Op>().metadata(this).m_arrayProfile;2870 return instruction->as<Op>().metadata(this).m_arrayProfile; 2777 2871 2778 2872 #define CASE2(Op) \ … … 2786 2880 #undef CASE2 2787 2881 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 }2795 2882 default: 2796 2883 break; … … 2901 2988 numberOfSamplesInProfiles += numSamples; 2902 2989 if (isArgument) { 2903 profile.computeUpdatedPrediction( locker);2990 profile.computeUpdatedPrediction(); 2904 2991 return; 2905 2992 } 2906 2993 if (profile.numberOfSamples() || profile.isSampledBefore()) 2907 2994 numberOfLiveNonArgumentValueProfiles++; 2908 profile.computeUpdatedPrediction( locker);2995 profile.computeUpdatedPrediction(); 2909 2996 }); 2910 2997 … … 2913 3000 if (metadata.m_buffer) { 2914 3001 metadata.m_buffer->forEach([&](ValueProfileAndVirtualRegister& profile) { 2915 profile.computeUpdatedPrediction( locker);3002 profile.computeUpdatedPrediction(); 2916 3003 }); 2917 3004 } … … 2932 3019 void CodeBlock::updateAllArrayPredictions() 2933 3020 { 2934 ConcurrentJSLocker locker(m_lock);2935 2936 3021 forEachArrayProfile([&](ArrayProfile& profile) { 2937 profile.computeUpdatedPrediction( locker,this);3022 profile.computeUpdatedPrediction(this); 2938 3023 }); 2939 3024 … … 3165 3250 #define CASE(Op) \ 3166 3251 case Op::opcodeID: \ 3167 return &instruction->as<Op>().metadata(this).m_profile;3252 return instruction->as<Op>().metadata(this).m_profile; 3168 3253 3169 3254 FOR_EACH_OPCODE_WITH_VALUE_PROFILE(CASE) … … 3182 3267 } 3183 3268 3184 SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex( const ConcurrentJSLocker& locker,BytecodeIndex bytecodeIndex)3269 SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex(BytecodeIndex bytecodeIndex) 3185 3270 { 3186 3271 if (ValueProfile* valueProfile = tryGetValueProfileForBytecodeIndex(bytecodeIndex)) 3187 return valueProfile->computeUpdatedPrediction( locker);3272 return valueProfile->computeUpdatedPrediction(); 3188 3273 return SpecNone; 3189 3274 }
Note:
See TracChangeset
for help on using the changeset viewer.