/ bytecode / UnlinkedMetadataTable.cpp
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