<!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>[218992] trunk/Source</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/218992">218992</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2017-06-30 01:23:18 -0700 (Fri, 30 Jun 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG_ASSERT should allow stuffing registers before trapping.
https://bugs.webkit.org/show_bug.cgi?id=174005

Reviewed by Mark Lam.

Source/JavaScriptCore:

DFG_ASSERT currently prints error data to stderr before crashing,
which is nice for local development. In the wild, however, we
can't see this information in crash logs. This patch enables
stuffing some of the most useful information from DFG_ASSERTS into
up to five registers right before crashing. The values stuffed
should not impact any logging during local development.

* assembler/AbortReason.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::verifyEdge):
* dfg/DFGGraph.cpp:
(JSC::DFG::logForCrash):
(JSC::DFG::Graph::logAssertionFailure):
(JSC::DFG::crash): Deleted.
(JSC::DFG::Graph::handleAssertionFailure): Deleted.
* dfg/DFGGraph.h:

Source/WTF:

Add new template functions that enable stuffing up to five values
into registers before crashing.

* wtf/Assertions.h:
(CRASH_WITH_INFO):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerAbortReasonh">trunk/Source/JavaScriptCore/assembler/AbortReason.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphh">trunk/Source/JavaScriptCore/dfg/DFGGraph.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfAssertionsh">trunk/Source/WTF/wtf/Assertions.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/JavaScriptCore/ChangeLog       2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2017-06-30  Keith Miller  <keith_miller@apple.com>
+
+        DFG_ASSERT should allow stuffing registers before trapping.
+        https://bugs.webkit.org/show_bug.cgi?id=174005
+
+        Reviewed by Mark Lam.
+
+        DFG_ASSERT currently prints error data to stderr before crashing,
+        which is nice for local development. In the wild, however, we
+        can't see this information in crash logs. This patch enables
+        stuffing some of the most useful information from DFG_ASSERTS into
+        up to five registers right before crashing. The values stuffed
+        should not impact any logging during local development.
+
+        * assembler/AbortReason.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::verifyEdge):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::logForCrash):
+        (JSC::DFG::Graph::logAssertionFailure):
+        (JSC::DFG::crash): Deleted.
+        (JSC::DFG::Graph::handleAssertionFailure): Deleted.
+        * dfg/DFGGraph.h:
+
</ins><span class="cx"> 2017-06-29  Saam Barati  <sbarati@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Calculating postCapacity in unshiftCountSlowCase is wrong
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerAbortReasonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/AbortReason.h (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/AbortReason.h      2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/JavaScriptCore/assembler/AbortReason.h 2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -76,4 +76,9 @@
</span><span class="cx">     YARRNoInputConsumed                               = 340,
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// See above for comment on numbering. This enum is for crashes during compilation.
+enum CompilationAbortReason {
+    AIEdgeVerificationFailed                          = 10,
+};
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h  2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h     2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -130,8 +130,8 @@
</span><span class="cx"> {
</span><span class="cx">     if (!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())))
</span><span class="cx">         return;
</span><del>-    
-    DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data());
</del><ins>+
+    DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type), " (", forNode(edge).m_type, ")").data(), AIEdgeVerificationFailed, node->op(), edge->op(), forNode(edge).m_type, typeFilterFor(edge.useKind()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template<typename AbstractStateType>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp     2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -1438,7 +1438,7 @@
</span><span class="cx">     DFG_CRASH(*this, nullptr, toCString("Structure ", pointerDump(structure), " is watchable but isn't being watched.").data());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NO_RETURN_DUE_TO_CRASH static void crash(
</del><ins>+static void logForCrash(
</ins><span class="cx">     Graph& graph, const CString& whileText, const char* file, int line, const char* function,
</span><span class="cx">     const char* assertion)
</span><span class="cx"> {
</span><span class="lines">@@ -1452,25 +1452,25 @@
</span><span class="cx">     dataLog("\n");
</span><span class="cx">     dataLog("DFG ASSERTION FAILED: ", assertion, "\n");
</span><span class="cx">     dataLog(file, "(", line, ") : ", function, "\n");
</span><del>-    CRASH_WITH_SECURITY_IMPLICATION();
</del><ins>+    WTFReportBacktrace();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Graph::handleAssertionFailure(
</del><ins>+void Graph::logAssertionFailure(
</ins><span class="cx">     std::nullptr_t, const char* file, int line, const char* function, const char* assertion)
</span><span class="cx"> {
</span><del>-    crash(*this, "", file, line, function, assertion);
</del><ins>+    logForCrash(*this, "", file, line, function, assertion);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Graph::handleAssertionFailure(
</del><ins>+void Graph::logAssertionFailure(
</ins><span class="cx">     Node* node, const char* file, int line, const char* function, const char* assertion)
</span><span class="cx"> {
</span><del>-    crash(*this, toCString("While handling node ", node, "\n\n"), file, line, function, assertion);
</del><ins>+    logForCrash(*this, toCString("While handling node ", node, "\n\n"), file, line, function, assertion);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Graph::handleAssertionFailure(
</del><ins>+void Graph::logAssertionFailure(
</ins><span class="cx">     BasicBlock* block, const char* file, int line, const char* function, const char* assertion)
</span><span class="cx"> {
</span><del>-    crash(*this, toCString("While handling block ", pointerDump(block), "\n\n"), file, line, function, assertion);
</del><ins>+    logForCrash(*this, toCString("While handling block ", pointerDump(block), "\n\n"), file, line, function, assertion);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Dominators& Graph::ensureDominators()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.h (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.h       2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.h  2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -93,16 +93,18 @@
</span><span class="cx">         }                                                               \
</span><span class="cx">     } while (false)
</span><span class="cx"> 
</span><del>-#define DFG_ASSERT(graph, node, assertion) do {                         \
</del><ins>+#define DFG_ASSERT(graph, node, assertion, ...) do {                    \
</ins><span class="cx">         if (!!(assertion))                                              \
</span><span class="cx">             break;                                                      \
</span><del>-        (graph).handleAssertionFailure(                                 \
</del><ins>+        (graph).logAssertionFailure(                                 \
</ins><span class="cx">             (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
</span><ins>+        CRASH_WITH_INFO(__VA_ARGS__);                                       \
</ins><span class="cx">     } while (false)
</span><span class="cx"> 
</span><del>-#define DFG_CRASH(graph, node, reason) do {                             \
-        (graph).handleAssertionFailure(                                 \
</del><ins>+#define DFG_CRASH(graph, node, reason, ...) do {                        \
+        (graph).logAssertionFailure(                                 \
</ins><span class="cx">             (node), __FILE__, __LINE__, WTF_PRETTY_FUNCTION, (reason)); \
</span><ins>+        CRASH_WITH_INFO(__VA_ARGS__);                                       \
</ins><span class="cx">     } while (false)
</span><span class="cx"> 
</span><span class="cx"> struct InlineVariableData {
</span><span class="lines">@@ -886,14 +888,15 @@
</span><span class="cx">     void registerFrozenValues();
</span><span class="cx">     
</span><span class="cx">     void visitChildren(SlotVisitor&) override;
</span><del>-    
-    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
</del><ins>+
+    // These should not be called directly. Instead they should be called through the DFG_CRASH/DFG_ASSERT macros.
+    void logAssertionFailure(
</ins><span class="cx">         std::nullptr_t, const char* file, int line, const char* function,
</span><span class="cx">         const char* assertion);
</span><del>-    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
</del><ins>+    void logAssertionFailure(
</ins><span class="cx">         Node*, const char* file, int line, const char* function,
</span><span class="cx">         const char* assertion);
</span><del>-    NO_RETURN_DUE_TO_CRASH void handleAssertionFailure(
</del><ins>+    void logAssertionFailure(
</ins><span class="cx">         BasicBlock*, const char* file, int line, const char* function,
</span><span class="cx">         const char* assertion);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/WTF/ChangeLog  2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2017-06-30  Keith Miller  <keith_miller@apple.com>
+
+        DFG_ASSERT should allow stuffing registers before trapping.
+        https://bugs.webkit.org/show_bug.cgi?id=174005
+
+        Reviewed by Mark Lam.
+
+        Add new template functions that enable stuffing up to five values
+        into registers before crashing.
+
+        * wtf/Assertions.h:
+        (CRASH_WITH_INFO):
+
</ins><span class="cx"> 2017-06-28  Brent Fulgham  <bfulgham@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Teach ResourceLoadStatistics to recognize changes in the file system
</span></span></pre></div>
<a id="trunkSourceWTFwtfAssertionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Assertions.h (218991 => 218992)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Assertions.h        2017-06-30 07:48:37 UTC (rev 218991)
+++ trunk/Source/WTF/wtf/Assertions.h   2017-06-30 08:23:18 UTC (rev 218992)
</span><span class="lines">@@ -465,5 +465,102 @@
</span><span class="cx"> #define UNREACHABLE_FOR_PLATFORM() RELEASE_ASSERT_NOT_REACHED()
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#ifndef INLINE_CRASH_WITH_SECURITY_IMPLICATION
+// This is useful if you are going to stuff data into registers before crashing. Like the CRASH_WITH_INFO functions below...
+#define INLINE_CRASH_WITH_SECURITY_IMPLICATION() CRASH()
+#endif
</ins><span class="cx"> 
</span><ins>+#ifdef __cplusplus
+
+#if OS(DARWIN) && (CPU(X64_64) || CPU(ARM64))
+#if CPU(X86_64)
+#define STUFF_REGISTER_FOR_CRASH(reg, value) \
+    static_assert(std::is_integral<decltype(value)>::value, "STUFF_REGISTERS_FOR_CRASH expects an integral input"); \
+    __asm__ volatile ("movq %0, %%" reg : : "r" (static_cast<uint64_t>(value)) : reg)
+
+// This ordering was chosen to be consistant with JSC's JIT asserts. We probably shouldn't change this ordering
+// since it would make tooling crash reports much harder. If, for whatever reason, we decide to change the ordering
+// here we should update the abortWithReason functions.
+#define STUFF_FOR_CRASH_REGISTER1 "r11"
+#define STUFF_FOR_CRASH_REGISTER2 "r10"
+#define STUFF_FOR_CRASH_REGISTER3 "r9"
+#define STUFF_FOR_CRASH_REGISTER4 "r8"
+#define STUFF_FOR_CRASH_REGISTER5 "r15"
+
+#elif CPU(ARM64) // CPU(X86_64)
+#define STUFF_REGISTER_FOR_CRASH(reg, value) \
+    static_assert(std::is_integral<decltype(value)>::value, "STUFF_REGISTERS_FOR_CRASH expects an integral input"); \
+    __asm__ volatile ("mov " reg ", %0" : : "r" (static_cast<uint64_t>(value)) : reg)
+
+// See comment above on the ordering.
+#define STUFF_FOR_CRASH_REGISTER1 "x16"
+#define STUFF_FOR_CRASH_REGISTER2 "x17"
+#define STUFF_FOR_CRASH_REGISTER3 "x18"
+#define STUFF_FOR_CRASH_REGISTER4 "x19"
+#define STUFF_FOR_CRASH_REGISTER5 "x20"
+
+#endif // CPU(ARM64)
+
+template<typename Reason, typename A, typename B, typename C, typename D>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Reason reason, A misc1, B misc2, C misc3, D misc4)
+{
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER5, misc4);
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+template<typename Reason, typename A, typename B, typename C>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Reason reason, A misc1, B misc2, C misc3)
+{
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3);
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+template<typename Reason, typename A, typename B>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Reason reason, A misc1, B misc2)
+{
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+template<typename Reason, typename A>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Reason reason, A misc1)
+{
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+template<typename Reason>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Reason reason)
+{
+    STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO()
+{
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+#else // OS(DARWIN) && (CPU(X64_64) || CPU(ARM64))
+
+template<typename... Types>
+ALWAYS_INLINE NO_RETURN_DUE_TO_CRASH void CRASH_WITH_INFO(Types...)
+{
+    INLINE_CRASH_WITH_SECURITY_IMPLICATION();
+}
+
+#endif // OS(DARWIN) && (CPU(X64_64) || CPU(ARM64))
+
+#endif // __cplusplus
+
</ins><span class="cx"> #endif /* WTF_Assertions_h */
</span></span></pre>
</div>
</div>

</body>
</html>