<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[245669] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/245669">245669</a></dd>
<dt>Author</dt> <dd>ysuzuki@apple.com</dd>
<dt>Date</dt> <dd>2019-05-22 18:47:29 -0700 (Wed, 22 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] UnlinkedMetadataTable's offset table should be small
https://bugs.webkit.org/show_bug.cgi?id=197910

Reviewed by Saam Barati.

In Gmail, we found that massive # of UnlinkedMetadataTable (21979 - 24727) exists. Each UnlinkedMetadataTable takes at least 204 bytes
because of large (unsinged) offset table. This patch reduces the size of offset table by introducing 16bit version offset table.
Previously our code for looking up Metadata is like this.

    offset = offsetTable32[opcode]
    metadata = (SomeOp::Metadata*)table[offset] + id

Instead, we introduce uint16_t offset table. The lookup code becomes like this.

    offset = offsetTable16[opcode]
    if (!offset)
        offset = offsetTable32[opcode]
    metadata = (SomeOp::Metadata*)table[offset] + id

We use 0 offset as a marker to indicate that we have 32bit offset table. This is OK since 0 offset does not appear since all the offsets
included in this table is larger than s_offset16TableSize.

32bit offset table is allocated only when the offset exceeds 16bit range. It means that this will be used only when Metadata table is larger
than almost 64KB. Even in Gmail, such MetadataTable is rare, and additional 32bit offset table size does not matter much in this case since
MetadataTable is already so large.

Based on the # of UnlinkedMetadataTables, this optimization should improve Gmail steady state memory by 2MB.

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/MetadataTable.cpp:
(JSC::MetadataTable::~MetadataTable):
(JSC::MetadataTable::destroy):
* bytecode/MetadataTable.h:
(JSC::MetadataTable::ref):
(JSC::MetadataTable::deref):
(JSC::MetadataTable::buffer):
(JSC::MetadataTable::is32Bit const):
(JSC::MetadataTable::offsetTable16 const):
(JSC::MetadataTable::offsetTable32 const):
(JSC::MetadataTable::totalSize const):
(JSC::MetadataTable::getOffset const):
(JSC::MetadataTable::getImpl):
(JSC::MetadataTable::ref const): Deleted.
(JSC::MetadataTable::deref const): Deleted.
* bytecode/Opcode.cpp:
* bytecode/UnlinkedMetadataTable.cpp: Added.
(JSC::UnlinkedMetadataTable::finalize):
* bytecode/UnlinkedMetadataTable.h:
(JSC::UnlinkedMetadataTable::create):
(JSC::UnlinkedMetadataTable::totalSize const):
(JSC::UnlinkedMetadataTable::offsetTableSize const):
(JSC::UnlinkedMetadataTable::preprocessBuffer const):
(JSC::UnlinkedMetadataTable::buffer const):
(JSC::UnlinkedMetadataTable::offsetTable16 const):
(JSC::UnlinkedMetadataTable::offsetTable32 const):
* bytecode/UnlinkedMetadataTableInlines.h:
(JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
(JSC::UnlinkedMetadataTable::addEntry):
(JSC::UnlinkedMetadataTable::sizeInBytes):
(JSC::UnlinkedMetadataTable::link):
(JSC::UnlinkedMetadataTable::unlink):
(JSC::UnlinkedMetadataTable::finalize): Deleted.
* llint/LowLevelInterpreter.asm:
* runtime/CachedTypes.cpp:
(JSC::CachedMetadataTable::encode):
(JSC::CachedMetadataTable::decode const):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreSourcestxt">trunk/Source/JavaScriptCore/Sources.txt</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeMetadataTablecpp">trunk/Source/JavaScriptCore/bytecode/MetadataTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeMetadataTableh">trunk/Source/JavaScriptCore/bytecode/MetadataTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeOpcodecpp">trunk/Source/JavaScriptCore/bytecode/Opcode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTableh">trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTableInlinesh">trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCachedTypescpp">trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTablecpp">trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -1,5 +1,75 @@
</span><span class="cx"> 2019-05-22  Yusuke Suzuki  <ysuzuki@apple.com>
</span><span class="cx"> 
</span><ins>+        [JSC] UnlinkedMetadataTable's offset table should be small
+        https://bugs.webkit.org/show_bug.cgi?id=197910
+
+        Reviewed by Saam Barati.
+
+        In Gmail, we found that massive # of UnlinkedMetadataTable (21979 - 24727) exists. Each UnlinkedMetadataTable takes at least 204 bytes
+        because of large (unsinged) offset table. This patch reduces the size of offset table by introducing 16bit version offset table.
+        Previously our code for looking up Metadata is like this.
+
+            offset = offsetTable32[opcode]
+            metadata = (SomeOp::Metadata*)table[offset] + id
+
+        Instead, we introduce uint16_t offset table. The lookup code becomes like this.
+
+            offset = offsetTable16[opcode]
+            if (!offset)
+                offset = offsetTable32[opcode]
+            metadata = (SomeOp::Metadata*)table[offset] + id
+
+        We use 0 offset as a marker to indicate that we have 32bit offset table. This is OK since 0 offset does not appear since all the offsets
+        included in this table is larger than s_offset16TableSize.
+
+        32bit offset table is allocated only when the offset exceeds 16bit range. It means that this will be used only when Metadata table is larger
+        than almost 64KB. Even in Gmail, such MetadataTable is rare, and additional 32bit offset table size does not matter much in this case since
+        MetadataTable is already so large.
+
+        Based on the # of UnlinkedMetadataTables, this optimization should improve Gmail steady state memory by 2MB.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * bytecode/MetadataTable.cpp:
+        (JSC::MetadataTable::~MetadataTable):
+        (JSC::MetadataTable::destroy):
+        * bytecode/MetadataTable.h:
+        (JSC::MetadataTable::ref):
+        (JSC::MetadataTable::deref):
+        (JSC::MetadataTable::buffer):
+        (JSC::MetadataTable::is32Bit const):
+        (JSC::MetadataTable::offsetTable16 const):
+        (JSC::MetadataTable::offsetTable32 const):
+        (JSC::MetadataTable::totalSize const):
+        (JSC::MetadataTable::getOffset const):
+        (JSC::MetadataTable::getImpl):
+        (JSC::MetadataTable::ref const): Deleted.
+        (JSC::MetadataTable::deref const): Deleted.
+        * bytecode/Opcode.cpp:
+        * bytecode/UnlinkedMetadataTable.cpp: Added.
+        (JSC::UnlinkedMetadataTable::finalize):
+        * bytecode/UnlinkedMetadataTable.h:
+        (JSC::UnlinkedMetadataTable::create):
+        (JSC::UnlinkedMetadataTable::totalSize const):
+        (JSC::UnlinkedMetadataTable::offsetTableSize const):
+        (JSC::UnlinkedMetadataTable::preprocessBuffer const):
+        (JSC::UnlinkedMetadataTable::buffer const):
+        (JSC::UnlinkedMetadataTable::offsetTable16 const):
+        (JSC::UnlinkedMetadataTable::offsetTable32 const):
+        * bytecode/UnlinkedMetadataTableInlines.h:
+        (JSC::UnlinkedMetadataTable::UnlinkedMetadataTable):
+        (JSC::UnlinkedMetadataTable::addEntry):
+        (JSC::UnlinkedMetadataTable::sizeInBytes):
+        (JSC::UnlinkedMetadataTable::link):
+        (JSC::UnlinkedMetadataTable::unlink):
+        (JSC::UnlinkedMetadataTable::finalize): Deleted.
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CachedTypes.cpp:
+        (JSC::CachedMetadataTable::encode):
+        (JSC::CachedMetadataTable::decode const):
+
+2019-05-22  Yusuke Suzuki  <ysuzuki@apple.com>
+
</ins><span class="cx">         [JSC] ArrayAllocationProfile should not access to butterfly in concurrent compiler
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=197809
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj     2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -4724,6 +4724,7 @@
</span><span class="cx">          E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VM.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
</span><span class="cx">          E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = VM.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
</span><ins>+               E3060128228F978100FAABDF /* UnlinkedMetadataTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkedMetadataTable.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           E30677971B8BC6F5003F87F0 /* ModuleLoader.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = ModuleLoader.js; sourceTree = "<group>"; };
</span><span class="cx">          E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolTableOrScopeDepth.h; sourceTree = "<group>"; };
</span><span class="cx">          E31618101EC5FE080006A218 /* DOMAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMAnnotation.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -8067,6 +8068,7 @@
</span><span class="cx">                          14142E541B7973C000F4BF4B /* UnlinkedFunctionExecutable.cpp */,
</span><span class="cx">                          14142E501B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h */,
</span><span class="cx">                          14AD911C1DCA9FA40014F9FE /* UnlinkedGlobalCodeBlock.h */,
</span><ins>+                               E3060128228F978100FAABDF /* UnlinkedMetadataTable.cpp */,
</ins><span class="cx">                           142D52BE21762958002DB086 /* UnlinkedMetadataTable.h */,
</span><span class="cx">                          142D52BD21762957002DB086 /* UnlinkedMetadataTableInlines.h */,
</span><span class="cx">                          14AD912A1DCAAAB00014F9FE /* UnlinkedModuleProgramCodeBlock.cpp */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Sources.txt (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Sources.txt  2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/Sources.txt     2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -273,6 +273,7 @@
</span><span class="cx"> bytecode/UnlinkedEvalCodeBlock.cpp
</span><span class="cx"> bytecode/UnlinkedFunctionCodeBlock.cpp
</span><span class="cx"> bytecode/UnlinkedFunctionExecutable.cpp
</span><ins>+bytecode/UnlinkedMetadataTable.cpp
</ins><span class="cx"> bytecode/UnlinkedModuleProgramCodeBlock.cpp
</span><span class="cx"> bytecode/UnlinkedProgramCodeBlock.cpp
</span><span class="cx"> bytecode/ValueRecovery.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeMetadataTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/MetadataTable.cpp (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/MetadataTable.cpp   2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/bytecode/MetadataTable.cpp      2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -56,11 +56,16 @@
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = 0; i < NUMBER_OF_BYTECODE_WITH_METADATA; i++)
</span><span class="cx">         getOpcodeType<DeallocTable>(static_cast<OpcodeID>(i), this);
</span><del>-    Ref<UnlinkedMetadataTable> unlinkedMetadata = WTFMove(linkingData().unlinkedMetadata);
</del><span class="cx">     linkingData().~LinkingData();
</span><ins>+}
+
+void MetadataTable::destroy(MetadataTable* table)
+{
+    Ref<UnlinkedMetadataTable> unlinkedMetadata = WTFMove(table->linkingData().unlinkedMetadata);
+    table->~MetadataTable();
</ins><span class="cx">     // Since UnlinkedMetadata::unlink frees the underlying memory of MetadataTable.
</span><span class="cx">     // We need to destroy LinkingData before calling it.
</span><del>-    unlinkedMetadata->unlink(*this);
</del><ins>+    unlinkedMetadata->unlink(*table);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> size_t MetadataTable::sizeInBytes()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeMetadataTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/MetadataTable.h (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/MetadataTable.h     2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/bytecode/MetadataTable.h        2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -63,16 +63,16 @@
</span><span class="cx"> 
</span><span class="cx">     size_t sizeInBytes();
</span><span class="cx"> 
</span><del>-    void ref() const
</del><ins>+    void ref()
</ins><span class="cx">     {
</span><span class="cx">         ++linkingData().refCount;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void deref() const
</del><ins>+    void deref()
</ins><span class="cx">     {
</span><span class="cx">         unsigned tempRefCount = linkingData().refCount - 1;
</span><span class="cx">         if (!tempRefCount) {
</span><del>-            this->~MetadataTable();
</del><ins>+            MetadataTable::destroy(this);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         linkingData().refCount = tempRefCount;
</span><span class="lines">@@ -91,20 +91,37 @@
</span><span class="cx"> private:
</span><span class="cx">     MetadataTable(UnlinkedMetadataTable&);
</span><span class="cx"> 
</span><ins>+    UnlinkedMetadataTable::Offset16* offsetTable16() const { return bitwise_cast<UnlinkedMetadataTable::Offset16*>(this); }
+    UnlinkedMetadataTable::Offset32* offsetTable32() const { return bitwise_cast<UnlinkedMetadataTable::Offset32*>(bitwise_cast<uint8_t*>(this) + UnlinkedMetadataTable::s_offset16TableSize); }
+
+    size_t totalSize() const
+    {
+        return getOffset(UnlinkedMetadataTable::s_offsetTableEntries - 1);
+    }
+
</ins><span class="cx">     UnlinkedMetadataTable::LinkingData& linkingData() const
</span><span class="cx">     {
</span><span class="cx">         return *bitwise_cast<UnlinkedMetadataTable::LinkingData*>((bitwise_cast<uint8_t*>(this) - sizeof(UnlinkedMetadataTable::LinkingData)));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    UnlinkedMetadataTable::Offset* buffer()
</del><ins>+    void* buffer() { return this; }
+
+    bool is32Bit() const { return !offsetTable16()[0]; }
+
+    ALWAYS_INLINE unsigned getOffset(unsigned i) const
</ins><span class="cx">     {
</span><del>-        return bitwise_cast<UnlinkedMetadataTable::Offset*>(this);
</del><ins>+        unsigned offset = offsetTable16()[i];
+        if (offset)
+            return offset;
+        return offsetTable32()[i];
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ALWAYS_INLINE uint8_t* getImpl(unsigned i)
</span><span class="cx">     {
</span><del>-        return bitwise_cast<uint8_t*>(this) + buffer()[i];
</del><ins>+        return bitwise_cast<uint8_t*>(this) + getOffset(i);
</ins><span class="cx">     }
</span><ins>+
+    static void destroy(MetadataTable*);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeOpcodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Opcode.cpp (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Opcode.cpp  2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/bytecode/Opcode.cpp     2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -203,7 +203,7 @@
</span><span class="cx"> 
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-static unsigned metadataSizes[] = {
</del><ins>+static const unsigned metadataSizes[] = {
</ins><span class="cx"> 
</span><span class="cx"> #define METADATA_SIZE(size) size,
</span><span class="cx">     FOR_EACH_BYTECODE_METADATA_SIZE(METADATA_SIZE)
</span><span class="lines">@@ -211,7 +211,7 @@
</span><span class="cx"> 
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-static unsigned metadataAlignments[] = {
</del><ins>+static const unsigned metadataAlignments[] = {
</ins><span class="cx"> 
</span><span class="cx"> #define METADATA_ALIGNMENT(size) size,
</span><span class="cx">     FOR_EACH_BYTECODE_METADATA_ALIGNMENT(METADATA_ALIGNMENT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTablecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp (0 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp                           (rev 0)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.cpp      2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -0,0 +1,88 @@
</span><ins>+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "UnlinkedMetadataTable.h"
+
+#include "BytecodeStructs.h"
+#include "CodeBlock.h"
+#include "JSCInlines.h"
+#include "OpcodeInlines.h"
+#include "UnlinkedMetadataTableInlines.h"
+#include <wtf/FastMalloc.h>
+
+namespace JSC {
+
+#define JSC_ALIGNMENT_CHECK(size) static_assert(size <= UnlinkedMetadataTable::s_maxMetadataAlignment);
+FOR_EACH_BYTECODE_METADATA_ALIGNMENT(JSC_ALIGNMENT_CHECK)
+#undef JSC_ALIGNMENT_CHECK
+
+void UnlinkedMetadataTable::finalize()
+{
+    ASSERT(!m_isFinalized);
+    m_isFinalized = true;
+    if (!m_hasMetadata) {
+        fastFree(m_rawBuffer);
+        m_rawBuffer = nullptr;
+        return;
+    }
+
+    unsigned offset = s_offset16TableSize;
+    {
+        Offset32* buffer = preprocessBuffer();
+        for (unsigned i = 0; i < s_offsetTableEntries - 1; i++) {
+            unsigned numberOfEntries = buffer[i];
+            if (!numberOfEntries) {
+                buffer[i] = offset;
+                continue;
+            }
+            unsigned alignment = metadataAlignment(static_cast<OpcodeID>(i));
+            offset = roundUpToMultipleOf(alignment, offset);
+            ASSERT(alignment <= s_maxMetadataAlignment);
+            buffer[i] = offset;
+            offset += numberOfEntries * metadataSize(static_cast<OpcodeID>(i));
+        }
+        buffer[s_offsetTableEntries - 1] = offset;
+        m_is32Bit = offset > UINT16_MAX;
+    }
+
+    if (m_is32Bit) {
+        m_rawBuffer = reinterpret_cast<uint8_t*>(fastRealloc(m_rawBuffer, s_offset16TableSize + s_offset32TableSize + sizeof(LinkingData)));
+        memmove(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize, m_rawBuffer + sizeof(LinkingData), s_offset32TableSize);
+        memset(m_rawBuffer + sizeof(LinkingData), 0, s_offset16TableSize);
+        Offset32* buffer = bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize);
+        // This adjustment does not break the alignment calculated for metadata in the above loop so long as s_offset32TableSize is rounded with 8.
+        for (unsigned i = 0; i < s_offsetTableEntries; i++)
+            buffer[i] += s_offset32TableSize;
+    } else {
+        Offset32* oldBuffer = bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData));
+        Offset16* buffer = bitwise_cast<Offset16*>(m_rawBuffer + sizeof(LinkingData));
+        for (unsigned i = 0; i < s_offsetTableEntries; i++)
+            buffer[i] = oldBuffer[i];
+        m_rawBuffer = static_cast<uint8_t*>(fastRealloc(m_rawBuffer, s_offset16TableSize + sizeof(LinkingData)));
+    }
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h     2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTable.h        2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -37,8 +37,9 @@
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx">     friend class MetadataTable;
</span><span class="cx">     friend class CachedMetadataTable;
</span><ins>+public:
+    static constexpr unsigned s_maxMetadataAlignment = 8;
</ins><span class="cx"> 
</span><del>-public:
</del><span class="cx">     struct LinkingData {
</span><span class="cx">         Ref<UnlinkedMetadataTable> unlinkedMetadata;
</span><span class="cx">         unsigned refCount;
</span><span class="lines">@@ -61,22 +62,63 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     UnlinkedMetadataTable();
</span><ins>+    UnlinkedMetadataTable(bool is32Bit);
</ins><span class="cx"> 
</span><ins>+    static Ref<UnlinkedMetadataTable> create(bool is32Bit)
+    {
+        return adoptRef(*new UnlinkedMetadataTable(is32Bit));
+    }
+
</ins><span class="cx">     void unlink(MetadataTable&);
</span><span class="cx"> 
</span><span class="cx">     size_t sizeInBytes(MetadataTable&);
</span><span class="cx"> 
</span><del>-    using Offset = unsigned;
</del><ins>+    unsigned totalSize() const
+    {
+        ASSERT(m_isFinalized);
+        if (m_is32Bit)
+            return offsetTable32()[s_offsetTableEntries - 1];
+        return offsetTable16()[s_offsetTableEntries - 1];
+    }
</ins><span class="cx"> 
</span><ins>+    unsigned offsetTableSize() const
+    {
+        ASSERT(m_isFinalized);
+        if (m_is32Bit)
+            return s_offset16TableSize + s_offset32TableSize;
+        return s_offset16TableSize;
+    }
+
+    using Offset32 = uint32_t;
+    using Offset16 = uint16_t;
+
</ins><span class="cx">     static constexpr unsigned s_offsetTableEntries = NUMBER_OF_BYTECODE_WITH_METADATA + 1; // one extra entry for the "end" offset;
</span><del>-    static constexpr unsigned s_offsetTableSize = s_offsetTableEntries * sizeof(UnlinkedMetadataTable::Offset);
</del><span class="cx"> 
</span><del>-    Offset* buffer() const { return bitwise_cast<Offset*>(bitwise_cast<uint8_t*>(m_rawBuffer) + sizeof(LinkingData)); }
</del><ins>+    // Not to break alignment of 32bit offset table, we round up size with sizeof(Offset32).
+    static constexpr unsigned s_offset16TableSize = roundUpToMultipleOf<sizeof(Offset32)>(s_offsetTableEntries * sizeof(Offset16));
+    // Not to break alignment of the metadata calculated based on the alignment of s_offset16TableSize, s_offset32TableSize must be rounded by 8.
+    // 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));
</ins><span class="cx"> 
</span><ins>+    Offset32* preprocessBuffer() const { return bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData)); }
+    void* buffer() const { return m_rawBuffer + sizeof(LinkingData); }
+
+    Offset16* offsetTable16() const
+    {
+        ASSERT(!m_is32Bit);
+        return bitwise_cast<Offset16*>(m_rawBuffer + sizeof(LinkingData));
+    }
+    Offset32* offsetTable32() const
+    {
+        ASSERT(m_is32Bit);
+        return bitwise_cast<Offset32*>(m_rawBuffer + sizeof(LinkingData) + s_offset16TableSize);
+    }
+
</ins><span class="cx">     bool m_hasMetadata : 1;
</span><span class="cx">     bool m_isFinalized : 1;
</span><span class="cx">     bool m_isLinked : 1;
</span><del>-    void* m_rawBuffer;
</del><ins>+    bool m_is32Bit : 1;
+    uint8_t* m_rawBuffer;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeUnlinkedMetadataTableInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h      2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/bytecode/UnlinkedMetadataTableInlines.h 2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -35,10 +35,20 @@
</span><span class="cx">     : m_hasMetadata(false)
</span><span class="cx">     , m_isFinalized(false)
</span><span class="cx">     , m_isLinked(false)
</span><del>-    , m_rawBuffer(fastZeroedMalloc(sizeof(LinkingData) + s_offsetTableSize))
</del><ins>+    , m_is32Bit(false)
+    , m_rawBuffer(static_cast<uint8_t*>(fastZeroedMalloc(sizeof(LinkingData) + s_offset32TableSize)))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE UnlinkedMetadataTable::UnlinkedMetadataTable(bool is32Bit)
+    : m_hasMetadata(false)
+    , m_isFinalized(false)
+    , m_isLinked(false)
+    , m_is32Bit(is32Bit)
+    , m_rawBuffer(static_cast<uint8_t*>(fastZeroedMalloc(sizeof(LinkingData) + (is32Bit ? s_offset16TableSize + s_offset32TableSize : s_offset16TableSize))))
+{
+}
+
</ins><span class="cx"> ALWAYS_INLINE UnlinkedMetadataTable::~UnlinkedMetadataTable()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_isLinked);
</span><span class="lines">@@ -50,7 +60,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_isFinalized && opcodeID < s_offsetTableEntries - 1);
</span><span class="cx">     m_hasMetadata = true;
</span><del>-    return buffer()[opcodeID]++;
</del><ins>+    return preprocessBuffer()[opcodeID]++;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE size_t UnlinkedMetadataTable::sizeInBytes()
</span><span class="lines">@@ -58,7 +68,9 @@
</span><span class="cx">     if (m_isFinalized && !m_hasMetadata)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    return s_offsetTableSize;
</del><ins>+    if (m_is32Bit)
+        return s_offset16TableSize + s_offset32TableSize;
+    return s_offset16TableSize;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE size_t UnlinkedMetadataTable::sizeInBytes(MetadataTable& metadataTable)
</span><span class="lines">@@ -67,38 +79,16 @@
</span><span class="cx"> 
</span><span class="cx">     // In this case, we return the size of the table minus the offset table,
</span><span class="cx">     // which was already accounted for in the UnlinkedCodeBlock.
</span><ins>+    size_t result = totalSize();
</ins><span class="cx">     if (metadataTable.buffer() == buffer()) {
</span><span class="cx">         ASSERT(m_isLinked);
</span><del>-        return buffer()[s_offsetTableEntries - 1] - s_offsetTableSize;
</del><ins>+        if (m_is32Bit)
+            return result - (s_offset16TableSize + s_offset32TableSize);
+        return result - s_offset16TableSize;
</ins><span class="cx">     }
</span><del>-
-    return metadataTable.buffer()[s_offsetTableEntries - 1];
</del><ins>+    return result;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE void UnlinkedMetadataTable::finalize()
-{
-    ASSERT(!m_isFinalized);
-    m_isFinalized = true;
-    if (!m_hasMetadata) {
-        fastFree(m_rawBuffer);
-        m_rawBuffer = nullptr;
-        return;
-    }
-
-    unsigned offset = s_offsetTableSize;
-    for (unsigned i = 0; i < s_offsetTableEntries - 1; i++) {
-        unsigned numberOfEntries = buffer()[i];
-
-        if (numberOfEntries > 0) {
-            offset = roundUpToMultipleOf(metadataAlignment(static_cast<OpcodeID>(i)), offset);
-            buffer()[i] = offset;
-            offset += numberOfEntries * metadataSize(static_cast<OpcodeID>(i));
-        } else
-            buffer()[i] = offset;
-    }
-    buffer()[s_offsetTableEntries - 1] = offset;
-}
-
</del><span class="cx"> ALWAYS_INLINE RefPtr<MetadataTable> UnlinkedMetadataTable::link()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_isFinalized);
</span><span class="lines">@@ -106,7 +96,8 @@
</span><span class="cx">     if (!m_hasMetadata)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    unsigned totalSize = buffer()[s_offsetTableEntries - 1];
</del><ins>+    unsigned totalSize = this->totalSize();
+    unsigned offsetTableSize = this->offsetTableSize();
</ins><span class="cx">     uint8_t* buffer;
</span><span class="cx">     if (!m_isLinked) {
</span><span class="cx">         m_isLinked = true;
</span><span class="lines">@@ -113,9 +104,9 @@
</span><span class="cx">         m_rawBuffer = buffer = reinterpret_cast<uint8_t*>(fastRealloc(m_rawBuffer, sizeof(LinkingData) + totalSize));
</span><span class="cx">     } else {
</span><span class="cx">         buffer = reinterpret_cast<uint8_t*>(fastMalloc(sizeof(LinkingData) + totalSize));
</span><del>-        memcpy(buffer, m_rawBuffer, sizeof(LinkingData) + s_offsetTableSize);
</del><ins>+        memcpy(buffer, m_rawBuffer, sizeof(LinkingData) + offsetTableSize);
</ins><span class="cx">     }
</span><del>-    memset(buffer + sizeof(LinkingData) + s_offsetTableSize, 0, totalSize - s_offsetTableSize);
</del><ins>+    memset(buffer + sizeof(LinkingData) + offsetTableSize, 0, totalSize - offsetTableSize);
</ins><span class="cx">     return adoptRef(*new (buffer + sizeof(LinkingData)) MetadataTable(*this));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -128,7 +119,7 @@
</span><span class="cx">     if (metadataTable.buffer() == buffer()) {
</span><span class="cx">         ASSERT(m_isLinked);
</span><span class="cx">         m_isLinked = false;
</span><del>-        m_rawBuffer = fastRealloc(m_rawBuffer, sizeof(LinkingData) + s_offsetTableSize);
</del><ins>+        m_rawBuffer = static_cast<uint8_t*>(fastRealloc(m_rawBuffer, sizeof(LinkingData) + offsetTableSize()));
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     fastFree(&metadataTable.linkingData());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm   2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -181,6 +181,9 @@
</span><span class="cx"> const FirstArgumentOffset = ThisArgumentOffset + SlotSize
</span><span class="cx"> const CallFrameHeaderSize = ThisArgumentOffset
</span><span class="cx"> 
</span><ins>+const MetadataOffsetTable16Offset = 0
+const MetadataOffsetTable32Offset = constexpr UnlinkedMetadataTable::s_offset16TableSize
+
</ins><span class="cx"> # Some value representation constants.
</span><span class="cx"> if JSVALUE64
</span><span class="cx">     const TagBitTypeOther = constexpr TagBitTypeOther
</span><span class="lines">@@ -336,7 +339,10 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro metadata(size, opcode, dst, scratch)
</span><del>-    loadi constexpr %opcode%::opcodeID * 4[metadataTable], dst # offset = metadataTable<unsigned*>[opcodeID]
</del><ins>+    loadh (constexpr %opcode%::opcodeID * 2 + MetadataOffsetTable16Offset)[metadataTable], dst # offset = metadataTable<uint16_t*>[opcodeID]
+    btinz dst, .setUpOffset
+    loadi (constexpr %opcode%::opcodeID * 4 + MetadataOffsetTable32Offset)[metadataTable], dst # offset = metadataTable<uint32_t*>[opcodeID]
+.setUpOffset:
</ins><span class="cx">     getu(size, opcode, m_metadataID, scratch) # scratch = bytecode.m_metadataID
</span><span class="cx">     muli sizeof %opcode%::Metadata, scratch # scratch *= sizeof(Op::Metadata)
</span><span class="cx">     addi scratch, dst # offset += scratch
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCachedTypescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp (245668 => 245669)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp      2019-05-23 01:39:47 UTC (rev 245668)
+++ trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp 2019-05-23 01:47:29 UTC (rev 245669)
</span><span class="lines">@@ -1348,23 +1348,35 @@
</span><span class="cx">         m_hasMetadata = metadataTable.m_hasMetadata;
</span><span class="cx">         if (!m_hasMetadata)
</span><span class="cx">             return;
</span><del>-        for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
-            m_metadata[i] = metadataTable.buffer()[i];
</del><ins>+        m_is32Bit = metadataTable.m_is32Bit;
+        if (m_is32Bit) {
+            for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
+                m_metadata[i] = metadataTable.offsetTable32()[i];
+        } else {
+            for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
+                m_metadata[i] = metadataTable.offsetTable16()[i];
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Ref<UnlinkedMetadataTable> decode(Decoder&) const
</span><span class="cx">     {
</span><del>-        Ref<UnlinkedMetadataTable> metadataTable = UnlinkedMetadataTable::create();
</del><ins>+        Ref<UnlinkedMetadataTable> metadataTable = UnlinkedMetadataTable::create(m_is32Bit);
</ins><span class="cx">         metadataTable->m_isFinalized = true;
</span><span class="cx">         metadataTable->m_isLinked = false;
</span><span class="cx">         metadataTable->m_hasMetadata = m_hasMetadata;
</span><del>-        for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
-            metadataTable->buffer()[i] = m_metadata[i];
</del><ins>+        if (m_is32Bit) {
+            for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
+                metadataTable->offsetTable32()[i] = m_metadata[i];
+        } else {
+            for (unsigned i = UnlinkedMetadataTable::s_offsetTableEntries; i--;)
+                metadataTable->offsetTable16()[i] = m_metadata[i];
+        }
</ins><span class="cx">         return metadataTable;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     bool m_hasMetadata;
</span><ins>+    bool m_is32Bit;
</ins><span class="cx">     std::array<unsigned, UnlinkedMetadataTable::s_offsetTableEntries> m_metadata;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>