Title: [282917] branches/safari-612-branch/Source/_javascript_Core
Revision
282917
Author
repst...@apple.com
Date
2021-09-22 21:30:16 -0700 (Wed, 22 Sep 2021)

Log Message

Cherry-pick r282621. rdar://problem/83183656

    Move some profiling to UnlinkedCodeBlock
    https://bugs.webkit.org/show_bug.cgi?id=230078
    <rdar://problem/82947571>

    Reviewed by Yusuke Suzuki.

    This patch adds UnlinkedValueProfile and UnlinkedArrayProfile to
    UnlinkedCodeBlock. These profiles serialize the data in ValueProfile
    and ArrayProfile. Each time a CodeBlock updates value profiles,
    it mixes in up to date information from the unlinked profiles, and
    also writes back data to the unlinked profiles, so the data is shared
    between CodeBlocks of the same UnlinkedCodeBlock.

    This patch also fixes a pre-existing bug where we would sometimes think
    we had more metadata table entries than we really had in practice. This is
    because MetadataTable::forEach used the next opcode's start pointer. That
    pointer was aligned to that opcode's metadata alignment. So that might make
    the previous opcode think it had an extra 1-7 entries (depending on size,
    alignment, etc). This patch fixes that by having the next opcode's start
    offset in the table always be the end offset of the previous opcode, and we
    align the start pointer when using it.

    This was measured as a ~0.5% speedup on Speedometer2.

    * bytecode/ArrayProfile.h:
    (JSC::UnlinkedArrayProfile::update):
    * bytecode/CodeBlock.cpp:
    (JSC::CodeBlock::finishCreation):
    (JSC::CodeBlock::updateAllValueProfilePredictionsAndCountLiveness):
    (JSC::CodeBlock::updateAllArrayProfilePredictions):
    (JSC::CodeBlock::updateAllArrayPredictions):
    * bytecode/CodeBlock.h:
    (JSC::CodeBlock::metadata):
    * bytecode/CodeBlockInlines.h:
    (JSC::CodeBlock::forEachArrayProfile): Deleted.
    * bytecode/MetadataTable.cpp:
    (JSC::DeallocTable::withOpcodeType):
    * bytecode/MetadataTable.h:
    (JSC::MetadataTable::get):
    (JSC::MetadataTable::forEach):
    (JSC::MetadataTable::getWithoutAligning):
    (JSC::MetadataTable::getImpl): Deleted.
    * bytecode/UnlinkedCodeBlock.cpp:
    (JSC::UnlinkedCodeBlock::allocateSharedProfiles):
    * bytecode/UnlinkedCodeBlock.h:
    (JSC::UnlinkedCodeBlock::unlinkedValueProfile):
    (JSC::UnlinkedCodeBlock::unlinkedArrayProfile):
    * bytecode/UnlinkedCodeBlockGenerator.cpp:
    (JSC::UnlinkedCodeBlockGenerator::finalize):
    * bytecode/UnlinkedMetadataTable.cpp:
    (JSC::UnlinkedMetadataTable::finalize):
    * bytecode/UnlinkedMetadataTable.h:
    (JSC::UnlinkedMetadataTable::isFinalized):
    (JSC::UnlinkedMetadataTable::hasMetadata):
    * bytecode/UnlinkedMetadataTableInlines.h:
    (JSC::UnlinkedMetadataTable::numEntries):
    * bytecode/ValueProfile.h:
    (JSC::UnlinkedValueProfile::update):
    * bytecompiler/BytecodeGenerator.h:
    * llint/LowLevelInterpreter.asm:
    * runtime/CachedTypes.cpp:
    (JSC::CachedCodeBlock::numValueProfiles const):
    (JSC::CachedCodeBlock::numArrayProfiles const):
    (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
    (JSC::CachedCodeBlock<CodeBlockType>::encode):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282621 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-612-branch/Source/_javascript_Core/ChangeLog (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/ChangeLog	2021-09-23 04:30:16 UTC (rev 282917)
@@ -1,5 +1,146 @@
 2021-09-22  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r282621. rdar://problem/83183656
+
+    Move some profiling to UnlinkedCodeBlock
+    https://bugs.webkit.org/show_bug.cgi?id=230078
+    <rdar://problem/82947571>
+    
+    Reviewed by Yusuke Suzuki.
+    
+    This patch adds UnlinkedValueProfile and UnlinkedArrayProfile to
+    UnlinkedCodeBlock. These profiles serialize the data in ValueProfile
+    and ArrayProfile. Each time a CodeBlock updates value profiles,
+    it mixes in up to date information from the unlinked profiles, and
+    also writes back data to the unlinked profiles, so the data is shared
+    between CodeBlocks of the same UnlinkedCodeBlock.
+    
+    This patch also fixes a pre-existing bug where we would sometimes think
+    we had more metadata table entries than we really had in practice. This is
+    because MetadataTable::forEach used the next opcode's start pointer. That
+    pointer was aligned to that opcode's metadata alignment. So that might make
+    the previous opcode think it had an extra 1-7 entries (depending on size,
+    alignment, etc). This patch fixes that by having the next opcode's start
+    offset in the table always be the end offset of the previous opcode, and we
+    align the start pointer when using it.
+    
+    This was measured as a ~0.5% speedup on Speedometer2.
+    
+    * bytecode/ArrayProfile.h:
+    (JSC::UnlinkedArrayProfile::update):
+    * bytecode/CodeBlock.cpp:
+    (JSC::CodeBlock::finishCreation):
+    (JSC::CodeBlock::updateAllValueProfilePredictionsAndCountLiveness):
+    (JSC::CodeBlock::updateAllArrayProfilePredictions):
+    (JSC::CodeBlock::updateAllArrayPredictions):
+    * bytecode/CodeBlock.h:
+    (JSC::CodeBlock::metadata):
+    * bytecode/CodeBlockInlines.h:
+    (JSC::CodeBlock::forEachArrayProfile): Deleted.
+    * bytecode/MetadataTable.cpp:
+    (JSC::DeallocTable::withOpcodeType):
+    * bytecode/MetadataTable.h:
+    (JSC::MetadataTable::get):
+    (JSC::MetadataTable::forEach):
+    (JSC::MetadataTable::getWithoutAligning):
+    (JSC::MetadataTable::getImpl): Deleted.
+    * bytecode/UnlinkedCodeBlock.cpp:
+    (JSC::UnlinkedCodeBlock::allocateSharedProfiles):
+    * bytecode/UnlinkedCodeBlock.h:
+    (JSC::UnlinkedCodeBlock::unlinkedValueProfile):
+    (JSC::UnlinkedCodeBlock::unlinkedArrayProfile):
+    * bytecode/UnlinkedCodeBlockGenerator.cpp:
+    (JSC::UnlinkedCodeBlockGenerator::finalize):
+    * bytecode/UnlinkedMetadataTable.cpp:
+    (JSC::UnlinkedMetadataTable::finalize):
+    * bytecode/UnlinkedMetadataTable.h:
+    (JSC::UnlinkedMetadataTable::isFinalized):
+    (JSC::UnlinkedMetadataTable::hasMetadata):
+    * bytecode/UnlinkedMetadataTableInlines.h:
+    (JSC::UnlinkedMetadataTable::numEntries):
+    * bytecode/ValueProfile.h:
+    (JSC::UnlinkedValueProfile::update):
+    * bytecompiler/BytecodeGenerator.h:
+    * llint/LowLevelInterpreter.asm:
+    * runtime/CachedTypes.cpp:
+    (JSC::CachedCodeBlock::numValueProfiles const):
+    (JSC::CachedCodeBlock::numArrayProfiles const):
+    (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+    (JSC::CachedCodeBlock<CodeBlockType>::encode):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@282621 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-09-16  Saam Barati  <sbar...@apple.com>
+
+            Move some profiling to UnlinkedCodeBlock
+            https://bugs.webkit.org/show_bug.cgi?id=230078
+            <rdar://problem/82947571>
+
+            Reviewed by Yusuke Suzuki.
+
+            This patch adds UnlinkedValueProfile and UnlinkedArrayProfile to
+            UnlinkedCodeBlock. These profiles serialize the data in ValueProfile
+            and ArrayProfile. Each time a CodeBlock updates value profiles,
+            it mixes in up to date information from the unlinked profiles, and
+            also writes back data to the unlinked profiles, so the data is shared
+            between CodeBlocks of the same UnlinkedCodeBlock.
+
+            This patch also fixes a pre-existing bug where we would sometimes think
+            we had more metadata table entries than we really had in practice. This is
+            because MetadataTable::forEach used the next opcode's start pointer. That
+            pointer was aligned to that opcode's metadata alignment. So that might make
+            the previous opcode think it had an extra 1-7 entries (depending on size,
+            alignment, etc). This patch fixes that by having the next opcode's start
+            offset in the table always be the end offset of the previous opcode, and we
+            align the start pointer when using it.
+
+            This was measured as a ~0.5% speedup on Speedometer2.
+
+            * bytecode/ArrayProfile.h:
+            (JSC::UnlinkedArrayProfile::update):
+            * bytecode/CodeBlock.cpp:
+            (JSC::CodeBlock::finishCreation):
+            (JSC::CodeBlock::updateAllValueProfilePredictionsAndCountLiveness):
+            (JSC::CodeBlock::updateAllArrayProfilePredictions):
+            (JSC::CodeBlock::updateAllArrayPredictions):
+            * bytecode/CodeBlock.h:
+            (JSC::CodeBlock::metadata):
+            * bytecode/CodeBlockInlines.h:
+            (JSC::CodeBlock::forEachArrayProfile): Deleted.
+            * bytecode/MetadataTable.cpp:
+            (JSC::DeallocTable::withOpcodeType):
+            * bytecode/MetadataTable.h:
+            (JSC::MetadataTable::get):
+            (JSC::MetadataTable::forEach):
+            (JSC::MetadataTable::getWithoutAligning):
+            (JSC::MetadataTable::getImpl): Deleted.
+            * bytecode/UnlinkedCodeBlock.cpp:
+            (JSC::UnlinkedCodeBlock::allocateSharedProfiles):
+            * bytecode/UnlinkedCodeBlock.h:
+            (JSC::UnlinkedCodeBlock::unlinkedValueProfile):
+            (JSC::UnlinkedCodeBlock::unlinkedArrayProfile):
+            * bytecode/UnlinkedCodeBlockGenerator.cpp:
+            (JSC::UnlinkedCodeBlockGenerator::finalize):
+            * bytecode/UnlinkedMetadataTable.cpp:
+            (JSC::UnlinkedMetadataTable::finalize):
+            * bytecode/UnlinkedMetadataTable.h:
+            (JSC::UnlinkedMetadataTable::isFinalized):
+            (JSC::UnlinkedMetadataTable::hasMetadata):
+            * bytecode/UnlinkedMetadataTableInlines.h:
+            (JSC::UnlinkedMetadataTable::numEntries):
+            * bytecode/ValueProfile.h:
+            (JSC::UnlinkedValueProfile::update):
+            * bytecompiler/BytecodeGenerator.h:
+            * llint/LowLevelInterpreter.asm:
+            * runtime/CachedTypes.cpp:
+            (JSC::CachedCodeBlock::numValueProfiles const):
+            (JSC::CachedCodeBlock::numArrayProfiles const):
+            (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+            (JSC::CachedCodeBlock<CodeBlockType>::encode):
+
+2021-09-22  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r281319. rdar://problem/83430082
 
     Reduce StructureID entropy bits to 5 to make room for more StructureIDs.

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/ArrayProfile.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/ArrayProfile.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/ArrayProfile.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -32,6 +32,7 @@
 
 class CodeBlock;
 class LLIntOffsetsExtractor;
+class UnlinkedArrayProfile;
 
 // This is a bitfield where each bit represents an type of array access that we have seen.
 // There are 19 indexing types that use the lower bits.
@@ -195,6 +196,7 @@
 
 class ArrayProfile {
     friend class CodeBlock;
+    friend class UnlinkedArrayProfile;
 
 public:
     explicit ArrayProfile()
@@ -249,4 +251,46 @@
 };
 static_assert(sizeof(ArrayProfile) == 12);
 
+class UnlinkedArrayProfile {
+public:
+    UnlinkedArrayProfile() = default;
+
+    void update(ArrayProfile& arrayProfile)
+    {
+        ArrayModes newModes = arrayProfile.m_observedArrayModes | m_observedArrayModes;
+        m_observedArrayModes = newModes;
+        arrayProfile.m_observedArrayModes = newModes;
+
+        if (m_mayStoreToHole)
+            arrayProfile.m_mayStoreToHole = true;
+        else
+            m_mayStoreToHole = arrayProfile.m_mayStoreToHole;
+
+        if (m_outOfBounds)
+            arrayProfile.m_outOfBounds = true;
+        else
+            m_outOfBounds = arrayProfile.m_outOfBounds;
+
+        if (m_mayInterceptIndexedAccesses)
+            arrayProfile.m_mayInterceptIndexedAccesses = true;
+        else
+            m_mayInterceptIndexedAccesses = arrayProfile.m_mayInterceptIndexedAccesses;
+
+        if (!m_usesOriginalArrayStructures)
+            arrayProfile.m_usesOriginalArrayStructures = false;
+        else
+            m_usesOriginalArrayStructures = arrayProfile.m_usesOriginalArrayStructures;
+    }
+
+private:
+    ArrayModes m_observedArrayModes { 0 };
+    // We keep these as full byte-sized booleans just for speed, because the
+    // alignment of this struct will already make us 8 bytes large. But if we
+    // ever need to add more stuff, these fields can become bitfields.
+    bool m_mayStoreToHole { false };
+    bool m_outOfBounds { false };
+    bool m_mayInterceptIndexedAccesses { false };
+    bool m_usesOriginalArrayStructures { true };
+};
+
 } // namespace JSC

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -2893,6 +2893,7 @@
     numberOfLiveNonArgumentValueProfiles = 0;
     numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
 
+    unsigned index = 0;
     forEachValueProfile([&](ValueProfile& profile, bool isArgument) {
         unsigned numSamples = profile.totalNumberOfSamples();
         static_assert(ValueProfile::numberOfBuckets == 1);
@@ -2901,11 +2902,13 @@
         numberOfSamplesInProfiles += numSamples;
         if (isArgument) {
             profile.computeUpdatedPrediction(locker);
+            unlinkedCodeBlock()->unlinkedValueProfile(index++).update(profile);
             return;
         }
         if (profile.numberOfSamples() || profile.isSampledBefore())
             numberOfLiveNonArgumentValueProfiles++;
         profile.computeUpdatedPrediction(locker);
+        unlinkedCodeBlock()->unlinkedValueProfile(index++).update(profile);
     });
 
     if (m_metadata) {
@@ -2929,14 +2932,50 @@
     updateAllValueProfilePredictionsAndCountLiveness(ignoredValue1, ignoredValue2);
 }
 
+void CodeBlock::updateAllArrayProfilePredictions(const ConcurrentJSLocker& locker)
+{
+    if (!m_metadata)
+        return;
+
+    unsigned index = 0;
+
+    auto process = [&] (ArrayProfile& profile) {
+        profile.computeUpdatedPrediction(locker, this);
+        unlinkedCodeBlock()->unlinkedArrayProfile(index++).update(profile);
+    };
+
+    m_metadata->forEach<OpGetById>([&] (auto& metadata) {
+        if (metadata.m_modeMetadata.mode == GetByIdMode::ArrayLength)
+            process(metadata.m_modeMetadata.arrayLengthMode.arrayProfile);
+        else {
+            // We reserve an index per GetById whether or not it's currently in ArrayLength mode.
+            ++index;
+        }
+    });
+
+#define VISIT1(__op) \
+    m_metadata->forEach<__op>([&] (auto& metadata) { process(metadata.m_arrayProfile); });
+
+#define VISIT2(__op) \
+    m_metadata->forEach<__op>([&] (auto& metadata) { process(metadata.m_callLinkInfo.m_arrayProfile); });
+
+    FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(VISIT1)
+    FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(VISIT2)
+
+#undef VISIT1
+#undef VISIT2
+
+    m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {
+        process(metadata.m_iterableProfile);
+    });
+}
+
 void CodeBlock::updateAllArrayPredictions()
 {
     ConcurrentJSLocker locker(m_lock);
+
+    updateAllArrayProfilePredictions(locker);
     
-    forEachArrayProfile([&](ArrayProfile& profile) {
-        profile.computeUpdatedPrediction(locker, this);
-    });
-    
     forEachArrayAllocationProfile([&](ArrayAllocationProfile& profile) {
         profile.updateProfile();
     });

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlock.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -489,7 +489,6 @@
     SpeculatedType valueProfilePredictionForBytecodeIndex(const ConcurrentJSLocker&, BytecodeIndex);
 
     template<typename Functor> void forEachValueProfile(const Functor&);
-    template<typename Functor> void forEachArrayProfile(const Functor&);
     template<typename Functor> void forEachArrayAllocationProfile(const Functor&);
     template<typename Functor> void forEachObjectAllocationProfile(const Functor&);
     template<typename Functor> void forEachLLIntCallLinkInfo(const Functor&);
@@ -787,6 +786,7 @@
 
     bool shouldOptimizeNow();
     void updateAllValueProfilePredictions();
+    void updateAllArrayProfilePredictions(const ConcurrentJSLocker&);
     void updateAllArrayPredictions();
     void updateAllPredictions();
 
@@ -886,7 +886,8 @@
     Metadata& metadata(OpcodeID opcodeID, unsigned metadataID)
     {
         ASSERT(m_metadata);
-        return bitwise_cast<Metadata*>(m_metadata->get(opcodeID))[metadataID];
+        ASSERT_UNUSED(opcodeID, opcodeID == Metadata::opcodeID);
+        return m_metadata->get<Metadata>()[metadataID];
     }
 
     template<typename Metadata>

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlockInlines.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlockInlines.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/CodeBlockInlines.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -61,33 +61,6 @@
 }
 
 template<typename Functor>
-void CodeBlock::forEachArrayProfile(const Functor& func)
-{
-    if (m_metadata) {
-        m_metadata->forEach<OpGetById>([&] (auto& metadata) {
-            if (metadata.m_modeMetadata.mode == GetByIdMode::ArrayLength)
-                func(metadata.m_modeMetadata.arrayLengthMode.arrayProfile);
-        });
-
-#define VISIT1(__op) \
-    m_metadata->forEach<__op>([&] (auto& metadata) { func(metadata.m_arrayProfile); });
-
-#define VISIT2(__op) \
-    m_metadata->forEach<__op>([&] (auto& metadata) { func(metadata.m_callLinkInfo.m_arrayProfile); });
-
-        FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(VISIT1)
-        FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(VISIT2)
-
-#undef VISIT1
-#undef VISIT2
-
-        m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {
-            func(metadata.m_iterableProfile);
-        });
-    }
-}
-
-template<typename Functor>
 void CodeBlock::forEachArrayAllocationProfile(const Functor& func)
 {
     if (m_metadata) {

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -44,9 +44,11 @@
     template<typename Op>
     static void withOpcodeType(MetadataTable* table)
     {
-        table->forEach<Op>([](auto& entry) {
-            entry.~Metadata();
-        });
+        if constexpr (static_cast<unsigned>(Op::opcodeID) < NUMBER_OF_BYTECODE_WITH_METADATA) {
+            table->forEach<Op>([](auto& entry) {
+                entry.~Metadata();
+            });
+        }
     }
 };
 

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/MetadataTable.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -46,18 +46,22 @@
 public:
     ~MetadataTable();
 
-    ALWAYS_INLINE Instruction::Metadata* get(OpcodeID opcodeID)
+    template<typename Metadata>
+    ALWAYS_INLINE Metadata* get()
     {
+        auto opcodeID = Metadata::opcodeID;
         ASSERT(opcodeID < NUMBER_OF_BYTECODE_WITH_METADATA);
-        return reinterpret_cast<Instruction::Metadata*>(getImpl(opcodeID));
+        uintptr_t ptr = bitwise_cast<uintptr_t>(getWithoutAligning(opcodeID));
+        ptr = roundUpToMultipleOf(alignof(Metadata), ptr);
+        return bitwise_cast<Metadata*>(ptr);
     }
 
     template<typename Op, typename Functor>
     ALWAYS_INLINE void forEach(const Functor& func)
     {
-        auto* metadata = bitwise_cast<typename Op::Metadata*>(get(Op::opcodeID));
-        auto* end = bitwise_cast<typename Op::Metadata*>(getImpl(Op::opcodeID + 1));
-        for (; metadata + 1 <= end; ++metadata)
+        auto* metadata = get<typename Op::Metadata>();
+        auto* end = bitwise_cast<typename Op::Metadata*>(getWithoutAligning(Op::opcodeID + 1));
+        for (; metadata < end; ++metadata)
             func(*metadata);
     }
 
@@ -116,7 +120,7 @@
         return offsetTable32()[i];
     }
 
-    ALWAYS_INLINE uint8_t* getImpl(unsigned i)
+    ALWAYS_INLINE uint8_t* getWithoutAligning(unsigned i)
     {
         return bitwise_cast<uint8_t*>(this) + getOffset(i);
     }

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -316,4 +316,37 @@
     return m_outOfLineJumpTargets.get(bytecodeOffset);
 }
 
+void UnlinkedCodeBlock::allocateSharedProfiles()
+{
+    RELEASE_ASSERT(!m_metadata->isFinalized());
+
+    {
+        unsigned numberOfValueProfiles = numParameters();
+        if (m_metadata->hasMetadata()) {
+#define COUNT(__op) \
+            numberOfValueProfiles += m_metadata->numEntries<__op>();
+            FOR_EACH_OPCODE_WITH_VALUE_PROFILE(COUNT)
+#undef COUNT
+            numberOfValueProfiles += m_metadata->numEntries<OpIteratorOpen>() * 3;
+            numberOfValueProfiles += m_metadata->numEntries<OpIteratorNext>() * 3;
+        }
+
+        m_valueProfiles = FixedVector<UnlinkedValueProfile>(numberOfValueProfiles);
+    }
+
+    if (m_metadata->hasMetadata()) {
+        unsigned numberOfArrayProfiles = 0;
+
+#define COUNT(__op) \
+        numberOfArrayProfiles += m_metadata->numEntries<__op>();
+        FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(COUNT)
+        FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(COUNT)
+#undef COUNT
+        numberOfArrayProfiles += m_metadata->numEntries<OpIteratorNext>();
+        numberOfArrayProfiles += m_metadata->numEntries<OpGetById>();
+
+        m_arrayProfiles = FixedVector<UnlinkedArrayProfile>(numberOfArrayProfiles);
+    }
+}
+
 } // namespace JSC

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "ArrayProfile.h"
 #include "BytecodeConventions.h"
 #include "CodeType.h"
 #include "DFGExitProfile.h"
@@ -38,6 +39,7 @@
 #include "RegExp.h"
 #include "UnlinkedFunctionExecutable.h"
 #include "UnlinkedMetadataTable.h"
+#include "ValueProfile.h"
 #include "VirtualRegister.h"
 #include <algorithm>
 #include <wtf/BitVector.h>
@@ -68,8 +70,6 @@
 template<typename CodeBlockType>
 class CachedCodeBlock;
 
-typedef unsigned UnlinkedValueProfile;
-typedef unsigned UnlinkedArrayProfile;
 typedef unsigned UnlinkedArrayAllocationProfile;
 typedef unsigned UnlinkedObjectAllocationProfile;
 typedef unsigned UnlinkedLLIntCallLinkInfo;
@@ -334,6 +334,9 @@
         return m_metadata->sizeInBytes();
     }
 
+    void allocateSharedProfiles();
+    UnlinkedValueProfile& unlinkedValueProfile(unsigned index) { return m_valueProfiles[index]; }
+    UnlinkedArrayProfile& unlinkedArrayProfile(unsigned index) { return m_arrayProfiles[index]; }
 
 protected:
     UnlinkedCodeBlock(VM&, Structure*, CodeType, const ExecutableInfo&, OptionSet<CodeGenerationMode>);
@@ -462,6 +465,8 @@
     OutOfLineJumpTargets m_outOfLineJumpTargets;
     std::unique_ptr<RareData> m_rareData;
     FixedVector<ExpressionRangeInfo> m_expressionInfo;
+    FixedVector<UnlinkedValueProfile> m_valueProfiles;
+    FixedVector<UnlinkedArrayProfile> m_arrayProfiles;
 
 protected:
     DECLARE_VISIT_CHILDREN;

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -119,6 +119,7 @@
     {
         Locker locker { m_codeBlock->cellLock() };
         m_codeBlock->m_instructions = WTFMove(instructions);
+        m_codeBlock->allocateSharedProfiles();
         m_codeBlock->m_metadata->finalize();
 
         m_codeBlock->m_jumpTargets = WTFMove(m_jumpTargets);

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -55,10 +55,10 @@
                 buffer[i] = offset;
                 continue;
             }
+            buffer[i] = offset; // We align when we access this.
             unsigned alignment = metadataAlignment(static_cast<OpcodeID>(i));
             offset = roundUpToMultipleOf(alignment, offset);
             ASSERT(alignment <= s_maxMetadataAlignment);
-            buffer[i] = offset;
             offset += numberOfEntries * metadataSize(static_cast<OpcodeID>(i));
         }
         buffer[s_offsetTableEntries - 1] = offset;

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -64,6 +64,12 @@
         return adoptRef(*new UnlinkedMetadataTable);
     }
 
+    template <typename Bytecode>
+    unsigned numEntries();
+
+    bool isFinalized() { return m_isFinalized; }
+    bool hasMetadata() { return m_hasMetadata; }
+
 private:
     enum EmptyTag { Empty };
 

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -73,6 +73,14 @@
     return preprocessBuffer()[opcodeID]++;
 }
 
+template <typename Bytecode>
+ALWAYS_INLINE unsigned UnlinkedMetadataTable::numEntries()
+{
+    constexpr auto opcodeID = Bytecode::opcodeID;
+    ASSERT(!m_isFinalized && opcodeID < s_offsetTableEntries - 1);
+    return preprocessBuffer()[opcodeID];
+}
+
 ALWAYS_INLINE size_t UnlinkedMetadataTable::sizeInBytes()
 {
     if (m_isFinalized && !m_hasMetadata)

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecode/ValueProfile.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecode/ValueProfile.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecode/ValueProfile.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -31,13 +31,18 @@
 #include "ConcurrentJSLock.h"
 #include "SpeculatedType.h"
 #include "Structure.h"
+#include "VirtualRegister.h"
 #include <wtf/PrintStream.h>
 #include <wtf/StringPrintStream.h>
 
 namespace JSC {
 
+class UnlinkedValueProfile;
+
 template<unsigned numberOfBucketsArgument>
 struct ValueProfileBase {
+    friend class UnlinkedValueProfile;
+
     static constexpr unsigned numberOfBuckets = numberOfBucketsArgument;
     static constexpr unsigned numberOfSpecFailBuckets = 1;
     static constexpr unsigned bucketIndexMask = numberOfBuckets - 1;
@@ -213,4 +218,19 @@
     unsigned m_size;
 };
 
+class UnlinkedValueProfile {
+public:
+    UnlinkedValueProfile() = default;
+
+    void update(ValueProfile& profile)
+    {
+        SpeculatedType newType = profile.m_prediction | m_prediction;
+        profile.m_prediction = newType;
+        m_prediction = newType;
+    }
+
+private:
+    SpeculatedType m_prediction { SpecNone };
+};
+
 } // namespace JSC

Modified: branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-09-23 04:30:16 UTC (rev 282917)
@@ -1069,7 +1069,6 @@
         void popLexicalScope(VariableEnvironmentNode*);
         void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
         int labelScopeDepth() const;
-        UnlinkedArrayProfile newArrayProfile();
 
     private:
         ParserError generate();

Modified: branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2021-09-23 04:30:16 UTC (rev 282917)
@@ -413,6 +413,11 @@
     muli sizeof %opcode%::Metadata, scratch # scratch *= sizeof(Op::Metadata)
     addi scratch, dst # offset += scratch
     addp metadataTable, dst # return &metadataTable[offset]
+    # roundUpToMultipleOf(alignof(Metadata), dst)
+    const adder = (constexpr (alignof(%opcode%::Metadata))) - 1
+    const mask = ~adder
+    addp adder, dst
+    andp mask, dst
 end
 
 macro jumpImpl(dispatchIndirect, targetOffsetReg)

Modified: branches/safari-612-branch/Source/_javascript_Core/runtime/CachedTypes.cpp (282916 => 282917)


--- branches/safari-612-branch/Source/_javascript_Core/runtime/CachedTypes.cpp	2021-09-23 04:30:08 UTC (rev 282916)
+++ branches/safari-612-branch/Source/_javascript_Core/runtime/CachedTypes.cpp	2021-09-23 04:30:16 UTC (rev 282917)
@@ -1916,6 +1916,9 @@
 
     UnlinkedCodeBlock::RareData* rareData(Decoder& decoder) const { return m_rareData.decode(decoder); }
 
+    unsigned numValueProfiles() const { return m_numValueProfiles; }
+    unsigned numArrayProfiles() const { return m_numArrayProfiles; }
+
 private:
     VirtualRegister m_thisRegister;
     VirtualRegister m_scopeRegister;
@@ -1947,6 +1950,9 @@
     int m_numCalleeLocals;
     int m_numParameters;
 
+    unsigned m_numValueProfiles;
+    unsigned m_numArrayProfiles;
+
     CachedMetadataTable m_metadata;
 
     CachedPtr<CachedCodeBlockRareData> m_rareData;
@@ -2151,8 +2157,9 @@
 
     , m_metadata(cachedCodeBlock.metadata(decoder))
     , m_instructions(cachedCodeBlock.instructions(decoder))
-
     , m_rareData(cachedCodeBlock.rareData(decoder))
+    , m_valueProfiles(cachedCodeBlock.numValueProfiles())
+    , m_arrayProfiles(cachedCodeBlock.numArrayProfiles())
 {
 }
 
@@ -2328,6 +2335,8 @@
     m_codeGenerationMode = codeBlock.m_codeGenerationMode;
     m_codeType = codeBlock.m_codeType;
     m_hasCheckpoints = codeBlock.m_hasCheckpoints;
+    m_numValueProfiles = codeBlock.m_valueProfiles.size();
+    m_numArrayProfiles = codeBlock.m_arrayProfiles.size();
 
     m_metadata.encode(encoder, codeBlock.m_metadata.get());
     m_rareData.encode(encoder, codeBlock.m_rareData.get());
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to