<!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>[242469] releases/WebKitGTK/webkit-2.24/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/242469">242469</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2019-03-05 09:20:48 -0800 (Tue, 05 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/242096">r242096</a> - [Re-landing] Add some randomness into the StructureID.
https://bugs.webkit.org/show_bug.cgi?id=194989
<rdar://problem/47975563>

Reviewed by Yusuke Suzuki.

1. On 64-bit, the StructureID will now be encoded as:

    ----------------------------------------------------------------
    | 1 Nuke Bit | 24 StructureIDTable index bits | 7 entropy bits |
    ----------------------------------------------------------------

   The entropy bits are chosen at random and assigned when a StructureID is
   allocated.

2. Instead of Structure pointers, the StructureIDTable will now contain
   encodedStructureBits, which is encoded as such:

    ----------------------------------------------------------------
    | 7 entropy bits |                   57 structure pointer bits |
    ----------------------------------------------------------------

   The entropy bits here are the same 7 bits used in the encoding of the
   StructureID for this structure entry in the StructureIDTable.

3. Retrieval of the structure pointer given a StructureID is now computed as
   follows:

        index = structureID >> 7; // with arithmetic shift.
        encodedStructureBits = structureIDTable[index];
        structure = encodedStructureBits ^ (structureID << 57);

    We use an arithmetic shift for the right shift because that will preserve
    the nuke bit in the high bit of the index if the StructureID was not
    decontaminated before use as expected.

4. Remove unused function loadArgumentWithSpecificClass() in SpecializedThunkJIT.

5. Define StructureIDTable::m_size to be the number of allocated StructureIDs
   instead of always being the same as m_capacity.

6. Change StructureIDTable::s_unusedID's value to 0.

   Its previous value of unusedPointer i.e. 0xd1e7beef, does not make sense for
   StructureID on 64-bit.  Also, there was never any code that initializes unused
   IDs to the s_unusedID.  The only meaningful value for s_unusedID is 0, which
   is the ID we'll get when the freelist is empty, prompting a resize of the
   structureIDTable.

This patch appears to be perf neutral on JetStream 2 run via the cli on a
11" MacBook Air, 13" MacBook Pro, iPhone 6S, and iPhone XR.

* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::loadStructure):
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::appendJSCellOrAuxiliary):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::emitLoadStructure):
* jit/AssemblyHelpers.h:
* jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::loadArgumentWithSpecificClass): Deleted.
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/StructureIDTable.cpp:
(JSC::StructureIDTable::StructureIDTable):
(JSC::StructureIDTable::makeFreeListFromRange):
(JSC::StructureIDTable::resize):
(JSC::StructureIDTable::allocateID):
(JSC::StructureIDTable::deallocateID):
* runtime/StructureIDTable.h:
(JSC::StructureIDTable::decode):
(JSC::StructureIDTable::encode):
(JSC::StructureIDTable::get):
(JSC::StructureIDTable::isValid):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCoreftlFTLLowerDFGToB3cpp">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCoreheapSlotVisitorcpp">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/heap/SlotVisitor.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCorejitAssemblyHelperscpp">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCorejitAssemblyHelpersh">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.h</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCorejitSpecializedThunkJITh">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/SpecializedThunkJIT.h</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCorellintLowLevelInterpreterasm">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCorellintLowLevelInterpreter64asm">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCoreruntimeStructureIDTablecpp">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceJavaScriptCoreruntimeStructureIDTableh">releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ChangeLog (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ChangeLog   2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ChangeLog      2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -1,3 +1,80 @@
</span><ins>+2019-02-26  Mark Lam  <mark.lam@apple.com>
+
+        [Re-landing] Add some randomness into the StructureID.
+        https://bugs.webkit.org/show_bug.cgi?id=194989
+        <rdar://problem/47975563>
+
+        Reviewed by Yusuke Suzuki.
+
+        1. On 64-bit, the StructureID will now be encoded as:
+
+            ----------------------------------------------------------------
+            | 1 Nuke Bit | 24 StructureIDTable index bits | 7 entropy bits |
+            ----------------------------------------------------------------
+
+           The entropy bits are chosen at random and assigned when a StructureID is
+           allocated.
+
+        2. Instead of Structure pointers, the StructureIDTable will now contain
+           encodedStructureBits, which is encoded as such:
+
+            ----------------------------------------------------------------
+            | 7 entropy bits |                   57 structure pointer bits |
+            ----------------------------------------------------------------
+
+           The entropy bits here are the same 7 bits used in the encoding of the
+           StructureID for this structure entry in the StructureIDTable.
+
+        3. Retrieval of the structure pointer given a StructureID is now computed as
+           follows:
+
+                index = structureID >> 7; // with arithmetic shift.
+                encodedStructureBits = structureIDTable[index];
+                structure = encodedStructureBits ^ (structureID << 57);
+
+            We use an arithmetic shift for the right shift because that will preserve
+            the nuke bit in the high bit of the index if the StructureID was not
+            decontaminated before use as expected.
+
+        4. Remove unused function loadArgumentWithSpecificClass() in SpecializedThunkJIT.
+
+        5. Define StructureIDTable::m_size to be the number of allocated StructureIDs
+           instead of always being the same as m_capacity.
+
+        6. Change StructureIDTable::s_unusedID's value to 0.
+
+           Its previous value of unusedPointer i.e. 0xd1e7beef, does not make sense for
+           StructureID on 64-bit.  Also, there was never any code that initializes unused
+           IDs to the s_unusedID.  The only meaningful value for s_unusedID is 0, which
+           is the ID we'll get when the freelist is empty, prompting a resize of the
+           structureIDTable.
+
+        This patch appears to be perf neutral on JetStream 2 run via the cli on a
+        11" MacBook Air, 13" MacBook Pro, iPhone 6S, and iPhone XR.
+
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::loadStructure):
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::appendJSCellOrAuxiliary):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::emitLoadStructure):
+        * jit/AssemblyHelpers.h:
+        * jit/SpecializedThunkJIT.h:
+        (JSC::SpecializedThunkJIT::loadArgumentWithSpecificClass): Deleted.
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/StructureIDTable.cpp:
+        (JSC::StructureIDTable::StructureIDTable):
+        (JSC::StructureIDTable::makeFreeListFromRange):
+        (JSC::StructureIDTable::resize):
+        (JSC::StructureIDTable::allocateID):
+        (JSC::StructureIDTable::deallocateID):
+        * runtime/StructureIDTable.h:
+        (JSC::StructureIDTable::decode):
+        (JSC::StructureIDTable::encode):
+        (JSC::StructureIDTable::get):
+        (JSC::StructureIDTable::isValid):
+
</ins><span class="cx"> 2019-02-26  Guillaume Emont  <guijemont@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [JSC] Fix compilation on 32-bit platforms after r242071
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp     2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -16944,12 +16944,13 @@
</span><span class="cx"> 
</span><span class="cx">     LValue loadStructure(LValue value)
</span><span class="cx">     {
</span><del>-        LValue tableIndex = m_out.load32(value, m_heaps.JSCell_structureID);
-        LValue tableBase = m_out.loadPtr(
-            m_out.absolute(vm().heap.structureIDTable().base()));
-        TypedPointer address = m_out.baseIndex(
-            m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex));
-        return m_out.loadPtr(address);
</del><ins>+        LValue structureID = m_out.load32(value, m_heaps.JSCell_structureID);
+        LValue tableBase = m_out.loadPtr(m_out.absolute(vm().heap.structureIDTable().base()));
+        LValue tableIndex = m_out.aShr(structureID, m_out.constInt32(StructureIDTable::s_numberOfEntropyBits));
+        LValue entropyBits = m_out.shl(m_out.zeroExtPtr(structureID), m_out.constInt32(StructureIDTable::s_entropyBitsShiftForStructurePointer));
+        TypedPointer address = m_out.baseIndex(m_heaps.structureTable, tableBase, m_out.zeroExtPtr(tableIndex));
+        LValue encodedStructureBits = m_out.loadPtr(address);
+        return m_out.bitXor(encodedStructureBits, entropyBits);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     LValue weakPointer(JSCell* pointer)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCoreheapSlotVisitorcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/heap/SlotVisitor.cpp (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/heap/SlotVisitor.cpp        2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/heap/SlotVisitor.cpp   2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -198,8 +198,8 @@
</span><span class="cx">         
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">         // This detects the worst of the badness.
</span><del>-        if (structureID >= heap()->structureIDTable().size())
-            die("GC scan found corrupt object: structureID is out of bounds!\n");
</del><ins>+        if (!heap()->structureIDTable().isValid(structureID))
+            die("GC scan found corrupt object: structureID is invalid!\n");
</ins><span class="cx"> #endif
</span><span class="cx">     };
</span><span class="cx">     
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCorejitAssemblyHelperscpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.cpp (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.cpp     2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.cpp        2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -369,15 +369,30 @@
</span><span class="cx"> void AssemblyHelpers::emitLoadStructure(VM& vm, RegisterID source, RegisterID dest, RegisterID scratch)
</span><span class="cx"> {
</span><span class="cx"> #if USE(JSVALUE64)
</span><ins>+#if CPU(ARM64)
+    RegisterID scratch2 = dataTempRegister;
+#elif CPU(X86_64)
+    RegisterID scratch2 = scratchRegister();
+#else
+#error "Unsupported cpu"
+#endif
+
</ins><span class="cx">     ASSERT(dest != scratch);
</span><del>-    load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), dest);
</del><ins>+    ASSERT(dest != scratch2);
+    ASSERT(scratch != scratch2);
+
+    load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), scratch2);
</ins><span class="cx">     loadPtr(vm.heap.structureIDTable().base(), scratch);
</span><ins>+    rshift32(scratch2, TrustedImm32(StructureIDTable::s_numberOfEntropyBits), dest);
</ins><span class="cx">     loadPtr(MacroAssembler::BaseIndex(scratch, dest, MacroAssembler::TimesEight), dest);
</span><del>-#else
</del><ins>+    lshiftPtr(TrustedImm32(StructureIDTable::s_entropyBitsShiftForStructurePointer), scratch2);
+    xorPtr(scratch2, dest);
+#else // not USE(JSVALUE64)
</ins><span class="cx">     UNUSED_PARAM(scratch);
</span><ins>+    UNUSED_PARAM(scratch2);
</ins><span class="cx">     UNUSED_PARAM(vm);
</span><span class="cx">     loadPtr(MacroAssembler::Address(source, JSCell::structureIDOffset()), dest);
</span><del>-#endif
</del><ins>+#endif // not USE(JSVALUE64)
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AssemblyHelpers::makeSpaceOnStackForCCall()
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCorejitAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.h (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.h       2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/AssemblyHelpers.h  2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -1782,7 +1782,7 @@
</span><span class="cx">         storePtr(TrustedImmPtr(nullptr), Address(resultGPR, JSObject::butterflyOffset()));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JumpList branchIfValue(VM&, JSValueRegs value, GPRReg scratch, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg, FPRReg, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject*, bool negateResult);
</del><ins>+    JumpList branchIfValue(VM&, JSValueRegs, GPRReg scratch, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg, FPRReg, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject*, bool negateResult);
</ins><span class="cx">     JumpList branchIfTruthy(VM& vm, JSValueRegs value, GPRReg scratch, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg scratchFPR0, FPRReg scratchFPR1, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject* globalObject)
</span><span class="cx">     {
</span><span class="cx">         return branchIfValue(vm, value, scratch, scratchIfShouldCheckMasqueradesAsUndefined, scratchFPR0, scratchFPR1, shouldCheckMasqueradesAsUndefined, globalObject, false);
</span><span class="lines">@@ -1791,7 +1791,7 @@
</span><span class="cx">     {
</span><span class="cx">         return branchIfValue(vm, value, scratch, scratchIfShouldCheckMasqueradesAsUndefined, scratchFPR0, scratchFPR1, shouldCheckMasqueradesAsUndefined, globalObject, true);
</span><span class="cx">     }
</span><del>-    void emitConvertValueToBoolean(VM&, JSValueRegs value, GPRReg result, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg, FPRReg, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject*, bool negateResult = false);
</del><ins>+    void emitConvertValueToBoolean(VM&, JSValueRegs, GPRReg result, GPRReg scratchIfShouldCheckMasqueradesAsUndefined, FPRReg, FPRReg, bool shouldCheckMasqueradesAsUndefined, JSGlobalObject*, bool negateResult = false);
</ins><span class="cx">     
</span><span class="cx">     template<typename ClassType>
</span><span class="cx">     void emitAllocateDestructibleObject(VM& vm, GPRReg resultGPR, Structure* structure, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCorejitSpecializedThunkJITh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/SpecializedThunkJIT.h (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/SpecializedThunkJIT.h   2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/jit/SpecializedThunkJIT.h      2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -71,15 +71,6 @@
</span><span class="cx">             m_failures.append(branchIfNotString(dst));
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        void loadArgumentWithSpecificClass(const ClassInfo* classInfo, int argument, RegisterID dst, RegisterID scratch)
-        {
-            loadCellArgument(argument, dst);
-            emitLoadStructure(*vm(), dst, scratch, dst);
-            appendFailure(branchPtr(NotEqual, Address(scratch, Structure::classInfoOffset()), TrustedImmPtr(PoisonedClassInfoPtr(classInfo).bits())));
-            // We have to reload the argument since emitLoadStructure clobbered it.
-            loadCellArgument(argument, dst);
-        }
-        
</del><span class="cx">         void loadInt32Argument(int argument, RegisterID dst, Jump& failTarget)
</span><span class="cx">         {
</span><span class="cx">             unsigned src = CallFrame::argumentOffset(argument);
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter.asm       2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter.asm  2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -204,6 +204,11 @@
</span><span class="cx">     const LowestTag = constexpr JSValue::LowestTag
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+if JSVALUE64
+    const NumberOfStructureIDEntropyBits = constexpr StructureIDTable::s_numberOfEntropyBits
+    const StructureEntropyBitsShift = constexpr StructureIDTable::s_entropyBitsShiftForStructurePointer
+end
+
</ins><span class="cx"> const CallOpCodeSize = constexpr op_call_length
</span><span class="cx"> 
</span><span class="cx"> const maxFrameExtentForSlowPathCall = constexpr maxFrameExtentForSlowPathCall
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm     2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -530,16 +530,20 @@
</span><span class="cx">         end)
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro structureIDToStructureWithScratch(structureIDThenStructure, scratch)
</del><ins>+macro structureIDToStructureWithScratch(structureIDThenStructure, scratch, scratch2)
</ins><span class="cx">     loadp CodeBlock[cfr], scratch
</span><ins>+    move structureIDThenStructure, scratch2
</ins><span class="cx">     loadp CodeBlock::m_vm[scratch], scratch
</span><ins>+    rshifti NumberOfStructureIDEntropyBits, scratch2
</ins><span class="cx">     loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch
</span><del>-    loadp [scratch, structureIDThenStructure, PtrSize], structureIDThenStructure
</del><ins>+    loadp [scratch, scratch2, PtrSize], scratch2
+    lshiftp StructureEntropyBitsShift, structureIDThenStructure
+    xorp scratch2, structureIDThenStructure
</ins><span class="cx"> end
</span><span class="cx"> 
</span><del>-macro loadStructureWithScratch(cell, structure, scratch)
</del><ins>+macro loadStructureWithScratch(cell, structure, scratch, scratch2)
</ins><span class="cx">     loadi JSCell::m_structureID[cell], structure
</span><del>-    structureIDToStructureWithScratch(structure, scratch)
</del><ins>+    structureIDToStructureWithScratch(structure, scratch, scratch2)
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> # Entrypoints into the interpreter.
</span><span class="lines">@@ -694,7 +698,7 @@
</span><span class="cx">     loadq [cfr, t0, 8], t0
</span><span class="cx">     btqnz t0, tagMask, .opToThisSlow
</span><span class="cx">     bbneq JSCell::m_type[t0], FinalObjectType, .opToThisSlow
</span><del>-    loadStructureWithScratch(t0, t1, t2)
</del><ins>+    loadStructureWithScratch(t0, t1, t2, t3)
</ins><span class="cx">     metadata(t2, t3)
</span><span class="cx">     loadp OpToThis::Metadata::m_cachedStructure[t2], t2
</span><span class="cx">     bpneq t1, t2, .opToThisSlow
</span><span class="lines">@@ -764,7 +768,7 @@
</span><span class="cx">         move 0, t0
</span><span class="cx">         jmp .done
</span><span class="cx">     .masqueradesAsUndefined:
</span><del>-        loadStructureWithScratch(t0, t2, t1)
</del><ins>+        loadStructureWithScratch(t0, t2, t1, t3)
</ins><span class="cx">         loadp CodeBlock[cfr], t0
</span><span class="cx">         loadp CodeBlock::m_globalObject[t0], t0
</span><span class="cx">         cpeq Structure::m_globalObject[t2], t0, t0
</span><span class="lines">@@ -1182,7 +1186,7 @@
</span><span class="cx">     move ValueFalse, t1
</span><span class="cx">     return(t1)
</span><span class="cx"> .masqueradesAsUndefined:
</span><del>-    loadStructureWithScratch(t0, t3, t1)
</del><ins>+    loadStructureWithScratch(t0, t3, t1, t2)
</ins><span class="cx">     loadp CodeBlock[cfr], t1
</span><span class="cx">     loadp CodeBlock::m_globalObject[t1], t1
</span><span class="cx">     cpeq Structure::m_globalObject[t3], t1, t0
</span><span class="lines">@@ -1353,7 +1357,7 @@
</span><span class="cx">     loadp OpPutById::Metadata::m_structureChain[t5], t3
</span><span class="cx">     btpz t3, .opPutByIdTransitionDirect
</span><span class="cx"> 
</span><del>-    structureIDToStructureWithScratch(t2, t1)
</del><ins>+    structureIDToStructureWithScratch(t2, t1, t3)
</ins><span class="cx"> 
</span><span class="cx">     # reload the StructureChain since we used t3 as a scratch above
</span><span class="cx">     loadp OpPutById::Metadata::m_structureChain[t5], t3
</span><span class="lines">@@ -1691,7 +1695,7 @@
</span><span class="cx">         assertNotConstant(size, t0)
</span><span class="cx">         loadq [cfr, t0, 8], t0
</span><span class="cx">         btqnz t0, tagMask, .immediate
</span><del>-        loadStructureWithScratch(t0, t2, t1)
</del><ins>+        loadStructureWithScratch(t0, t2, t1, t3)
</ins><span class="cx">         cellHandler(t2, JSCell::m_flags[t0], .target)
</span><span class="cx">         dispatch()
</span><span class="cx"> 
</span><span class="lines">@@ -2214,7 +2218,7 @@
</span><span class="cx"> macro loadWithStructureCheck(opcodeStruct, get, slowPath)
</span><span class="cx">     get(m_scope, t0)
</span><span class="cx">     loadq [cfr, t0, 8], t0
</span><del>-    loadStructureWithScratch(t0, t2, t1)
</del><ins>+    loadStructureWithScratch(t0, t2, t1, t3)
</ins><span class="cx">     loadp %opcodeStruct%::Metadata::m_structure[t5], t1
</span><span class="cx">     bpneq t2, t1, slowPath
</span><span class="cx"> end
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCoreruntimeStructureIDTablecpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.cpp (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.cpp        2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.cpp   2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -35,14 +35,14 @@
</span><span class="cx"> 
</span><span class="cx"> StructureIDTable::StructureIDTable()
</span><span class="cx">     : m_table(makeUniqueArray<StructureOrOffset>(s_initialSize))
</span><ins>+    , m_size(1)
</ins><span class="cx">     , m_capacity(s_initialSize)
</span><span class="cx"> {
</span><span class="cx">     // We pre-allocate the first offset so that the null Structure
</span><span class="cx">     // can still be represented as the StructureID '0'.
</span><del>-    table()[0].structure = nullptr;
</del><ins>+    table()[0].encodedStructureBits = 0;
</ins><span class="cx"> 
</span><span class="cx">     makeFreeListFromRange(1, m_capacity - 1);
</span><del>-    ASSERT(m_size == m_capacity);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StructureIDTable::makeFreeListFromRange(uint32_t first, uint32_t last)
</span><span class="lines">@@ -95,11 +95,13 @@
</span><span class="cx"> 
</span><span class="cx">     m_firstFreeOffset = head;
</span><span class="cx">     m_lastFreeOffset = tail;
</span><del>-    m_size = m_capacity;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StructureIDTable::resize(size_t newCapacity)
</span><span class="cx"> {
</span><ins>+    if (newCapacity > s_maximumNumberOfStructures)
+        newCapacity = s_maximumNumberOfStructures;
+
</ins><span class="cx">     // Create the new table.
</span><span class="cx">     auto newTable = makeUniqueArray<StructureOrOffset>(newCapacity);
</span><span class="cx"> 
</span><span class="lines">@@ -128,22 +130,35 @@
</span><span class="cx"> 
</span><span class="cx"> StructureID StructureIDTable::allocateID(Structure* structure)
</span><span class="cx"> {
</span><del>-    if (!m_firstFreeOffset) {
-        RELEASE_ASSERT(m_capacity <= UINT_MAX);
-        if (m_size == m_capacity)
-            resize(m_capacity * 2);
</del><ins>+    if (UNLIKELY(!m_firstFreeOffset)) {
+        RELEASE_ASSERT(m_capacity <= s_maximumNumberOfStructures);
</ins><span class="cx">         ASSERT(m_size == m_capacity);
</span><ins>+        resize(m_capacity * 2);
+        ASSERT(m_size < m_capacity);
</ins><span class="cx">         ASSERT(m_firstFreeOffset);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_firstFreeOffset != s_unusedID);
</span><span class="cx"> 
</span><del>-    StructureID result = m_firstFreeOffset;
</del><ins>+    // entropyBits must not be zero. This ensures that if a corrupted
+    // structureID is encountered (with incorrect entropyBits), the decoded
+    // structure pointer for that ID will be always be a bad pointer with
+    // high bits set.
+    constexpr uint32_t entropyBitsMask = (1 << s_numberOfEntropyBits) - 1;
+    uint32_t entropyBits = m_weakRandom.getUint32() & entropyBitsMask;
+    if (UNLIKELY(!entropyBits)) {
+        constexpr uint32_t numberOfValuesToPickFrom = entropyBitsMask;
+        entropyBits = (m_weakRandom.getUint32() % numberOfValuesToPickFrom) + 1;
+    }
+
+    uint32_t structureIndex = m_firstFreeOffset;
</ins><span class="cx">     m_firstFreeOffset = table()[m_firstFreeOffset].offset;
</span><span class="cx">     if (!m_firstFreeOffset)
</span><span class="cx">         m_lastFreeOffset = 0;
</span><span class="cx"> 
</span><del>-    table()[result].structure = structure;
</del><ins>+    StructureID result = (structureIndex << s_numberOfEntropyBits) | entropyBits;
+    table()[structureIndex].encodedStructureBits = encode(structure, result);
+    m_size++;
</ins><span class="cx">     ASSERT(!isNuked(result));
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -151,23 +166,25 @@
</span><span class="cx"> void StructureIDTable::deallocateID(Structure* structure, StructureID structureID)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(structureID != s_unusedID);
</span><del>-    RELEASE_ASSERT(table()[structureID].structure == structure);
-
</del><ins>+    uint32_t structureIndex = structureID >> s_numberOfEntropyBits;
+    ASSERT(structureIndex && structureIndex < s_maximumNumberOfStructures);
+    RELEASE_ASSERT(table()[structureIndex].encodedStructureBits == encode(structure, structureID));
+    m_size--;
</ins><span class="cx">     if (!m_firstFreeOffset) {
</span><del>-        table()[structureID].offset = 0;
-        m_firstFreeOffset = structureID;
-        m_lastFreeOffset = structureID;
</del><ins>+        table()[structureIndex].offset = 0;
+        m_firstFreeOffset = structureIndex;
+        m_lastFreeOffset = structureIndex;
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool insertAtHead = m_weakRandom.getUint32() & 1;
</span><span class="cx">     if (insertAtHead) {
</span><del>-        table()[structureID].offset = m_firstFreeOffset;
-        m_firstFreeOffset = structureID;
</del><ins>+        table()[structureIndex].offset = m_firstFreeOffset;
+        m_firstFreeOffset = structureIndex;
</ins><span class="cx">     } else {
</span><del>-        table()[structureID].offset = 0;
-        table()[m_lastFreeOffset].offset = structureID;
-        m_lastFreeOffset = structureID;
</del><ins>+        table()[structureIndex].offset = 0;
+        table()[m_lastFreeOffset].offset = structureIndex;
+        m_lastFreeOffset = structureIndex;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceJavaScriptCoreruntimeStructureIDTableh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.h (242468 => 242469)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.h  2019-03-05 17:20:36 UTC (rev 242468)
+++ releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/runtime/StructureIDTable.h     2019-03-05 17:20:48 UTC (rev 242469)
</span><span class="lines">@@ -82,6 +82,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx"> 
</span><ins>+using EncodedStructureBits = uintptr_t;
+
</ins><span class="cx"> class StructureIDTable {
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> public:
</span><span class="lines">@@ -89,6 +91,7 @@
</span><span class="cx"> 
</span><span class="cx">     void** base() { return reinterpret_cast<void**>(&m_table); }
</span><span class="cx"> 
</span><ins>+    bool isValid(StructureID);
</ins><span class="cx">     Structure* get(StructureID);
</span><span class="cx">     void deallocateID(Structure*, StructureID);
</span><span class="cx">     StructureID allocateID(Structure*);
</span><span class="lines">@@ -104,12 +107,14 @@
</span><span class="cx">     union StructureOrOffset {
</span><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span><del>-        Structure* structure;
</del><ins>+        EncodedStructureBits encodedStructureBits;
</ins><span class="cx">         StructureID offset;
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     StructureOrOffset* table() const { return m_table.get(); }
</span><del>-    
</del><ins>+    static Structure* decode(EncodedStructureBits, StructureID);
+    static EncodedStructureBits encode(Structure*, StructureID);
+
</ins><span class="cx">     static constexpr size_t s_initialSize = 512;
</span><span class="cx"> 
</span><span class="cx">     Vector<UniqueArray<StructureOrOffset>> m_oldTables;
</span><span class="lines">@@ -123,17 +128,50 @@
</span><span class="cx"> 
</span><span class="cx">     WeakRandom m_weakRandom;
</span><span class="cx"> 
</span><del>-    static const StructureID s_unusedID = unusedPointer;
</del><ins>+    static constexpr StructureID s_unusedID = 0;
+
+public:
+    static constexpr uint32_t s_numberOfNukeBits = 1;
+    static constexpr uint32_t s_numberOfEntropyBits = 7;
+    static constexpr uint32_t s_entropyBitsShiftForStructurePointer = (sizeof(intptr_t) * 8) - s_numberOfEntropyBits;
+
+    static constexpr uint32_t s_maximumNumberOfStructures = 1 << (32 - s_numberOfEntropyBits - s_numberOfNukeBits);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE Structure* StructureIDTable::decode(EncodedStructureBits bits, StructureID structureID)
+{
+    return reinterpret_cast<Structure*>(bits ^ (static_cast<uintptr_t>(structureID) << s_entropyBitsShiftForStructurePointer));
+}
+
+ALWAYS_INLINE EncodedStructureBits StructureIDTable::encode(Structure* structure, StructureID structureID)
+{
+    return reinterpret_cast<EncodedStructureBits>(structure) ^ (static_cast<EncodedStructureBits>(structureID) << s_entropyBitsShiftForStructurePointer);
+}
+
</ins><span class="cx"> inline Structure* StructureIDTable::get(StructureID structureID)
</span><span class="cx"> {
</span><span class="cx">     ASSERT_WITH_SECURITY_IMPLICATION(structureID);
</span><span class="cx">     ASSERT_WITH_SECURITY_IMPLICATION(!isNuked(structureID));
</span><del>-    ASSERT_WITH_SECURITY_IMPLICATION(structureID < m_capacity);
-    return table()[structureID].structure;
</del><ins>+    uint32_t structureIndex = structureID >> s_numberOfEntropyBits;
+    ASSERT_WITH_SECURITY_IMPLICATION(structureIndex < m_capacity);
+    return decode(table()[structureIndex].encodedStructureBits, structureID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool StructureIDTable::isValid(StructureID structureID)
+{
+    if (!structureID)
+        return false;
+    uint32_t structureIndex = structureID >> s_numberOfEntropyBits;
+    if (structureIndex >= m_capacity)
+        return false;
+#if CPU(ADDRESS64)
+    Structure* structure = decode(table()[structureIndex].encodedStructureBits, structureID);
+    if (reinterpret_cast<uintptr_t>(structure) >> s_entropyBitsShiftForStructurePointer)
+        return false;
+#endif
+    return true;
+}
+
</ins><span class="cx"> #else // not USE(JSVALUE64)
</span><span class="cx"> 
</span><span class="cx"> class StructureIDTable {
</span></span></pre>
</div>
</div>

</body>
</html>