<!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>[245214] trunk</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/245214">245214</a></dd>
<dt>Author</dt> <dd>ysuzuki@apple.com</dd>
<dt>Date</dt> <dd>2019-05-12 15:50:21 -0700 (Sun, 12 May 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Compress Watchpoint size by using enum type and Packed<> data structure
https://bugs.webkit.org/show_bug.cgi?id=197730

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Watchpoint takes 5~ MB memory in Gmail (total memory starts with 400 - 500 MB), so 1~%. Since it is allocated massively,
reducing each size of Watchpoint reduces memory footprint significantly.

As a first step, this patch uses Packed<> and enum to reduce the size of Watchpoint.

1. Watchpoint should have enum type and should not use vtable. vtable takes one pointer, and it is too costly for such a
   memory sensitive objects. We perform downcast and dispatch the method of the derived classes based on this enum. Since
   the # of derived Watchpoint classes are limited (Only 8), we can list up them easily. One unfortunate thing is that
   we cannot do this for destructor so long as we use "delete" for deleting objects. If we dispatch the destructor of derived
   class in the destructor of the base class, we call the destructor of the base class multiple times. delete operator override
   does not help since custom delete operator is called after the destructor is called. While we can fix this issue by always
   using custom deleter, currently we do not since all the watchpoints do not have members which have non trivial destructor.
   Once it is strongly required, we can start using custom deleter, but for now, we do not need to do this.

2. We use Packed<> to compact pointers in Watchpoint. Since Watchpoint is a node of doubly linked list, each one has two
   pointers for prev and next. This is also too costly. PackedPtr reduces the size and makes alignment 1.S

3. We use PackedCellPtr<> for JSCells in Watchpoint. This leverages alignment information and makes pointers smaller in
   Darwin ARM64. One important thing to note here is that since this pointer is packed, it cannot be found by conservative
   GC scan. It is OK for watchpoint since they are allocated in the heap anyway.

We applied this change to Watchpoint and get the following memory reduction. The highlight is that CodeBlockJettisoningWatchpoint in
ARM64 only takes 2 pointers size.

                                                                      ORIGINAL    X86_64   ARM64
    WatchpointSet:                                                    40          32       28
    CodeBlockJettisoningWatchpoint:                                   32          19       15
    StructureStubClearingWatchpoint:                                  56          48       40
    AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint: 24          13       11
    AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint:  24          13       11
    FunctionRareData::AllocationProfileClearingWatchpoint:            32          19       15
    ObjectToStringAdaptiveStructureWatchpoint:                        56          48       40
    LLIntPrototypeLoadAdaptiveStructureWatchpoint:                    64          48       48
    DFG::AdaptiveStructureWatchpoint:                                 56          48       40

While we will re-architect the mechanism of Watchpoint, anyway Packed<> mechanism and enum types will be used too.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
* bytecode/CodeBlockJettisoningWatchpoint.h:
* bytecode/CodeOrigin.h:
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
(JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
* bytecode/StructureStubClearingWatchpoint.cpp:
(JSC::StructureStubClearingWatchpoint::fireInternal):
* bytecode/StructureStubClearingWatchpoint.h:
* bytecode/Watchpoint.cpp:
(JSC::Watchpoint::fire):
* bytecode/Watchpoint.h:
(JSC::Watchpoint::Watchpoint):
* dfg/DFGAdaptiveStructureWatchpoint.cpp:
(JSC::DFG::AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint):
* dfg/DFGAdaptiveStructureWatchpoint.h:
* heap/PackedCellPtr.h: Added.
* runtime/FunctionRareData.h:
* runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp: Added.
(JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
* runtime/ObjectToStringAdaptiveStructureWatchpoint.h: Added.
* runtime/StructureRareData.cpp:
(JSC::StructureRareData::clearObjectToStringValue):
(JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint): Deleted.
(JSC::ObjectToStringAdaptiveStructureWatchpoint::install): Deleted.
(JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal): Deleted.
* runtime/StructureRareData.h:

Source/WTF:

This patch introduces a new data structures, WTF::Packed, WTF::PackedPtr, and WTF::PackedAlignedPtr.

- WTF::Packed

    WTF::Packed is data storage. We can read and write trivial (in C++ term [1]) data to this storage. The difference to
    the usual storage is that the alignment of this storage is always 1. We access the underlying data by using unalignedLoad/unalignedStore.
    This class offers alignment = 1 data structure instead of missing the following characteristics.

        1. Load / Store are non atomic even if the data size is within a pointer width. We should not use this for a member which can be accessed
           in a racy way. (e.g. fields accessed optimistically from the concurrent compilers).

        2. We cannot take reference / pointer to the underlying storage since they are unaligned.

        3. Access to this storage is unaligned access. The code is using memcpy, and the compiler will convert to an appropriate unaligned access
           in certain architectures (x86_64 / ARM64). It could be slow. So use it for non performance sensitive & memory sensitive places.

- WTF::PackedPtr

    WTF::PackedPtr is a specialization of WTF::Packed<T*>. And it is basically WTF::PackedAlignedPtr with alignment = 1. We further compact
    the pointer by leveraging the platform specific knowledge. In 64bit architectures, the effective width of pointers are less than 64 bit.
    In x86_64, it is 48 bits. And Darwin ARM64 is further smaller, 36 bits. This information allows us to compact the pointer to 6 bytes in
    x86_64 and 5 bytes in Darwin ARM64.

- WTF::PackedAlignedPtr

    WTF::PackedAlignedPtr is the WTF::PackedPtr with alignment information of the T. If we use this alignment information, we could reduce the
    size of packed pointer further in some cases. For example, since we guarantee that JSCells are 16 byte aligned, low 4 bits are empty. Leveraging
    this information in Darwin ARM64 platform allows us to make packed JSCell pointer 4 bytes (36 - 4 bits). We do not use passed alignment
    information if it is not profitable.

We also have PackedPtrTraits. This is new PtrTraits and use it for various data structures such as Bag<>.

[1]: https://en.cppreference.com/w/cpp/types/is_trivial

* WTF.xcodeproj/project.pbxproj:
* wtf/Bag.h:
(WTF::Bag::clear):
(WTF::Bag::iterator::operator++):
* wtf/CMakeLists.txt:
* wtf/DumbPtrTraits.h:
* wtf/DumbValueTraits.h:
* wtf/MathExtras.h:
(WTF::clzConstexpr):
(WTF::clz):
(WTF::ctzConstexpr):
(WTF::ctz):
(WTF::getLSBSetConstexpr):
(WTF::getMSBSetConstexpr):
* wtf/Packed.h: Added.
(WTF::Packed::Packed):
(WTF::Packed::get const):
(WTF::Packed::set):
(WTF::Packed::operator=):
(WTF::Packed::exchange):
(WTF::Packed::swap):
(WTF::alignof):
(WTF::PackedPtrTraits::exchange):
(WTF::PackedPtrTraits::swap):
(WTF::PackedPtrTraits::unwrap):
* wtf/Platform.h:
* wtf/SentinelLinkedList.h:
(WTF::BasicRawSentinelNode::BasicRawSentinelNode):
(WTF::BasicRawSentinelNode::prev):
(WTF::BasicRawSentinelNode::next):
(WTF::PtrTraits>::remove):
(WTF::PtrTraits>::prepend):
(WTF::PtrTraits>::append):
(WTF::RawNode>::SentinelLinkedList):
(WTF::RawNode>::remove):
(WTF::BasicRawSentinelNode<T>::remove): Deleted.
(WTF::BasicRawSentinelNode<T>::prepend): Deleted.
(WTF::BasicRawSentinelNode<T>::append): Deleted.
* wtf/StdLibExtras.h:
(WTF::roundUpToMultipleOfImpl):
(WTF::roundUpToMultipleOfImpl0): Deleted.
* wtf/UnalignedAccess.h:
(WTF::unalignedLoad):
(WTF::unalignedStore):

Tools:

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/MathExtras.cpp:
(TestWebKitAPI::TEST):
* TestWebKitAPI/Tests/WTF/Packed.cpp: Added.
(TestWebKitAPI::TEST):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<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="#trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBaseh">trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointh">trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeOriginh">trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointh">trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointh">trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointcpp">trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeWatchpointh">trunk/Source/JavaScriptCore/bytecode/Watchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAdaptiveStructureWatchpointcpp">trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAdaptiveStructureWatchpointh">trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionRareDatah">trunk/Source/JavaScriptCore/runtime/FunctionRareData.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatacpp">trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStructureRareDatah">trunk/Source/JavaScriptCore/runtime/StructureRareData.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFWTFxcodeprojprojectpbxproj">trunk/Source/WTF/WTF.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWTFwtfBagh">trunk/Source/WTF/wtf/Bag.h</a></li>
<li><a href="#trunkSourceWTFwtfCMakeListstxt">trunk/Source/WTF/wtf/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWTFwtfDumbPtrTraitsh">trunk/Source/WTF/wtf/DumbPtrTraits.h</a></li>
<li><a href="#trunkSourceWTFwtfDumbValueTraitsh">trunk/Source/WTF/wtf/DumbValueTraits.h</a></li>
<li><a href="#trunkSourceWTFwtfMathExtrash">trunk/Source/WTF/wtf/MathExtras.h</a></li>
<li><a href="#trunkSourceWTFwtfPlatformh">trunk/Source/WTF/wtf/Platform.h</a></li>
<li><a href="#trunkSourceWTFwtfSentinelLinkedListh">trunk/Source/WTF/wtf/SentinelLinkedList.h</a></li>
<li><a href="#trunkSourceWTFwtfStdLibExtrash">trunk/Source/WTF/wtf/StdLibExtras.h</a></li>
<li><a href="#trunkSourceWTFwtfUnalignedAccessh">trunk/Source/WTF/wtf/UnalignedAccess.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsTestWebKitAPICMakeListstxt">trunk/Tools/TestWebKitAPI/CMakeLists.txt</a></li>
<li><a href="#trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFMathExtrascpp">trunk/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreheapPackedCellPtrh">trunk/Source/JavaScriptCore/heap/PackedCellPtr.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectToStringAdaptiveStructureWatchpointcpp">trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectToStringAdaptiveStructureWatchpointh">trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h</a></li>
<li><a href="#trunkSourceWTFwtfPackedh">trunk/Source/WTF/wtf/Packed.h</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFPackedcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -606,6 +606,7 @@
</span><span class="cx">     heap/MarkedSpace.h
</span><span class="cx">     heap/MarkingConstraint.h
</span><span class="cx">     heap/MutatorState.h
</span><ins>+    heap/PackedCellPtr.h
</ins><span class="cx">     heap/RegisterState.h
</span><span class="cx">     heap/RunningScope.h
</span><span class="cx">     heap/SimpleMarkingConstraint.h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -1,5 +1,83 @@
</span><span class="cx"> 2019-05-12  Yusuke Suzuki  <ysuzuki@apple.com>
</span><span class="cx"> 
</span><ins>+        [JSC] Compress Watchpoint size by using enum type and Packed<> data structure
+        https://bugs.webkit.org/show_bug.cgi?id=197730
+
+        Reviewed by Filip Pizlo.
+
+        Watchpoint takes 5~ MB memory in Gmail (total memory starts with 400 - 500 MB), so 1~%. Since it is allocated massively,
+        reducing each size of Watchpoint reduces memory footprint significantly.
+
+        As a first step, this patch uses Packed<> and enum to reduce the size of Watchpoint.
+
+        1. Watchpoint should have enum type and should not use vtable. vtable takes one pointer, and it is too costly for such a
+           memory sensitive objects. We perform downcast and dispatch the method of the derived classes based on this enum. Since
+           the # of derived Watchpoint classes are limited (Only 8), we can list up them easily. One unfortunate thing is that
+           we cannot do this for destructor so long as we use "delete" for deleting objects. If we dispatch the destructor of derived
+           class in the destructor of the base class, we call the destructor of the base class multiple times. delete operator override
+           does not help since custom delete operator is called after the destructor is called. While we can fix this issue by always
+           using custom deleter, currently we do not since all the watchpoints do not have members which have non trivial destructor.
+           Once it is strongly required, we can start using custom deleter, but for now, we do not need to do this.
+
+        2. We use Packed<> to compact pointers in Watchpoint. Since Watchpoint is a node of doubly linked list, each one has two
+           pointers for prev and next. This is also too costly. PackedPtr reduces the size and makes alignment 1.S
+
+        3. We use PackedCellPtr<> for JSCells in Watchpoint. This leverages alignment information and makes pointers smaller in
+           Darwin ARM64. One important thing to note here is that since this pointer is packed, it cannot be found by conservative
+           GC scan. It is OK for watchpoint since they are allocated in the heap anyway.
+
+        We applied this change to Watchpoint and get the following memory reduction. The highlight is that CodeBlockJettisoningWatchpoint in
+        ARM64 only takes 2 pointers size.
+
+                                                                              ORIGINAL    X86_64   ARM64
+            WatchpointSet:                                                    40          32       28
+            CodeBlockJettisoningWatchpoint:                                   32          19       15
+            StructureStubClearingWatchpoint:                                  56          48       40
+            AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint: 24          13       11
+            AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint:  24          13       11
+            FunctionRareData::AllocationProfileClearingWatchpoint:            32          19       15
+            ObjectToStringAdaptiveStructureWatchpoint:                        56          48       40
+            LLIntPrototypeLoadAdaptiveStructureWatchpoint:                    64          48       48
+            DFG::AdaptiveStructureWatchpoint:                                 56          48       40
+
+        While we will re-architect the mechanism of Watchpoint, anyway Packed<> mechanism and enum types will be used too.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
+        * bytecode/CodeBlockJettisoningWatchpoint.h:
+        * bytecode/CodeOrigin.h:
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp:
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint):
+        (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal):
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
+        * bytecode/StructureStubClearingWatchpoint.cpp:
+        (JSC::StructureStubClearingWatchpoint::fireInternal):
+        * bytecode/StructureStubClearingWatchpoint.h:
+        * bytecode/Watchpoint.cpp:
+        (JSC::Watchpoint::fire):
+        * bytecode/Watchpoint.h:
+        (JSC::Watchpoint::Watchpoint):
+        * dfg/DFGAdaptiveStructureWatchpoint.cpp:
+        (JSC::DFG::AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint):
+        * dfg/DFGAdaptiveStructureWatchpoint.h:
+        * heap/PackedCellPtr.h: Added.
+        * runtime/FunctionRareData.h:
+        * runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp: Added.
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint):
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::install):
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal):
+        * runtime/ObjectToStringAdaptiveStructureWatchpoint.h: Added.
+        * runtime/StructureRareData.cpp:
+        (JSC::StructureRareData::clearObjectToStringValue):
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint): Deleted.
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::install): Deleted.
+        (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal): Deleted.
+        * runtime/StructureRareData.h:
+
+2019-05-12  Yusuke Suzuki  <ysuzuki@apple.com>
+
</ins><span class="cx">         [JSC] Compact generator code's bytecode size
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=197822
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj     2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -1779,6 +1779,7 @@
</span><span class="cx">          E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E355D38F22446877008F1AD6 /* GlobalExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = E355D38D2244686B008F1AD6 /* GlobalExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               E356987222841187008CDCCB /* PackedCellPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = E356987122841183008CDCCB /* PackedCellPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">           E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E35CA1541DBC3A5C00F83516 /* DOMJITHeapRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1521DBC3A5600F83516 /* DOMJITHeapRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E35CA1561DBC3A5F00F83516 /* DOMJITAbstractHeap.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -1792,6 +1793,7 @@
</span><span class="cx">          E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */; };
</span><span class="cx">          E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               E39EEAF322812450008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */; };
</ins><span class="cx">           E3A0531A21342B680022EC14 /* WasmStreamingParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531621342B660022EC14 /* WasmStreamingParser.h */; };
</span><span class="cx">          E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531821342B670022EC14 /* WasmSectionParser.h */; };
</span><span class="cx">          E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A32BC61FC8312E007D7E76 /* WeakMapImpl.h */; };
</span><span class="lines">@@ -4773,6 +4775,7 @@
</span><span class="cx">          E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterSnippet.h; sourceTree = "<group>"; };
</span><span class="cx">          E355D38D2244686B008F1AD6 /* GlobalExecutable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalExecutable.h; sourceTree = "<group>"; };
</span><span class="cx">          E355D38E2244686C008F1AD6 /* GlobalExecutable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalExecutable.cpp; sourceTree = "<group>"; };
</span><ins>+               E356987122841183008CDCCB /* PackedCellPtr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PackedCellPtr.h; sourceTree = "<group>"; };
</ins><span class="cx">           E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableBaseInlines.h; sourceTree = "<group>"; };
</span><span class="cx">          E35CA14F1DBC3A5600F83516 /* DOMJITAbstractHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAbstractHeap.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E35CA1501DBC3A5600F83516 /* DOMJITAbstractHeap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeap.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -4799,6 +4802,8 @@
</span><span class="cx">          E39D9D841D39000600667282 /* InterpreterInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterpreterInlines.h; sourceTree = "<group>"; };
</span><span class="cx">          E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; };
</span><ins>+               E39EEAF12281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectToStringAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
+               E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjectToStringAdaptiveStructureWatchpoint.h; sourceTree = "<group>"; };
</ins><span class="cx">           E3A0531621342B660022EC14 /* WasmStreamingParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmStreamingParser.h; sourceTree = "<group>"; };
</span><span class="cx">          E3A0531721342B660022EC14 /* WasmSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSectionParser.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E3A0531821342B670022EC14 /* WasmSectionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSectionParser.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -6025,6 +6030,7 @@
</span><span class="cx">                          0F1FB3981E1F65F900A9BE50 /* MutatorScheduler.h */,
</span><span class="cx">                          0FA762021DB9242300B7A2FD /* MutatorState.cpp */,
</span><span class="cx">                          0FA762031DB9242300B7A2FD /* MutatorState.h */,
</span><ins>+                               E356987122841183008CDCCB /* PackedCellPtr.h */,
</ins><span class="cx">                           0F9DAA081FD1C3C80079C5B2 /* ParallelSourceAdapter.h */,
</span><span class="cx">                          0FBB73B61DEF3AAC002C009E /* PreventCollectionScope.h */,
</span><span class="cx">                          0FD0E5EF1E46BF230006AB08 /* RegisterState.h */,
</span><span class="lines">@@ -7174,6 +7180,8 @@
</span><span class="cx">                          E3C295DC1ED2CBAA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h */,
</span><span class="cx">                          BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */,
</span><span class="cx">                          BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */,
</span><ins>+                               E39EEAF12281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.cpp */,
+                               E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */,
</ins><span class="cx">                           F692A8770255597D01FF60F7 /* Operations.cpp */,
</span><span class="cx">                          F692A8780255597D01FF60F7 /* Operations.h */,
</span><span class="cx">                          0FE228EA1436AB2300196C48 /* Options.cpp */,
</span><span class="lines">@@ -9660,6 +9668,7 @@
</span><span class="cx">                          0FD3E40A1B618B6600C80E1E /* ObjectPropertyCondition.h in Headers */,
</span><span class="cx">                          0FD3E40C1B618B6600C80E1E /* ObjectPropertyConditionSet.h in Headers */,
</span><span class="cx">                          BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */,
</span><ins>+                               E39EEAF322812450008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h in Headers */,
</ins><span class="cx">                           E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
</span><span class="cx">                          14F79F70216EAFD200046D39 /* Opcode.h in Headers */,
</span><span class="cx">                          FE64872E2141D04800AB0D3E /* OpcodeInlines.h in Headers */,
</span><span class="lines">@@ -9668,6 +9677,7 @@
</span><span class="cx">                          A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
</span><span class="cx">                          BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,
</span><span class="cx">                          0FE228ED1436AB2700196C48 /* Options.h in Headers */,
</span><ins>+                               E356987222841187008CDCCB /* PackedCellPtr.h in Headers */,
</ins><span class="cx">                           0F9DAA0A1FD1C3D30079C5B2 /* ParallelSourceAdapter.h in Headers */,
</span><span class="cx">                          E34E657520668EAA00FB81AC /* ParseHash.h in Headers */,
</span><span class="cx">                          37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Sources.txt (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Sources.txt  2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/Sources.txt     2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -899,6 +899,7 @@
</span><span class="cx"> runtime/ObjectConstructor.cpp
</span><span class="cx"> runtime/ObjectInitializationScope.cpp
</span><span class="cx"> runtime/ObjectPrototype.cpp
</span><ins>+runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp
</ins><span class="cx"> runtime/Operations.cpp
</span><span class="cx"> runtime/Options.cpp
</span><span class="cx"> runtime/ProgramExecutable.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeAdaptiveInferredPropertyValueWatchpointBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -45,24 +45,33 @@
</span><span class="cx"> 
</span><span class="cx">     virtual ~AdaptiveInferredPropertyValueWatchpointBase() = default;
</span><span class="cx"> 
</span><del>-protected:
-    virtual bool isValid() const;
-    virtual void handleFire(VM&, const FireDetail&) = 0;
-
-private:
</del><span class="cx">     class StructureWatchpoint final : public Watchpoint {
</span><span class="cx">     public:
</span><del>-        StructureWatchpoint() { }
-    protected:
-        void fireInternal(VM&, const FireDetail&) override;
</del><ins>+        StructureWatchpoint()
+            : Watchpoint(Watchpoint::Type::AdaptiveInferredPropertyValueStructure)
+        { }
+
+        void fireInternal(VM&, const FireDetail&);
</ins><span class="cx">     };
</span><ins>+    // Own destructor may not be called. Keep members trivially destructible.
+    static_assert(sizeof(StructureWatchpoint) == sizeof(Watchpoint), "");
+
</ins><span class="cx">     class PropertyWatchpoint final : public Watchpoint {
</span><span class="cx">     public:
</span><del>-        PropertyWatchpoint() { }
-    protected:
-        void fireInternal(VM&, const FireDetail&) override;
</del><ins>+        PropertyWatchpoint()
+            : Watchpoint(Watchpoint::Type::AdaptiveInferredPropertyValueProperty)
+        { }
+
+        void fireInternal(VM&, const FireDetail&);
</ins><span class="cx">     };
</span><ins>+    // Own destructor may not be called. Keep members trivially destructible.
+    static_assert(sizeof(PropertyWatchpoint) == sizeof(Watchpoint), "");
</ins><span class="cx"> 
</span><ins>+protected:
+    virtual bool isValid() const;
+    virtual void handleFire(VM&, const FireDetail&) = 0;
+
+private:
</ins><span class="cx">     void fire(VM&, const FireDetail&);
</span><span class="cx"> 
</span><span class="cx">     ObjectPropertyCondition m_key;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockJettisoningWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h    2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h       2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include "PackedCellPtr.h"
</ins><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -34,15 +35,15 @@
</span><span class="cx"> class CodeBlockJettisoningWatchpoint final : public Watchpoint {
</span><span class="cx"> public:
</span><span class="cx">     CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock)
</span><del>-        : m_codeBlock(codeBlock)
</del><ins>+        : Watchpoint(Watchpoint::Type::CodeBlockJettisoning)
+        , m_codeBlock(codeBlock)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-protected:
-    void fireInternal(VM&, const FireDetail&) override;
</del><ins>+    void fireInternal(VM&, const FireDetail&);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    CodeBlock* m_codeBlock;
</del><ins>+    JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_codeBlock);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeOriginh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -232,14 +232,9 @@
</span><span class="cx">         return bitwise_cast<InlineCallFrame*>(value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-#if CPU(ARM64) && CPU(ADDRESS64)
-    static constexpr unsigned s_freeBitsAtTop = 28;
-    static constexpr uintptr_t s_maskCompositeValueForPointer = 0x0000000ffffffff8;
-#elif CPU(ADDRESS64)
-    static constexpr unsigned s_freeBitsAtTop = 16;
-    static constexpr uintptr_t s_maskCompositeValueForPointer = 0x0000fffffffffff8;
-#endif
</del><span class="cx"> #if CPU(ADDRESS64)
</span><ins>+    static constexpr unsigned s_freeBitsAtTop = 64 - WTF_CPU_EFFECTIVE_ADDRESS_WIDTH;
+    static constexpr uintptr_t s_maskCompositeValueForPointer = ((1ULL << WTF_CPU_EFFECTIVE_ADDRESS_WIDTH) - 1) & ~(8ULL - 1);
</ins><span class="cx">     static uintptr_t buildCompositeValue(InlineCallFrame* inlineCallFrame, unsigned bytecodeIndex)
</span><span class="cx">     {
</span><span class="cx">         if (bytecodeIndex == s_invalidBytecodeIndex)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -33,9 +33,10 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(CodeBlock* owner, const ObjectPropertyCondition& key, unsigned bytecodeOffset)
</span><del>-    : m_owner(owner)
</del><ins>+    : Watchpoint(Watchpoint::Type::LLIntPrototypeLoadAdaptiveStructure)
+    , m_owner(owner)
+    , m_bytecodeOffset(bytecodeOffset)
</ins><span class="cx">     , m_key(key)
</span><del>-    , m_bytecodeOffset(bytecodeOffset)
</del><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
</span><span class="cx">     RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
</span><span class="lines">@@ -58,8 +59,8 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto& instruction = m_owner->instructions().at(m_bytecodeOffset);
-    clearLLIntGetByIdCache(instruction->as<OpGetById>().metadata(m_owner));
</del><ins>+    auto& instruction = m_owner->instructions().at(m_bytecodeOffset.get());
+    clearLLIntGetByIdCache(instruction->as<OpGetById>().metadata(m_owner.get()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(OpGetById::Metadata& metadata)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeLLIntPrototypeLoadAdaptiveStructureWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h     2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h        2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include "BytecodeStructs.h"
</span><span class="cx"> #include "ObjectPropertyCondition.h"
</span><ins>+#include "PackedCellPtr.h"
</ins><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -41,13 +42,13 @@
</span><span class="cx"> 
</span><span class="cx">     const ObjectPropertyCondition& key() const { return m_key; }
</span><span class="cx"> 
</span><del>-protected:
-    void fireInternal(VM&, const FireDetail&) override;
</del><ins>+    void fireInternal(VM&, const FireDetail&);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    CodeBlock* m_owner;
-    ObjectPropertyCondition m_key;
-    unsigned m_bytecodeOffset;
</del><ins>+    // Own destructor may not be called. Keep members trivially destructible.
+    JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_owner);
+    JSC_WATCHPOINT_FIELD(Packed<unsigned>, m_bytecodeOffset);
+    JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp 2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp    2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> void StructureStubClearingWatchpoint::fireInternal(VM& vm, const FireDetail&)
</span><span class="cx"> {
</span><del>-    if (!m_holder.isValid())
</del><ins>+    if (!m_holder->isValid())
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (!m_key || !m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
</span><span class="lines">@@ -43,8 +43,8 @@
</span><span class="cx">         // This will implicitly cause my own demise: stub reset removes all watchpoints.
</span><span class="cx">         // That works, because deleting a watchpoint removes it from the set's list, and
</span><span class="cx">         // the set's list traversal for firing is robust against the set changing.
</span><del>-        ConcurrentJSLocker locker(m_holder.codeBlock()->m_lock);
-        m_holder.stubInfo()->reset(m_holder.codeBlock());
</del><ins>+        ConcurrentJSLocker locker(m_holder->codeBlock()->m_lock);
+        m_holder->stubInfo()->reset(m_holder->codeBlock());
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeStructureStubClearingWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -44,20 +44,19 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(StructureStubClearingWatchpoint);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    StructureStubClearingWatchpoint(
-        const ObjectPropertyCondition& key,
-        WatchpointsOnStructureStubInfo& holder)
-        : m_key(key)
-        , m_holder(holder)
</del><ins>+    StructureStubClearingWatchpoint(const ObjectPropertyCondition& key, WatchpointsOnStructureStubInfo& holder)
+        : Watchpoint(Watchpoint::Type::StructureStubClearing)
+        , m_holder(&holder)
+        , m_key(key)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-protected:
-    void fireInternal(VM&, const FireDetail&) override;
</del><ins>+    void fireInternal(VM&, const FireDetail&);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    ObjectPropertyCondition m_key;
-    WatchpointsOnStructureStubInfo& m_holder;
</del><ins>+    // Own destructor may not be called. Keep members trivially destructible.
+    JSC_WATCHPOINT_FIELD(PackedPtr<WatchpointsOnStructureStubInfo>, m_holder);
+    JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class WatchpointsOnStructureStubInfo {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp      2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp 2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -26,7 +26,14 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> 
</span><ins>+#include "AdaptiveInferredPropertyValueWatchpointBase.h"
+#include "CodeBlockJettisoningWatchpoint.h"
+#include "DFGAdaptiveStructureWatchpoint.h"
+#include "FunctionRareData.h"
</ins><span class="cx"> #include "HeapInlines.h"
</span><ins>+#include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h"
+#include "ObjectToStringAdaptiveStructureWatchpoint.h"
+#include "StructureStubClearingWatchpoint.h"
</ins><span class="cx"> #include "VM.h"
</span><span class="cx"> #include <wtf/CompilationThread.h>
</span><span class="cx"> 
</span><span class="lines">@@ -52,7 +59,14 @@
</span><span class="cx"> void Watchpoint::fire(VM& vm, const FireDetail& detail)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(!isOnList());
</span><del>-    fireInternal(vm, detail);
</del><ins>+    switch (m_type) {
+#define JSC_DEFINE_WATCHPOINT_DISPATCH(type, cast) \
+    case Type::type: \
+        static_cast<cast*>(this)->fireInternal(vm, detail); \
+        break;
+    JSC_WATCHPOINT_TYPES(JSC_DEFINE_WATCHPOINT_DISPATCH)
+#undef JSC_DEFINE_WATCHPOINT_DISPATCH
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WatchpointSet::WatchpointSet(WatchpointState state)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/Watchpoint.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/Watchpoint.h        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/bytecode/Watchpoint.h   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -90,21 +90,75 @@
</span><span class="cx"> 
</span><span class="cx"> class WatchpointSet;
</span><span class="cx"> 
</span><del>-class Watchpoint : public BasicRawSentinelNode<Watchpoint> {
</del><ins>+// Really unfortunately, we do not have the way to dispatch appropriate destructor in base class' destructor
+// based on enum type. If we call destructor explicitly in the base class, it ends up calling the base destructor
+// twice. C++20 allows this by using std::std::destroying_delete_t. But we are not using C++20 right now.
+//
+// Because we cannot dispatch destructors of derived classes in the destructor of the base class, what it means is,
+// 1. Calling Watchpoint::~Watchpoint directly is illegal.
+// 2. `delete watchpoint` where watchpoint is non-final derived class is illegal. If watchpoint is final derived class, it works.
+// 3. If we really want to do (2), we need to call `watchpoint->destroy()` instead, and dispatch an appropriate destructor in Watchpoint::destroy.
+//
+// Luckily, none of our derived watchpoint classes have members which require destructors. So we do not dispatch
+// the destructor call to the drived class in the base class. If it becomes really required, we can introduce
+// a custom deleter for some classes which directly call "delete" to the allocated non-final Watchpoint class
+// (e.g. std::unique_ptr<Watchpoint>, RefPtr<Watchpoint>), and call Watchpoint::destroy instead of "delete"
+// operator. But since we do not require it for now, we are doing the simplest thing.
+#define JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro) \
+    macro(AdaptiveInferredPropertyValueStructure, AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint) \
+    macro(AdaptiveInferredPropertyValueProperty, AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint) \
+    macro(CodeBlockJettisoning, CodeBlockJettisoningWatchpoint) \
+    macro(LLIntPrototypeLoadAdaptiveStructure, LLIntPrototypeLoadAdaptiveStructureWatchpoint) \
+    macro(FunctionRareDataAllocationProfileClearing, FunctionRareData::AllocationProfileClearingWatchpoint) \
+    macro(ObjectToStringAdaptiveStructure, ObjectToStringAdaptiveStructureWatchpoint)
+
+#if ENABLE(JIT)
+#define JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro) \
+    JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro) \
+    macro(StructureStubClearing, StructureStubClearingWatchpoint)
+
+#if ENABLE(DFG_JIT)
+#define JSC_WATCHPOINT_TYPES(macro) \
+    JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro) \
+    macro(AdaptiveStructure, DFG::AdaptiveStructureWatchpoint)
+#else
+#define JSC_WATCHPOINT_TYPES(macro) \
+    JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro)
+#endif
+
+#else
+#define JSC_WATCHPOINT_TYPES(macro) \
+    JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro)
+#endif
+
+#define JSC_WATCHPOINT_FIELD(type, member) \
+    type member; \
+    static_assert(std::is_trivially_destructible<type>::value, ""); \
+
+
+class Watchpoint : public PackedRawSentinelNode<Watchpoint> {
</ins><span class="cx">     WTF_MAKE_NONCOPYABLE(Watchpoint);
</span><span class="cx">     WTF_MAKE_NONMOVABLE(Watchpoint);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    Watchpoint() = default;
-    
-    virtual ~Watchpoint();
</del><ins>+#define JSC_DEFINE_WATCHPOINT_TYPES(type, _) type,
+    enum class Type : uint8_t {
+        JSC_WATCHPOINT_TYPES(JSC_DEFINE_WATCHPOINT_TYPES)
+    };
+#undef JSC_DEFINE_WATCHPOINT_TYPES
</ins><span class="cx"> 
</span><ins>+    Watchpoint(Type type)
+        : m_type(type)
+    { }
+
</ins><span class="cx"> protected:
</span><del>-    virtual void fireInternal(VM&, const FireDetail&) = 0;
</del><ins>+    ~Watchpoint();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class WatchpointSet;
</span><span class="cx">     void fire(VM&, const FireDetail&);
</span><ins>+
+    Type m_type;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum WatchpointState {
</span><span class="lines">@@ -239,7 +293,7 @@
</span><span class="cx">     int8_t m_state;
</span><span class="cx">     int8_t m_setIsNotEmpty;
</span><span class="cx"> 
</span><del>-    SentinelLinkedList<Watchpoint, BasicRawSentinelNode<Watchpoint>> m_set;
</del><ins>+    SentinelLinkedList<Watchpoint, PackedRawSentinelNode<Watchpoint>> m_set;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // InlineWatchpointSet is a low-overhead, non-copyable watchpoint set in which
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAdaptiveStructureWatchpointcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -33,11 +33,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><del>-AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint(
-    const ObjectPropertyCondition& key,
-    CodeBlock* codeBlock)
-    : m_key(key)
</del><ins>+AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, CodeBlock* codeBlock)
+    : Watchpoint(Watchpoint::Type::AdaptiveStructure)
</ins><span class="cx">     , m_codeBlock(codeBlock)
</span><ins>+    , m_key(key)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
</span><span class="cx">     RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAdaptiveStructureWatchpointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h 2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h    2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #if ENABLE(DFG_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include "ObjectPropertyCondition.h"
</span><ins>+#include "PackedCellPtr.h"
</ins><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="lines">@@ -40,12 +41,12 @@
</span><span class="cx">     
</span><span class="cx">     void install(VM&);
</span><span class="cx"> 
</span><del>-protected:
-    void fireInternal(VM&, const FireDetail&) override;
</del><ins>+    void fireInternal(VM&, const FireDetail&);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    ObjectPropertyCondition m_key;
-    CodeBlock* m_codeBlock;
</del><ins>+    // Own destructor may not be called. Keep members trivially destructible.
+    JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_codeBlock);
+    JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapPackedCellPtrh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/heap/PackedCellPtr.h (0 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/PackedCellPtr.h                         (rev 0)
+++ trunk/Source/JavaScriptCore/heap/PackedCellPtr.h    2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -0,0 +1,36 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#include "MarkedBlock.h"
+#include <wtf/Packed.h>
+
+namespace JSC {
+
+template<typename T>
+using PackedCellPtr = PackedAlignedPtr<T, MarkedBlock::atomSize>;
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionRareData.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionRareData.h   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/runtime/FunctionRareData.h      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include "InternalFunctionAllocationProfile.h"
</span><span class="cx"> #include "JSCast.h"
</span><span class="cx"> #include "ObjectAllocationProfile.h"
</span><ins>+#include "PackedCellPtr.h"
</ins><span class="cx"> #include "Watchpoint.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -110,23 +111,25 @@
</span><span class="cx">         return m_allocationProfileClearingWatchpoint.get();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-protected:
-    FunctionRareData(VM&);
-    ~FunctionRareData();
-
-private:
-
</del><span class="cx">     class AllocationProfileClearingWatchpoint final : public Watchpoint {
</span><span class="cx">     public:
</span><span class="cx">         AllocationProfileClearingWatchpoint(FunctionRareData* rareData)
</span><del>-            : m_rareData(rareData)
</del><ins>+            : Watchpoint(Watchpoint::Type::FunctionRareDataAllocationProfileClearing)
+            , m_rareData(rareData)
</ins><span class="cx">         { }
</span><del>-    protected:
-        void fireInternal(VM&, const FireDetail&) override;
</del><ins>+
+        void fireInternal(VM&, const FireDetail&);
+
</ins><span class="cx">     private:
</span><del>-        FunctionRareData* m_rareData;
</del><ins>+        // Own destructor may not be called. Keep members trivially destructible.
+        JSC_WATCHPOINT_FIELD(PackedCellPtr<FunctionRareData>, m_rareData);
</ins><span class="cx">     };
</span><span class="cx"> 
</span><ins>+protected:
+    FunctionRareData(VM&);
+    ~FunctionRareData();
+
+private:
</ins><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="cx"> 
</span><span class="cx">     // Ideally, there would only be one allocation profile for subclassing but due to Reflect.construct we
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectToStringAdaptiveStructureWatchpointcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp (0 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -0,0 +1,63 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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 "ObjectToStringAdaptiveStructureWatchpoint.h"
+
+#include "ObjectPropertyConditionSet.h"
+#include "StructureRareData.h"
+
+namespace JSC {
+
+ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)
+    : Watchpoint(Watchpoint::Type::ObjectToStringAdaptiveStructure)
+    , m_structureRareData(structureRareData)
+    , m_key(key)
+{
+    RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
+    RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
+}
+
+void ObjectToStringAdaptiveStructureWatchpoint::install(VM& vm)
+{
+    RELEASE_ASSERT(m_key.isWatchable());
+
+    m_key.object()->structure(vm)->addTransitionWatchpoint(this);
+}
+
+void ObjectToStringAdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail&)
+{
+    if (!m_structureRareData->isLive())
+        return;
+
+    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
+        install(vm);
+        return;
+    }
+
+    m_structureRareData->clearObjectToStringValue();
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectToStringAdaptiveStructureWatchpointh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h (0 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h                          (rev 0)
+++ trunk/Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h     2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -0,0 +1,52 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#include "ObjectPropertyCondition.h"
+#include "PackedCellPtr.h"
+#include "Watchpoint.h"
+
+namespace JSC {
+
+class StructureRareData;
+
+class ObjectToStringAdaptiveStructureWatchpoint final : public Watchpoint {
+public:
+    ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*);
+
+    void install(VM&);
+
+    const ObjectPropertyCondition& key() const { return m_key; }
+
+    void fireInternal(VM&, const FireDetail&);
+    
+private:
+    // Own destructor may not be called. Keep members trivially destructible.
+    JSC_WATCHPOINT_FIELD(PackedCellPtr<StructureRareData>, m_structureRareData);
+    JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key);
+};
+
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include "JSString.h"
</span><span class="cx"> #include "JSCInlines.h"
</span><span class="cx"> #include "ObjectPropertyConditionSet.h"
</span><ins>+#include "ObjectToStringAdaptiveStructureWatchpoint.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -90,22 +91,6 @@
</span><span class="cx">     StructureRareData* m_structureRareData;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class ObjectToStringAdaptiveStructureWatchpoint final : public Watchpoint {
-public:
-    ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*);
-
-    void install(VM&);
-
-    const ObjectPropertyCondition& key() const { return m_key; }
-
-protected:
-    void fireInternal(VM&, const FireDetail&) override;
-    
-private:
-    ObjectPropertyCondition m_key;
-    StructureRareData* m_structureRareData;
-};
-
</del><span class="cx"> void StructureRareData::setObjectToStringValue(ExecState* exec, VM& vm, Structure* ownStructure, JSString* value, PropertySlot toStringTagSymbolSlot)
</span><span class="cx"> {
</span><span class="cx">     if (m_giveUpOnObjectToStringValueCache)
</span><span class="lines">@@ -164,7 +149,7 @@
</span><span class="cx">     m_objectToStringValue.set(vm, this, value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StructureRareData::clearObjectToStringValue()
</del><ins>+void StructureRareData::clearObjectToStringValue()
</ins><span class="cx"> {
</span><span class="cx">     m_objectToStringAdaptiveWatchpointSet.clear();
</span><span class="cx">     m_objectToStringAdaptiveInferredValueWatchpoint.reset();
</span><span class="lines">@@ -189,34 +174,6 @@
</span><span class="cx"> 
</span><span class="cx"> // ------------- Methods for Object.prototype.toString() helper watchpoint classes --------------
</span><span class="cx"> 
</span><del>-ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)
-    : m_key(key)
-    , m_structureRareData(structureRareData)
-{
-    RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());
-    RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());
-}
-
-void ObjectToStringAdaptiveStructureWatchpoint::install(VM& vm)
-{
-    RELEASE_ASSERT(m_key.isWatchable());
-
-    m_key.object()->structure(vm)->addTransitionWatchpoint(this);
-}
-
-void ObjectToStringAdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail&)
-{
-    if (!m_structureRareData->isLive())
-        return;
-
-    if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {
-        install(vm);
-        return;
-    }
-
-    m_structureRareData->clearObjectToStringValue();
-}
-
</del><span class="cx"> ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)
</span><span class="cx">     : Base(key)
</span><span class="cx">     , m_structureRareData(structureRareData)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStructureRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StructureRareData.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StructureRareData.h  2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/JavaScriptCore/runtime/StructureRareData.h     2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -35,8 +35,8 @@
</span><span class="cx"> 
</span><span class="cx"> class JSPropertyNameEnumerator;
</span><span class="cx"> class Structure;
</span><ins>+class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
</ins><span class="cx"> class ObjectToStringAdaptiveStructureWatchpoint;
</span><del>-class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;
</del><span class="cx"> 
</span><span class="cx"> class StructureRareData final : public JSCell {
</span><span class="cx"> public:
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/ChangeLog  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -1,3 +1,89 @@
</span><ins>+2019-05-12  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Compress Watchpoint size by using enum type and Packed<> data structure
+        https://bugs.webkit.org/show_bug.cgi?id=197730
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces a new data structures, WTF::Packed, WTF::PackedPtr, and WTF::PackedAlignedPtr.
+
+        - WTF::Packed
+
+            WTF::Packed is data storage. We can read and write trivial (in C++ term [1]) data to this storage. The difference to
+            the usual storage is that the alignment of this storage is always 1. We access the underlying data by using unalignedLoad/unalignedStore.
+            This class offers alignment = 1 data structure instead of missing the following characteristics.
+
+                1. Load / Store are non atomic even if the data size is within a pointer width. We should not use this for a member which can be accessed
+                   in a racy way. (e.g. fields accessed optimistically from the concurrent compilers).
+
+                2. We cannot take reference / pointer to the underlying storage since they are unaligned.
+
+                3. Access to this storage is unaligned access. The code is using memcpy, and the compiler will convert to an appropriate unaligned access
+                   in certain architectures (x86_64 / ARM64). It could be slow. So use it for non performance sensitive & memory sensitive places.
+
+        - WTF::PackedPtr
+
+            WTF::PackedPtr is a specialization of WTF::Packed<T*>. And it is basically WTF::PackedAlignedPtr with alignment = 1. We further compact
+            the pointer by leveraging the platform specific knowledge. In 64bit architectures, the effective width of pointers are less than 64 bit.
+            In x86_64, it is 48 bits. And Darwin ARM64 is further smaller, 36 bits. This information allows us to compact the pointer to 6 bytes in
+            x86_64 and 5 bytes in Darwin ARM64.
+
+        - WTF::PackedAlignedPtr
+
+            WTF::PackedAlignedPtr is the WTF::PackedPtr with alignment information of the T. If we use this alignment information, we could reduce the
+            size of packed pointer further in some cases. For example, since we guarantee that JSCells are 16 byte aligned, low 4 bits are empty. Leveraging
+            this information in Darwin ARM64 platform allows us to make packed JSCell pointer 4 bytes (36 - 4 bits). We do not use passed alignment
+            information if it is not profitable.
+
+        We also have PackedPtrTraits. This is new PtrTraits and use it for various data structures such as Bag<>.
+
+        [1]: https://en.cppreference.com/w/cpp/types/is_trivial
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/Bag.h:
+        (WTF::Bag::clear):
+        (WTF::Bag::iterator::operator++):
+        * wtf/CMakeLists.txt:
+        * wtf/DumbPtrTraits.h:
+        * wtf/DumbValueTraits.h:
+        * wtf/MathExtras.h:
+        (WTF::clzConstexpr):
+        (WTF::clz):
+        (WTF::ctzConstexpr):
+        (WTF::ctz):
+        (WTF::getLSBSetConstexpr):
+        (WTF::getMSBSetConstexpr):
+        * wtf/Packed.h: Added.
+        (WTF::Packed::Packed):
+        (WTF::Packed::get const):
+        (WTF::Packed::set):
+        (WTF::Packed::operator=):
+        (WTF::Packed::exchange):
+        (WTF::Packed::swap):
+        (WTF::alignof):
+        (WTF::PackedPtrTraits::exchange):
+        (WTF::PackedPtrTraits::swap):
+        (WTF::PackedPtrTraits::unwrap):
+        * wtf/Platform.h:
+        * wtf/SentinelLinkedList.h:
+        (WTF::BasicRawSentinelNode::BasicRawSentinelNode):
+        (WTF::BasicRawSentinelNode::prev):
+        (WTF::BasicRawSentinelNode::next):
+        (WTF::PtrTraits>::remove):
+        (WTF::PtrTraits>::prepend):
+        (WTF::PtrTraits>::append):
+        (WTF::RawNode>::SentinelLinkedList):
+        (WTF::RawNode>::remove):
+        (WTF::BasicRawSentinelNode<T>::remove): Deleted.
+        (WTF::BasicRawSentinelNode<T>::prepend): Deleted.
+        (WTF::BasicRawSentinelNode<T>::append): Deleted.
+        * wtf/StdLibExtras.h:
+        (WTF::roundUpToMultipleOfImpl):
+        (WTF::roundUpToMultipleOfImpl0): Deleted.
+        * wtf/UnalignedAccess.h:
+        (WTF::unalignedLoad):
+        (WTF::unalignedStore):
+
</ins><span class="cx"> 2019-05-10  Saam barati  <sbarati@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Bag's move operator= leaks memory
</span></span></pre></div>
<a id="trunkSourceWTFWTFxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -658,6 +658,7 @@
</span><span class="cx">          E311FB161F0A568B003C08DE /* ThreadGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadGroup.h; sourceTree = "<group>"; };
</span><span class="cx">          E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRegisters.h; sourceTree = "<group>"; };
</span><span class="cx">          E33D5F871FBED66700BF625E /* RecursableLambda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursableLambda.h; sourceTree = "<group>"; };
</span><ins>+               E34CD0D022810A020020D299 /* Packed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Packed.h; sourceTree = "<group>"; };
</ins><span class="cx">           E360C7642127B85B00C90F0E /* UnalignedAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnalignedAccess.h; sourceTree = "<group>"; };
</span><span class="cx">          E360C7652127B85C00C90F0E /* Unexpected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unexpected.h; sourceTree = "<group>"; };
</span><span class="cx">          E388886D20C9095100E632BC /* WorkerPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerPool.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -1056,6 +1057,7 @@
</span><span class="cx">                          7CBBA07319BB7FDC00BBF025 /* OSObjectPtr.h */,
</span><span class="cx">                          A8A472DA151A825B004123FF /* OSRandomSource.cpp */,
</span><span class="cx">                          A8A472DB151A825B004123FF /* OSRandomSource.h */,
</span><ins>+                               E34CD0D022810A020020D299 /* Packed.h */,
</ins><span class="cx">                           A8A472DF151A825B004123FF /* PackedIntVector.h */,
</span><span class="cx">                          A8A472E0151A825B004123FF /* PageAllocation.h */,
</span><span class="cx">                          A8A472E3151A825B004123FF /* PageBlock.cpp */,
</span></span></pre></div>
<a id="trunkSourceWTFwtfBagh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bag.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bag.h       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/Bag.h  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -28,15 +28,18 @@
</span><span class="cx"> #include <wtf/DumbPtrTraits.h>
</span><span class="cx"> #include <wtf/FastMalloc.h>
</span><span class="cx"> #include <wtf/Noncopyable.h>
</span><ins>+#include <wtf/Packed.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> namespace Private {
</span><span class="cx"> 
</span><del>-template<typename T>
</del><ins>+template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>>
</ins><span class="cx"> class BagNode {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><ins>+    using PtrTraits = typename PassedPtrTraits::template RebindTraits<BagNode>;
+
</ins><span class="cx">     template<typename... Args>
</span><span class="cx">     BagNode(Args&&... args)
</span><span class="cx">         : m_item(std::forward<Args>(args)...)
</span><span class="lines">@@ -43,16 +46,17 @@
</span><span class="cx">     { }
</span><span class="cx">     
</span><span class="cx">     T m_item;
</span><del>-    BagNode* m_next { nullptr };
</del><ins>+    typename PtrTraits::StorageType m_next { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace Private
</span><span class="cx"> 
</span><del>-template<typename T, typename PtrTraits = DumbPtrTraits<Private::BagNode<T>>>
</del><ins>+template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>>
</ins><span class="cx"> class Bag {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(Bag);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><del>-    using Node = Private::BagNode<T>;
</del><ins>+    using Node = Private::BagNode<T, PassedPtrTraits>;
+    using PtrTraits = typename PassedPtrTraits::template RebindTraits<Node>;
</ins><span class="cx"> 
</span><span class="cx"> public:
</span><span class="cx">     Bag() = default;
</span><span class="lines">@@ -75,7 +79,7 @@
</span><span class="cx">         Node* head = this->unwrappedHead();
</span><span class="cx">         while (head) {
</span><span class="cx">             Node* current = head;
</span><del>-            head = current->m_next;
</del><ins>+            head = Node::PtrTraits::unwrap(current->m_next);
</ins><span class="cx">             delete current;
</span><span class="cx">         }
</span><span class="cx">         m_head = nullptr;
</span><span class="lines">@@ -104,7 +108,7 @@
</span><span class="cx">         
</span><span class="cx">         iterator& operator++()
</span><span class="cx">         {
</span><del>-            m_node = m_node->m_next;
</del><ins>+            m_node = Node::PtrTraits::unwrap(m_node->m_next);
</ins><span class="cx">             return *this;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -148,6 +152,10 @@
</span><span class="cx">     typename PtrTraits::StorageType m_head { nullptr };
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template<typename T>
+using PackedBag = Bag<T, PackedPtrTraits<T>>;
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::Bag;
</span><ins>+using WTF::PackedBag;
</ins></span></pre></div>
<a id="trunkSourceWTFwtfCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/CMakeLists.txt (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CMakeLists.txt      2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -150,6 +150,7 @@
</span><span class="cx">     OptionSet.h
</span><span class="cx">     Optional.h
</span><span class="cx">     OrderMaker.h
</span><ins>+    Packed.h
</ins><span class="cx">     PackedIntVector.h
</span><span class="cx">     PageAllocation.h
</span><span class="cx">     PageBlock.h
</span></span></pre></div>
<a id="trunkSourceWTFwtfDumbPtrTraitsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/DumbPtrTraits.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/DumbPtrTraits.h     2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/DumbPtrTraits.h        2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx">     
</span><span class="cx"> template<typename T>
</span><span class="cx"> struct DumbPtrTraits {
</span><ins>+    template<typename U> using RebindTraits = DumbPtrTraits<U>;
+
</ins><span class="cx">     using StorageType = T*;
</span><span class="cx"> 
</span><span class="cx">     template<typename U>
</span></span></pre></div>
<a id="trunkSourceWTFwtfDumbValueTraitsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/DumbValueTraits.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/DumbValueTraits.h   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/DumbValueTraits.h      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx"> 
</span><span class="cx"> template<typename T>
</span><span class="cx"> struct DumbValueTraits {
</span><ins>+    template<typename U> using RebindTraits = DumbValueTraits<U>;
+
</ins><span class="cx">     using StorageType = T;
</span><span class="cx"> 
</span><span class="cx">     template<typename U>
</span></span></pre></div>
<a id="trunkSourceWTFwtfMathExtrash"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MathExtras.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MathExtras.h        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/MathExtras.h   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -615,6 +615,23 @@
</span><span class="cx">     shuffleVector(vector, vector.size(), randomFunc);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template <typename T>
+constexpr unsigned clzConstexpr(T value)
+{
+    constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
+
+    using UT = typename std::make_unsigned<T>::type;
+    UT uValue = value;
+
+    unsigned zeroCount = 0;
+    for (int i = bitSize - 1; i >= 0; i--) {
+        if (uValue >> i)
+            break;
+        zeroCount++;
+    }
+    return zeroCount;
+}
+
</ins><span class="cx"> template<typename T>
</span><span class="cx"> inline unsigned clz(T value)
</span><span class="cx"> {
</span><span class="lines">@@ -637,14 +654,29 @@
</span><span class="cx">         return bitSize - 1 - ret;
</span><span class="cx">     return bitSize;
</span><span class="cx"> #else
</span><ins>+    UNUSED_PARAM(bitSize);
+    UNUSED_PARAM(uValue);
+    return clzConstexpr(value);
+#endif
+}
+
+template <typename T>
+constexpr unsigned ctzConstexpr(T value)
+{
+    constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
+
+    using UT = typename std::make_unsigned<T>::type;
+    UT uValue = value;
+
</ins><span class="cx">     unsigned zeroCount = 0;
</span><del>-    for (int i = bitSize - 1; i >= 0; i--) {
-        if (uValue >> i)
</del><ins>+    for (unsigned i = 0; i < bitSize; i++) {
+        if (uValue & 1)
</ins><span class="cx">             break;
</span><ins>+
</ins><span class="cx">         zeroCount++;
</span><ins>+        uValue >>= 1;
</ins><span class="cx">     }
</span><span class="cx">     return zeroCount;
</span><del>-#endif
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template<typename T>
</span><span class="lines">@@ -665,15 +697,9 @@
</span><span class="cx">         return ret;
</span><span class="cx">     return bitSize;
</span><span class="cx"> #else
</span><del>-    unsigned zeroCount = 0;
-    for (unsigned i = 0; i < bitSize; i++) {
-        if (uValue & 1)
-            break;
-
-        zeroCount++;
-        uValue >>= 1;
-    }
-    return zeroCount;
</del><ins>+    UNUSED_PARAM(bitSize);
+    UNUSED_PARAM(uValue);
+    return ctzConstexpr(value);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -685,6 +711,13 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template<typename T>
</span><ins>+constexpr unsigned getLSBSetConstexpr(T t)
+{
+    ASSERT_UNDER_CONSTEXPR_CONTEXT(t);
+    return ctzConstexpr(t);
+}
+
+template<typename T>
</ins><span class="cx"> inline unsigned getMSBSet(T t)
</span><span class="cx"> {
</span><span class="cx">     constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
</span><span class="lines">@@ -692,6 +725,14 @@
</span><span class="cx">     return bitSize - 1 - clz(t);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template<typename T>
+constexpr unsigned getMSBSetConstexpr(T t)
+{
+    constexpr unsigned bitSize = sizeof(T) * CHAR_BIT;
+    ASSERT_UNDER_CONSTEXPR_CONTEXT(t);
+    return bitSize - 1 - clzConstexpr(t);
+}
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx"> 
</span><span class="cx"> using WTF::opaque;
</span></span></pre></div>
<a id="trunkSourceWTFwtfPackedh"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/Packed.h (0 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Packed.h                            (rev 0)
+++ trunk/Source/WTF/wtf/Packed.h       2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -0,0 +1,233 @@
</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.
+ */
+
+#pragma once
+
+#include <array>
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/UnalignedAccess.h>
+
+namespace WTF {
+
+template<typename T>
+class Packed {
+public:
+    static constexpr bool isPackedType = true;
+
+    Packed()
+        : Packed(T { })
+    {
+    }
+
+    Packed(const T& value)
+    {
+        unalignedStore<T>(m_storage.data(), value);
+    }
+
+    T get() const
+    {
+        return unalignedLoad<T>(m_storage.data());
+    }
+
+    void set(const T& value)
+    {
+        unalignedStore<T>(m_storage.data(), value);
+    }
+
+    Packed<T>& operator=(const T& value)
+    {
+        set(value);
+        return *this;
+    }
+
+    template<class U>
+    T exchange(U&& newValue)
+    {
+        T oldValue = get();
+        set(std::forward<U>(newValue));
+        return oldValue;
+    }
+
+    void swap(Packed& other)
+    {
+        m_storage.swap(other.m_storage);
+    }
+
+    template<typename Other, typename = std::enable_if_t<Other::isPackedType>>
+    void swap(Other& other)
+    {
+        T t1 = get();
+        T t2 = other.get();
+        set(t2);
+        other.set(t1);
+    }
+
+    void swap(T& t2)
+    {
+        T t1 = get();
+        std::swap(t1, t2);
+        set(t1);
+    }
+
+private:
+    std::array<uint8_t, sizeof(T)> m_storage;
+};
+
+// PackedAlignedPtr can take alignment parameter too. PackedAlignedPtr only uses this alignment information if it is profitable: we use
+// alignment information only when we can reduce the size of the storage. Since the pointer width is 36 bits and JSCells are aligned to 16 bytes,
+// we can use 4 bits in Darwin ARM64, we can compact cell pointer into 4 bytes (32 bits).
+template<typename T, size_t alignment = alignof(T)>
+class PackedAlignedPtr {
+public:
+    static_assert(hasOneBitSet(alignment), "Alignment needs to be power-of-two");
+    static constexpr bool isPackedType = true;
+    static constexpr unsigned alignmentShiftSizeIfProfitable = getLSBSetConstexpr(alignment);
+    static constexpr unsigned storageSizeWithoutAlignmentShift = roundUpToMultipleOf<8>(WTF_CPU_EFFECTIVE_ADDRESS_WIDTH) / 8;
+    static constexpr unsigned storageSizeWithAlignmentShift = roundUpToMultipleOf<8>(WTF_CPU_EFFECTIVE_ADDRESS_WIDTH - alignmentShiftSizeIfProfitable) / 8;
+    static constexpr bool isAlignmentShiftProfitable = storageSizeWithoutAlignmentShift > storageSizeWithAlignmentShift;
+    static constexpr unsigned alignmentShiftSize = isAlignmentShiftProfitable ? alignmentShiftSizeIfProfitable : 0;
+    static constexpr unsigned storageSize = storageSizeWithAlignmentShift;
+
+    constexpr PackedAlignedPtr()
+        : m_storage()
+    {
+    }
+
+    constexpr PackedAlignedPtr(std::nullptr_t)
+        : m_storage()
+    {
+    }
+
+    PackedAlignedPtr(T* value)
+    {
+        set(value);
+    }
+
+    T* get() const
+    {
+        // FIXME: PackedPtr<> can load memory with one mov by checking page boundary.
+        // https://bugs.webkit.org/show_bug.cgi?id=197754
+        uintptr_t value = 0;
+#if CPU(LITTLE_ENDIAN)
+        memcpy(&value, m_storage.data(), storageSize);
+#else
+        memcpy(bitwise_cast<uint8_t*>(&value) + (sizeof(void*) - storageSize), m_storage.data(), storageSize);
+#endif
+        if (isAlignmentShiftProfitable)
+            value <<= alignmentShiftSize;
+        return bitwise_cast<T*>(value);
+    }
+
+    void set(T* passedValue)
+    {
+        uintptr_t value = bitwise_cast<uintptr_t>(passedValue);
+        if (isAlignmentShiftProfitable)
+            value >>= alignmentShiftSize;
+#if CPU(LITTLE_ENDIAN)
+        memcpy(m_storage.data(), &value, storageSize);
+#else
+        memcpy(m_storage.data(), bitwise_cast<uint8_t*>(&value) + (sizeof(void*) - storageSize));
+#endif
+    }
+
+    void clear()
+    {
+        set(nullptr);
+    }
+
+    T* operator->() const { return get(); }
+    T& operator*() const { return *get(); }
+    bool operator!() const { return !get(); }
+
+    PackedAlignedPtr& operator=(T* value)
+    {
+        set(value);
+        return *this;
+    }
+
+    template<class U>
+    T exchange(U&& newValue)
+    {
+        T oldValue = get();
+        set(std::forward<U>(newValue));
+        return oldValue;
+    }
+
+    void swap(std::nullptr_t) { clear(); }
+
+    void swap(PackedAlignedPtr& other)
+    {
+        m_storage.swap(other.m_storage);
+    }
+
+    template<typename Other, typename = std::enable_if_t<Other::isPackedType>>
+    void swap(Other& other)
+    {
+        T t1 = get();
+        T t2 = other.get();
+        set(t2);
+        other.set(t1);
+    }
+
+    void swap(T& t2)
+    {
+        T t1 = get();
+        std::swap(t1, t2);
+        set(t1);
+    }
+
+private:
+    std::array<uint8_t, storageSize> m_storage;
+};
+
+template<typename T>
+class Packed<T*> : public PackedAlignedPtr<T, 1> {
+public:
+    using Base = PackedAlignedPtr<T, 1>;
+    using Base::Base;
+};
+
+template<typename T>
+using PackedPtr = Packed<T*>;
+
+template<typename T>
+struct PackedPtrTraits {
+    template<typename U> using RebindTraits = PackedPtrTraits<U>;
+
+    using StorageType = PackedPtr<T>;
+
+    template<class U> static ALWAYS_INLINE T* exchange(StorageType& ptr, U&& newValue) { return ptr.exchange(newValue); }
+
+    template<typename Other> static ALWAYS_INLINE void swap(PackedPtr<T>& a, Other& b) { a.swap(b); }
+
+    static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr.get(); }
+};
+
+} // namespace WTF
+
+using WTF::Packed;
+using WTF::PackedAlignedPtr;
+using WTF::PackedPtr;
</ins></span></pre></div>
<a id="trunkSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Platform.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Platform.h  2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/Platform.h     2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -747,6 +747,17 @@
</span><span class="cx"> #define USE_SYSTEM_MALLOC 1
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if CPU(ADDRESS64)
+#if OS(DARWIN) && CPU(ARM64)
+#define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 36
+#else
+/* We strongly assume that effective address width is <= 48 in 64bit architectures (e.g. NaN boxing). */
+#define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 48
+#endif
+#else
+#define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 32
+#endif
+
</ins><span class="cx"> #if !defined(USE_JSVALUE64) && !defined(USE_JSVALUE32_64)
</span><span class="cx"> #if CPU(ADDRESS64) || CPU(ARM64)
</span><span class="cx"> #define USE_JSVALUE64 1
</span></span></pre></div>
<a id="trunkSourceWTFwtfSentinelLinkedListh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/SentinelLinkedList.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/SentinelLinkedList.h        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/SentinelLinkedList.h   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -36,31 +36,29 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include <wtf/Packed.h>
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> enum SentinelTag { Sentinel };
</span><span class="cx"> 
</span><del>-template<typename T>
</del><ins>+template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>>
</ins><span class="cx"> class BasicRawSentinelNode {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><ins>+    using PtrTraits = typename PassedPtrTraits::template RebindTraits<BasicRawSentinelNode>;
+
</ins><span class="cx">     BasicRawSentinelNode(SentinelTag)
</span><del>-        : m_next(0)
-        , m_prev(0)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    BasicRawSentinelNode()
-        : m_next(0)
-        , m_prev(0)
-    {
-    }
</del><ins>+    BasicRawSentinelNode() = default;
</ins><span class="cx">     
</span><span class="cx">     void setPrev(BasicRawSentinelNode* prev) { m_prev = prev; }
</span><span class="cx">     void setNext(BasicRawSentinelNode* next) { m_next = next; }
</span><span class="cx">     
</span><del>-    T* prev() { return static_cast<T*>(m_prev); }
-    T* next() { return static_cast<T*>(m_next); }
</del><ins>+    T* prev() { return static_cast<T*>(PtrTraits::unwrap(m_prev)); }
+    T* next() { return static_cast<T*>(PtrTraits::unwrap(m_next)); }
</ins><span class="cx">     
</span><span class="cx">     bool isOnList() const
</span><span class="cx">     {
</span><span class="lines">@@ -74,8 +72,8 @@
</span><span class="cx">     void append(BasicRawSentinelNode*);
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    BasicRawSentinelNode* m_next;
-    BasicRawSentinelNode* m_prev;
</del><ins>+    typename PtrTraits::StorageType m_next { nullptr };
+    typename PtrTraits::StorageType m_prev { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template <typename T, typename RawNode = T> class SentinelLinkedList {
</span><span class="lines">@@ -118,20 +116,20 @@
</span><span class="cx">     RawNode m_tailSentinel;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template <typename T> void BasicRawSentinelNode<T>::remove()
</del><ins>+template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::remove()
</ins><span class="cx"> {
</span><del>-    SentinelLinkedList<T, BasicRawSentinelNode<T>>::remove(static_cast<T*>(this));
</del><ins>+    SentinelLinkedList<T, BasicRawSentinelNode>::remove(static_cast<T*>(this));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template <typename T> void BasicRawSentinelNode<T>::prepend(BasicRawSentinelNode* node)
</del><ins>+template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::prepend(BasicRawSentinelNode* node)
</ins><span class="cx"> {
</span><del>-    SentinelLinkedList<T, BasicRawSentinelNode<T>>::prepend(
</del><ins>+    SentinelLinkedList<T, BasicRawSentinelNode>::prepend(
</ins><span class="cx">         static_cast<T*>(this), static_cast<T*>(node));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template <typename T> void BasicRawSentinelNode<T>::append(BasicRawSentinelNode* node)
</del><ins>+template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::append(BasicRawSentinelNode* node)
</ins><span class="cx"> {
</span><del>-    SentinelLinkedList<T, BasicRawSentinelNode<T>>::append(
</del><ins>+    SentinelLinkedList<T, BasicRawSentinelNode>::append(
</ins><span class="cx">         static_cast<T*>(this), static_cast<T*>(node));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -140,10 +138,10 @@
</span><span class="cx">     , m_tailSentinel(Sentinel)
</span><span class="cx"> {
</span><span class="cx">     m_headSentinel.setNext(&m_tailSentinel);
</span><del>-    m_headSentinel.setPrev(0);
</del><ins>+    m_headSentinel.setPrev(nullptr);
</ins><span class="cx"> 
</span><span class="cx">     m_tailSentinel.setPrev(&m_headSentinel);
</span><del>-    m_tailSentinel.setNext(0);
</del><ins>+    m_tailSentinel.setNext(nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template <typename T, typename RawNode> inline typename SentinelLinkedList<T, RawNode>::iterator SentinelLinkedList<T, RawNode>::begin()
</span><span class="lines">@@ -200,8 +198,8 @@
</span><span class="cx">     prev->setNext(next);
</span><span class="cx">     next->setPrev(prev);
</span><span class="cx">     
</span><del>-    node->setPrev(0);
-    node->setNext(0);
</del><ins>+    node->setPrev(nullptr);
+    node->setNext(nullptr);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template <typename T, typename RawNode>
</span><span class="lines">@@ -271,7 +269,11 @@
</span><span class="cx">     other.m_tailSentinel.setPrev(&other.m_headSentinel);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template<typename T>
+using PackedRawSentinelNode = BasicRawSentinelNode<T, PackedPtrTraits<T>>;
+
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> using WTF::BasicRawSentinelNode;
</span><ins>+using WTF::PackedRawSentinelNode;
</ins><span class="cx"> using WTF::SentinelLinkedList;
</span></span></pre></div>
<a id="trunkSourceWTFwtfStdLibExtrash"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/StdLibExtras.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/StdLibExtras.h      2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/StdLibExtras.h 2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -172,16 +172,12 @@
</span><span class="cx"> #endif
</span><span class="cx"> #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array))
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl0(size_t remainderMask, size_t x)
</del><ins>+ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl(size_t divisor, size_t x)
</ins><span class="cx"> {
</span><ins>+    size_t remainderMask = divisor - 1;
</ins><span class="cx">     return (x + remainderMask) & ~remainderMask;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl(size_t divisor, size_t x)
-{
-    return roundUpToMultipleOfImpl0(divisor - 1, x);
-}
-
</del><span class="cx"> // Efficient implementation that takes advantage of powers of two.
</span><span class="cx"> inline size_t roundUpToMultipleOf(size_t divisor, size_t x)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWTFwtfUnalignedAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/UnalignedAccess.h (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/UnalignedAccess.h   2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Source/WTF/wtf/UnalignedAccess.h      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -31,20 +31,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-template<typename IntegralType>
-inline IntegralType unalignedLoad(const void* pointer)
</del><ins>+template<typename Type>
+inline Type unalignedLoad(const void* pointer)
</ins><span class="cx"> {
</span><del>-    static_assert(std::is_integral<IntegralType>::value || std::is_pointer<IntegralType>::value, "");
-    IntegralType result { };
-    memcpy(&result, pointer, sizeof(IntegralType));
</del><ins>+    static_assert(std::is_trivial<Type>::value, "");
+    Type result { };
+    memcpy(&result, pointer, sizeof(Type));
</ins><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template<typename IntegralType>
-inline void unalignedStore(void* pointer, IntegralType value)
</del><ins>+template<typename Type>
+inline void unalignedStore(void* pointer, Type value)
</ins><span class="cx"> {
</span><del>-    static_assert(std::is_integral<IntegralType>::value || std::is_pointer<IntegralType>::value, "");
-    memcpy(pointer, &value, sizeof(IntegralType));
</del><ins>+    static_assert(std::is_trivial<Type>::value, "");
+    memcpy(pointer, &value, sizeof(Type));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Tools/ChangeLog       2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2019-05-12  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Compress Watchpoint size by using enum type and Packed<> data structure
+        https://bugs.webkit.org/show_bug.cgi?id=197730
+
+        Reviewed by Filip Pizlo.
+
+        * TestWebKitAPI/CMakeLists.txt:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/MathExtras.cpp:
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/Tests/WTF/Packed.cpp: Added.
+        (TestWebKitAPI::TEST):
+
</ins><span class="cx"> 2019-05-10  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, fix ProcessSwap.OpenerLinkAfterAPIControlledProcessSwappingOfOpener API test
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPICMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/CMakeLists.txt (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/CMakeLists.txt 2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Tools/TestWebKitAPI/CMakeLists.txt    2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx">     Tests/WTF/NeverDestroyed.cpp
</span><span class="cx">     Tests/WTF/OptionSet.cpp
</span><span class="cx">     Tests/WTF/Optional.cpp
</span><ins>+    Tests/WTF/Packed.cpp
</ins><span class="cx">     Tests/WTF/ParkingLot.cpp
</span><span class="cx">     Tests/WTF/PriorityQueue.cpp
</span><span class="cx">     Tests/WTF/RedBlackTree.cpp
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj   2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -860,6 +860,7 @@
</span><span class="cx">          E1220DCA155B28AA0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E1220DC9155B287D0013E2FC /* MemoryCacheDisableWithinResourceLoadDelegate.html */; };
</span><span class="cx">          E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; };
</span><span class="cx">          E324A6F02041C82000A76593 /* UniqueArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E398BC0F2041C76300387136 /* UniqueArray.cpp */; };
</span><ins>+               E32B549222810AC4008AD702 /* Packed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E32B549122810AC0008AD702 /* Packed.cpp */; };
</ins><span class="cx">           E373D7911F2CF35200C6FAAF /* Signals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3953F951F2CF32100A76A2E /* Signals.cpp */; };
</span><span class="cx">          E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38A0D341FD50CBC00E98C8B /* Threading.cpp */; };
</span><span class="cx">          E3A1E77F21B25B39008C6007 /* URLParserTextEncoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3A1E77E21B25B39008C6007 /* URLParserTextEncoding.cpp */; };
</span><span class="lines">@@ -2231,6 +2232,7 @@
</span><span class="cx">          E194E1BA177E5145009C4D4E /* StopLoadingFromDidReceiveResponse.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = StopLoadingFromDidReceiveResponse.mm; sourceTree = "<group>"; };
</span><span class="cx">          E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = StopLoadingFromDidReceiveResponse.html; sourceTree = "<group>"; };
</span><span class="cx">          E19DB9781B32137C00DB38D4 /* NavigatorLanguage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigatorLanguage.mm; sourceTree = "<group>"; };
</span><ins>+               E32B549122810AC0008AD702 /* Packed.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Packed.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           E388887020C9098100E632BC /* WorkerPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerPool.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E38A0D341FD50CBC00E98C8B /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E3953F951F2CF32100A76A2E /* Signals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Signals.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -3349,6 +3351,7 @@
</span><span class="cx">                          A57D54F21F338C3600A97AA7 /* NeverDestroyed.cpp */,
</span><span class="cx">                          1AFDE6541953B2C000C48FFA /* Optional.cpp */,
</span><span class="cx">                          CE50D8C81C8665CE0072EA5A /* OptionSet.cpp */,
</span><ins>+                               E32B549122810AC0008AD702 /* Packed.cpp */,
</ins><span class="cx">                           0FE447971B76F1E3009498EB /* ParkingLot.cpp */,
</span><span class="cx">                          53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */,
</span><span class="cx">                          0FC6C4CB141027E0005B7F0C /* RedBlackTree.cpp */,
</span><span class="lines">@@ -3962,6 +3965,7 @@
</span><span class="cx">                          7C83DF011D0A590C00FEBCF3 /* Optional.cpp in Sources */,
</span><span class="cx">                          1A77BAA31D9AFFFC005FC568 /* OptionSet.cpp in Sources */,
</span><span class="cx">                          7C83DF021D0A590C00FEBCF3 /* OSObjectPtr.cpp in Sources */,
</span><ins>+                               E32B549222810AC4008AD702 /* Packed.cpp in Sources */,
</ins><span class="cx">                           7C83DF591D0A590C00FEBCF3 /* ParkingLot.cpp in Sources */,
</span><span class="cx">                          53EC25411E96FD87000831B9 /* PriorityQueue.cpp in Sources */,
</span><span class="cx">                          7C83DF131D0A590C00FEBCF3 /* RedBlackTree.cpp in Sources */,
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFMathExtrascpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp (245213 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp       2019-05-12 19:43:16 UTC (rev 245213)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp  2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -507,4 +507,78 @@
</span><span class="cx">     EXPECT_EQ(WTF::getMSBSet<uint64_t>(42), 5U);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+TEST(WTF, clzConstexpr)
+{
+    EXPECT_EQ(WTF::clzConstexpr<int32_t>(1), 31U);
+    EXPECT_EQ(WTF::clzConstexpr<int32_t>(42), 26U);
+    EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U);
+    EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 1U);
+    EXPECT_EQ(WTF::clzConstexpr<uint32_t>(0), 32U);
+
+    EXPECT_EQ(WTF::clzConstexpr<int8_t>(42), 2U);
+    EXPECT_EQ(WTF::clzConstexpr<int8_t>(3), 6U);
+    EXPECT_EQ(WTF::clzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U);
+    EXPECT_EQ(WTF::clzConstexpr<uint8_t>(0), 8U);
+
+    EXPECT_EQ(WTF::clzConstexpr<int64_t>(-1), 0U);
+    EXPECT_EQ(WTF::clzConstexpr<int64_t>(1), 63U);
+    EXPECT_EQ(WTF::clzConstexpr<int64_t>(3), 62U);
+    EXPECT_EQ(WTF::clzConstexpr<uint64_t>(42), 58U);
+    EXPECT_EQ(WTF::clzConstexpr<uint64_t>(0), 64U);
+}
+
+TEST(WTF, ctzConstexpr)
+{
+    EXPECT_EQ(WTF::ctzConstexpr<int32_t>(1), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<int32_t>(42), 1U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(0), 32U);
+
+    EXPECT_EQ(WTF::ctzConstexpr<int8_t>(42), 1U);
+    EXPECT_EQ(WTF::ctzConstexpr<int8_t>(3), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(0), 8U);
+
+    EXPECT_EQ(WTF::ctzConstexpr<int64_t>(static_cast<uint32_t>(-1)), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<int64_t>(1), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<int64_t>(3), 0U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(42), 1U);
+    EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(0), 64U);
+}
+
+TEST(WTF, getLSBSetConstexpr)
+{
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(1), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(42), 1U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U);
+
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(42), 1U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(3), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U);
+
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(-1), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(1), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(3), 0U);
+    EXPECT_EQ(WTF::getLSBSetConstexpr<uint64_t>(42), 1U);
+}
+
+TEST(WTF, getMSBSetConstexpr)
+{
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(1), 0U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(42), 5U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 31U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U);
+
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(42), 5U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(3), 1U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 7U);
+
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(-1), 63U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(1), 0U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(3), 1U);
+    EXPECT_EQ(WTF::getMSBSetConstexpr<uint64_t>(42), 5U);
+}
+
</ins><span class="cx"> } // namespace TestWebKitAPI
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFPackedcpp"></a>
<div class="addfile"><h4>Added: trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp (0 => 245214)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp                           (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Packed.cpp      2019-05-12 22:50:21 UTC (rev 245214)
</span><span class="lines">@@ -0,0 +1,85 @@
</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. AND ITS CONTRIBUTORS ``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 ITS 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 <wtf/Packed.h>
+
+namespace TestWebKitAPI {
+
+struct PackedPair {
+    PackedPtr<uint8_t> key { nullptr };
+    PackedPtr<uint8_t> value { nullptr };
+};
+
+TEST(WTF_Packed, StructSize)
+{
+    EXPECT_EQ(alignof(PackedPair), 1U);
+#if CPU(X86_64)
+    EXPECT_EQ(sizeof(PackedPair), 12U);
+#endif
+    {
+        Packed<double> value;
+        value = 4.2;
+        EXPECT_EQ(value.get(), 4.2);
+    }
+    {
+        uint64_t originalValue = 0xff00ff00dd00dd00UL;
+        Packed<uint64_t> value;
+        value = originalValue;
+        EXPECT_EQ(value.get(), originalValue);
+        EXPECT_EQ(alignof(Packed<uint64_t>), 1U);
+        EXPECT_EQ(sizeof(Packed<uint64_t>), sizeof(uint64_t));
+    }
+}
+
+TEST(WTF_Packed, AssignAndGet)
+{
+    {
+        PackedPtr<uint8_t> key { nullptr };
+        static_assert(WTF_CPU_EFFECTIVE_ADDRESS_WIDTH != 64, "");
+        uint8_t* max = bitwise_cast<uint8_t*>(static_cast<uintptr_t>(((1ULL) << WTF_CPU_EFFECTIVE_ADDRESS_WIDTH) - 1));
+        key = max;
+        EXPECT_EQ(key.get(), max);
+    }
+}
+
+TEST(WTF_Packed, PackedAlignedPtr)
+{
+    {
+        PackedAlignedPtr<uint8_t, 256> key { nullptr };
+        EXPECT_LE(sizeof(key), 5U);
+    }
+    {
+        PackedAlignedPtr<uint8_t, 16> key { nullptr };
+#if OS(DARWIN) && CPU(ARM64)
+        EXPECT_EQ(sizeof(key), 4U);
+#else
+        EXPECT_LE(sizeof(key), 6U);
+#endif
+    }
+}
+
+} // namespace TestWebKitAPI
</ins></span></pre>
</div>
</div>

</body>
</html>