Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,17 @@ void UnlinkedMetadataTable::finalize()
});
#endif

unsigned valueProfileSize = m_numValueProfiles * sizeof(ValueProfile);
ASSERT(!m_isLinked);
if (m_is32Bit) {
// offset already accounts for s_offset16TableSize
uint8_t* newBuffer = reinterpret_cast_ptr<uint8_t*>(MetadataTableMalloc::malloc(valueProfileSize + sizeof(LinkingData) + s_offset32TableSize + offset));
memset(newBuffer, 0, valueProfileSize + sizeof(LinkingData) + s_offset16TableSize);
memset(newBuffer + valueProfileSize + sizeof(LinkingData) + s_offset16TableSize + s_offset32TableSize, 0, offset - s_offset16TableSize);
Offset32* buffer = std::bit_cast<Offset32*>(newBuffer + valueProfileSize + sizeof(LinkingData) + s_offset16TableSize);
uint8_t* newBuffer = reinterpret_cast_ptr<uint8_t*>(MetadataTableMalloc::zeroedMalloc(s_offset16TableSize + s_offset32TableSize));
Offset32* buffer = std::bit_cast<Offset32*>(newBuffer + s_offset16TableSize);
for (unsigned i = 0; i < s_offsetTableEntries; ++i)
buffer[i] = preprocessBuffer()[i] + s_offset32TableSize;
MetadataTableMalloc::free(m_rawBuffer);
m_rawBuffer = newBuffer;
} else {
// offset already accounts for s_offset16TableSize
uint8_t* newBuffer = reinterpret_cast_ptr<uint8_t*>(MetadataTableMalloc::malloc(valueProfileSize + sizeof(LinkingData) + offset));
memset(newBuffer, 0, valueProfileSize + sizeof(LinkingData));
memset(newBuffer + valueProfileSize + sizeof(LinkingData) + s_offset16TableSize, 0, offset - s_offset16TableSize);
Offset16* buffer = std::bit_cast<Offset16*>(newBuffer + valueProfileSize + sizeof(LinkingData));
uint8_t* newBuffer = reinterpret_cast_ptr<uint8_t*>(MetadataTableMalloc::malloc(s_offset16TableSize));
Offset16* buffer = std::bit_cast<Offset16*>(newBuffer);
for (unsigned i = 0; i < s_offsetTableEntries; ++i)
buffer[i] = preprocessBuffer()[i];
MetadataTableMalloc::free(m_rawBuffer);
Expand Down
14 changes: 8 additions & 6 deletions Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ class UnlinkedMetadataTable : public ThreadSafeRefCounted<UnlinkedMetadataTable>
enum EmptyTag { Empty };

UnlinkedMetadataTable();
UnlinkedMetadataTable(bool is32Bit, unsigned numValueProfiles, unsigned lastOffset);
UnlinkedMetadataTable(bool is32Bit, unsigned numValueProfiles);
UnlinkedMetadataTable(EmptyTag);

static Ref<UnlinkedMetadataTable> create(bool is32Bit, unsigned numValueProfiles, unsigned lastOffset)
static Ref<UnlinkedMetadataTable> create(bool is32Bit, unsigned numValueProfiles)
{
return adoptRef(*new UnlinkedMetadataTable(is32Bit, numValueProfiles, lastOffset));
return adoptRef(*new UnlinkedMetadataTable(is32Bit, numValueProfiles));
}

static Ref<UnlinkedMetadataTable> empty()
Expand Down Expand Up @@ -151,18 +151,20 @@ class UnlinkedMetadataTable : public ThreadSafeRefCounted<UnlinkedMetadataTable>
// Then, s_offset16TableSize and s_offset16TableSize + s_offset32TableSize offer the same alignment characteristics for subsequent Metadata.
static constexpr unsigned s_offset32TableSize = roundUpToMultipleOf<s_maxMetadataAlignment>(s_offsetTableEntries * sizeof(Offset32));

void* buffer() const { return m_rawBuffer + m_numValueProfiles * sizeof(ValueProfile) + sizeof(LinkingData); }
// While no MetadataTable shares m_rawBuffer (!m_isLinked), the buffer holds only the offset table.
unsigned prefixSize() const { return m_isLinked ? m_numValueProfiles * sizeof(ValueProfile) + sizeof(LinkingData) : 0; }
void* buffer() const { return m_rawBuffer + prefixSize(); }
Offset32* preprocessBuffer() const { return std::bit_cast<Offset32*>(m_rawBuffer); }

Offset16* offsetTable16() const
{
ASSERT(!m_is32Bit);
return std::bit_cast<Offset16*>(m_rawBuffer + m_numValueProfiles * sizeof(ValueProfile) + sizeof(LinkingData));
return std::bit_cast<Offset16*>(m_rawBuffer + prefixSize());
}
Offset32* offsetTable32() const
{
ASSERT(m_is32Bit);
return std::bit_cast<Offset32*>(m_rawBuffer + m_numValueProfiles * sizeof(ValueProfile) + sizeof(LinkingData) + s_offset16TableSize);
return std::bit_cast<Offset32*>(m_rawBuffer + prefixSize() + s_offset16TableSize);
}

bool m_hasMetadata : 1;
Expand Down
22 changes: 13 additions & 9 deletions Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable()
{
}

ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable(bool is32Bit, unsigned numValueProfiles, unsigned lastOffset)
// A finalized table as it comes out of the bytecode cache: the caller fills in the offset table; the value-profile /
// metadata buffer is allocated at link().
ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable(bool is32Bit, unsigned numValueProfiles)
: m_hasMetadata(true)
, m_isFinalized(false)
, m_isLinked(false)
, m_is32Bit(is32Bit)
, m_numValueProfiles(numValueProfiles)
, m_rawBuffer(static_cast<uint8_t*>(MetadataTableMalloc::zeroedMalloc((sizeof(ValueProfile) * numValueProfiles) + sizeof(LinkingData) + lastOffset)))
, m_rawBuffer(static_cast<uint8_t*>(MetadataTableMalloc::zeroedMalloc(is32Bit ? s_offset16TableSize + s_offset32TableSize : s_offset16TableSize)))
{
}

Expand Down Expand Up @@ -123,21 +125,18 @@ ALWAYS_INLINE RefPtr<MetadataTable> UnlinkedMetadataTable::link()
unsigned totalSize = this->totalSize();
unsigned offsetTableSize = this->offsetTableSize();
unsigned valueProfileSize = m_numValueProfiles * sizeof(ValueProfile);
uint8_t* buffer;
uint8_t* buffer = static_cast<uint8_t*>(MetadataTableMalloc::zeroedMalloc(sizeof(LinkingData) + totalSize));
memcpy(buffer + valueProfileSize + sizeof(LinkingData), this->buffer(), offsetTableSize);
if (!m_isLinked) {
MetadataTableMalloc::free(m_rawBuffer);
m_rawBuffer = buffer;
m_isLinked = true;
buffer = m_rawBuffer;
} else {
#if ENABLE(METADATA_STATISTICS)
MetadataStatistics::numberOfCopiesFromLinking++;
MetadataStatistics::linkingCopyMemory += sizeof(LinkingData) + totalSize;
#endif
buffer = static_cast<uint8_t*>(MetadataTableMalloc::malloc(sizeof(LinkingData) + totalSize));
memcpy(buffer + valueProfileSize + sizeof(LinkingData), m_rawBuffer + valueProfileSize + sizeof(LinkingData), offsetTableSize);
}
// FIXME: Is this needed since we'll clear the data in the CodeBlock Constructor... Plus I could see caching value profiles being profitable.
memset(buffer, 0, valueProfileSize);
memset(buffer + valueProfileSize + sizeof(LinkingData) + offsetTableSize, 0, totalSize - offsetTableSize - valueProfileSize);
return adoptRef(*new (buffer + valueProfileSize + sizeof(LinkingData)) MetadataTable(*this));
}

Expand All @@ -149,6 +148,11 @@ ALWAYS_INLINE void UnlinkedMetadataTable::unlink(MetadataTable& metadataTable)

if (metadataTable.buffer() == buffer()) {
ASSERT(m_isLinked);
unsigned offsetTableSize = this->offsetTableSize();
uint8_t* compact = static_cast<uint8_t*>(MetadataTableMalloc::malloc(offsetTableSize));
memcpy(compact, buffer(), offsetTableSize);
MetadataTableMalloc::free(m_rawBuffer);
m_rawBuffer = compact;
m_isLinked = false;
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/runtime/CachedTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ class CachedMetadataTable : public CachedObject<UnlinkedMetadataTable> {
if (!m_hasMetadata)
return UnlinkedMetadataTable::empty();

Ref<UnlinkedMetadataTable> metadataTable = UnlinkedMetadataTable::create(m_is32Bit, m_numValueProfiles, m_metadata[UnlinkedMetadataTable::s_offsetTableEntries - 1]);
Ref<UnlinkedMetadataTable> metadataTable = UnlinkedMetadataTable::create(m_is32Bit, m_numValueProfiles);
metadataTable->m_isFinalized = true;
metadataTable->m_isLinked = false;
metadataTable->m_hasMetadata = m_hasMetadata;
Expand Down
Loading