Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (282620 => 282621)
--- trunk/Source/_javascript_Core/ChangeLog 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-09-17 00:11:24 UTC (rev 282621)
@@ -1,3 +1,71 @@
+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-16 Commit Queue <commit-qu...@webkit.org>
Unreviewed, reverting r282478.
Modified: trunk/Source/_javascript_Core/bytecode/ArrayProfile.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/ArrayProfile.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/ArrayProfile.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/CodeBlockInlines.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/CodeBlockInlines.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlockInlines.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/MetadataTable.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/MetadataTable.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/MetadataTable.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/MetadataTable.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/MetadataTable.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/MetadataTable.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlockGenerator.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTable.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedMetadataTableInlines.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecode/ValueProfile.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecode/ValueProfile.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (282620 => 282621)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2021-09-17 00:11:24 UTC (rev 282621)
@@ -1069,7 +1069,6 @@
void popLexicalScope(VariableEnvironmentNode*);
void prepareLexicalScopeForNextForLoopIteration(VariableEnvironmentNode*, RegisterID* loopSymbolTable);
int labelScopeDepth() const;
- UnlinkedArrayProfile newArrayProfile();
private:
ParserError generate();
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (282620 => 282621)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (282620 => 282621)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2021-09-17 00:09:25 UTC (rev 282620)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2021-09-17 00:11:24 UTC (rev 282621)
@@ -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());