MetadataTable.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 "Instruction.h" 29 #include "Opcode.h" 30 #include "UnlinkedMetadataTable.h" 31 #include <wtf/RefCounted.h> 32 33 namespace JSC { 34 35 class CodeBlock; 36 37 // MetadataTable has a bit strange memory layout for LLInt optimization. 38 // [UnlinkedMetadataTable::LinkingData][MetadataTable] 39 // ^ 40 // The pointer of MetadataTable points at this address. 41 class MetadataTable { 42 WTF_MAKE_FAST_ALLOCATED; 43 WTF_MAKE_NONCOPYABLE(MetadataTable); 44 friend class LLIntOffsetsExtractor; 45 friend class UnlinkedMetadataTable; 46 public: 47 ~MetadataTable(); 48 49 ALWAYS_INLINE Instruction::Metadata* get(OpcodeID opcodeID) 50 { 51 ASSERT(opcodeID < NUMBER_OF_BYTECODE_WITH_METADATA); 52 return reinterpret_cast<Instruction::Metadata*>(getImpl(opcodeID)); 53 } 54 55 template<typename Op, typename Functor> 56 ALWAYS_INLINE void forEach(const Functor& func) 57 { 58 auto* metadata = bitwise_cast<typename Op::Metadata*>(get(Op::opcodeID)); 59 auto* end = bitwise_cast<typename Op::Metadata*>(getImpl(Op::opcodeID + 1)); 60 for (; metadata + 1 <= end; ++metadata) 61 func(*metadata); 62 } 63 64 size_t sizeInBytes(); 65 66 void ref() 67 { 68 ++linkingData().refCount; 69 } 70 71 void deref() 72 { 73 unsigned tempRefCount = linkingData().refCount - 1; 74 if (!tempRefCount) { 75 MetadataTable::destroy(this); 76 return; 77 } 78 linkingData().refCount = tempRefCount; 79 } 80 81 unsigned refCount() const 82 { 83 return linkingData().refCount; 84 } 85 86 unsigned hasOneRef() const 87 { 88 return refCount() == 1; 89 } 90 91 private: 92 MetadataTable(UnlinkedMetadataTable&); 93 94 UnlinkedMetadataTable::Offset16* offsetTable16() const { return bitwise_cast<UnlinkedMetadataTable::Offset16*>(this); } 95 UnlinkedMetadataTable::Offset32* offsetTable32() const { return bitwise_cast<UnlinkedMetadataTable::Offset32*>(bitwise_cast<uint8_t*>(this) + UnlinkedMetadataTable::s_offset16TableSize); } 96 97 size_t totalSize() const 98 { 99 return getOffset(UnlinkedMetadataTable::s_offsetTableEntries - 1); 100 } 101 102 UnlinkedMetadataTable::LinkingData& linkingData() const 103 { 104 return *bitwise_cast<UnlinkedMetadataTable::LinkingData*>((bitwise_cast<uint8_t*>(this) - sizeof(UnlinkedMetadataTable::LinkingData))); 105 } 106 107 void* buffer() { return this; } 108 109 bool is32Bit() const { return !offsetTable16()[0]; } 110 111 ALWAYS_INLINE unsigned getOffset(unsigned i) const 112 { 113 unsigned offset = offsetTable16()[i]; 114 if (offset) 115 return offset; 116 return offsetTable32()[i]; 117 } 118 119 ALWAYS_INLINE uint8_t* getImpl(unsigned i) 120 { 121 return bitwise_cast<uint8_t*>(this) + getOffset(i); 122 } 123 124 static void destroy(MetadataTable*); 125 }; 126 127 } // namespace JSC