/ bytecode / UnlinkedMetadataTable.h
UnlinkedMetadataTable.h
  1  /*
  2   * Copyright (C) 2018 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  #pragma once
 27  
 28  #include "Opcode.h"
 29  #include <wtf/Ref.h>
 30  #include <wtf/RefCounted.h>
 31  
 32  namespace JSC {
 33  
 34  class VM;
 35  
 36  DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(MetadataTable);
 37  
 38  class MetadataTable;
 39  
 40  class UnlinkedMetadataTable : public RefCounted<UnlinkedMetadataTable> {
 41      friend class LLIntOffsetsExtractor;
 42      friend class MetadataTable;
 43      friend class CachedMetadataTable;
 44  public:
 45      static constexpr unsigned s_maxMetadataAlignment = 8;
 46  
 47      struct LinkingData {
 48          Ref<UnlinkedMetadataTable> unlinkedMetadata;
 49          unsigned refCount;
 50      };
 51  
 52      ~UnlinkedMetadataTable();
 53  
 54      unsigned addEntry(OpcodeID);
 55  
 56      size_t sizeInBytes();
 57  
 58      void finalize();
 59  
 60      RefPtr<MetadataTable> link();
 61  
 62      static Ref<UnlinkedMetadataTable> create()
 63      {
 64          return adoptRef(*new UnlinkedMetadataTable);
 65      }
 66  
 67  private:
 68      enum EmptyTag { Empty };
 69  
 70      UnlinkedMetadataTable();
 71      UnlinkedMetadataTable(bool is32Bit);
 72      UnlinkedMetadataTable(EmptyTag);
 73  
 74      static Ref<UnlinkedMetadataTable> create(bool is32Bit)
 75      {
 76          return adoptRef(*new UnlinkedMetadataTable(is32Bit));
 77      }
 78  
 79      static Ref<UnlinkedMetadataTable> empty()
 80      {
 81          return adoptRef(*new UnlinkedMetadataTable(Empty));
 82      }
 83  
 84      void unlink(MetadataTable&);
 85  
 86      size_t sizeInBytes(MetadataTable&);
 87  
 88      unsigned totalSize() const
 89      {
 90          ASSERT(m_isFinalized);
 91          if (m_is32Bit)
 92              return offsetTable32()[s_offsetTableEntries - 1];
 93          return offsetTable16()[s_offsetTableEntries - 1];
 94      }
 95  
 96      unsigned offsetTableSize() const
 97      {
 98          ASSERT(m_isFinalized);
 99          if (m_is32Bit)
100              return s_offset16TableSize + s_offset32TableSize;
101          return s_offset16TableSize;
102      }
103  
104      using Offset32 = uint32_t;
105      using Offset16 = uint16_t;
106  
107      static constexpr unsigned s_offsetTableEntries = NUMBER_OF_BYTECODE_WITH_METADATA + 1; // one extra entry for the "end" offset;
108  
109      // Not to break alignment of 32bit offset table, we round up size with sizeof(Offset32).
110      static constexpr unsigned s_offset16TableSize = roundUpToMultipleOf<sizeof(Offset32)>(s_offsetTableEntries * sizeof(Offset16));
111      // Not to break alignment of the metadata calculated based on the alignment of s_offset16TableSize, s_offset32TableSize must be rounded by 8.
112      // Then, s_offset16TableSize and s_offset16TableSize + s_offset32TableSize offer the same alignment characteristics for subsequent Metadata.
113      static constexpr unsigned s_offset32TableSize = roundUpToMultipleOf<s_maxMetadataAlignment>(s_offsetTableEntries * sizeof(Offset32));
114  
115      Offset32* preprocessBuffer() const { return bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData)); }
116      void* buffer() const { return m_rawBuffer + sizeof(LinkingData); }
117  
118      Offset16* offsetTable16() const
119      {
120          ASSERT(!m_is32Bit);
121          return bitwise_cast<Offset16*>(m_rawBuffer + sizeof(LinkingData));
122      }
123      Offset32* offsetTable32() const
124      {
125          ASSERT(m_is32Bit);
126          return bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize);
127      }
128  
129      bool m_hasMetadata : 1;
130      bool m_isFinalized : 1;
131      bool m_isLinked : 1;
132      bool m_is32Bit : 1;
133      uint8_t* m_rawBuffer;
134  };
135  
136  } // namespace JSC