UnlinkedMetadataTable.cpp
1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "UnlinkedMetadataTable.h" 28 29 #include "BytecodeStructs.h" 30 31 namespace JSC { 32 33 DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetadataTable); 34 35 #define JSC_ALIGNMENT_CHECK(size) static_assert(size <= UnlinkedMetadataTable::s_maxMetadataAlignment); 36 FOR_EACH_BYTECODE_METADATA_ALIGNMENT(JSC_ALIGNMENT_CHECK) 37 #undef JSC_ALIGNMENT_CHECK 38 39 void UnlinkedMetadataTable::finalize() 40 { 41 ASSERT(!m_isFinalized); 42 m_isFinalized = true; 43 if (!m_hasMetadata) { 44 MetadataTableMalloc::free(m_rawBuffer); 45 m_rawBuffer = nullptr; 46 return; 47 } 48 49 unsigned offset = s_offset16TableSize; 50 { 51 Offset32* buffer = preprocessBuffer(); 52 for (unsigned i = 0; i < s_offsetTableEntries - 1; i++) { 53 unsigned numberOfEntries = buffer[i]; 54 if (!numberOfEntries) { 55 buffer[i] = offset; 56 continue; 57 } 58 unsigned alignment = metadataAlignment(static_cast<OpcodeID>(i)); 59 offset = roundUpToMultipleOf(alignment, offset); 60 ASSERT(alignment <= s_maxMetadataAlignment); 61 buffer[i] = offset; 62 offset += numberOfEntries * metadataSize(static_cast<OpcodeID>(i)); 63 } 64 buffer[s_offsetTableEntries - 1] = offset; 65 m_is32Bit = offset > UINT16_MAX; 66 } 67 68 if (m_is32Bit) { 69 m_rawBuffer = reinterpret_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, s_offset16TableSize + s_offset32TableSize + sizeof(LinkingData))); 70 memmove(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize, m_rawBuffer + sizeof(LinkingData), s_offset32TableSize); 71 memset(m_rawBuffer + sizeof(LinkingData), 0, s_offset16TableSize); 72 Offset32* buffer = bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize); 73 // This adjustment does not break the alignment calculated for metadata in the above loop so long as s_offset32TableSize is rounded with 8. 74 for (unsigned i = 0; i < s_offsetTableEntries; i++) 75 buffer[i] += s_offset32TableSize; 76 } else { 77 Offset32* oldBuffer = bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData)); 78 Offset16* buffer = bitwise_cast<Offset16*>(m_rawBuffer + sizeof(LinkingData)); 79 for (unsigned i = 0; i < s_offsetTableEntries; i++) 80 buffer[i] = oldBuffer[i]; 81 m_rawBuffer = static_cast<uint8_t*>(MetadataTableMalloc::realloc(m_rawBuffer, s_offset16TableSize + sizeof(LinkingData))); 82 } 83 } 84 85 } // namespace JSC