Changeset 234335 in webkit


Ignore:
Timestamp:
Jul 27, 2018, 3:44:47 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Add some crash info to Heap::checkConn() RELEASE_ASSERTs.
https://bugs.webkit.org/show_bug.cgi?id=188123
<rdar://problem/42672268>

Reviewed by Keith Miller.

Source/JavaScriptCore:

  1. Add VM::m_id and Heap::m_lastPhase fields. Both of these fit within existing padding space in VM and Heap, and should not cost any measurable perf to initialize and update.
  1. Add some crash info to the RELEASE_ASSERTs in Heap::checkConn():

worldState tells us the value we failed the assertion on.

m_lastPhase, m_currentPhase, and m_nextPhase tells us the GC phase transition
that led us here.

VM::id(), and VM::numberOfIDs() tells us how many VMs may be in play.

VM::isEntered() tells us if the current VM is currently executing JS code.

Some of this data may be redundant, but the redundancy is intentional so that
we can double check what is really happening at the time of crash.

  • heap/Heap.cpp:

(JSC::asInt):
(JSC::Heap::checkConn):
(JSC::Heap::changePhase):

  • heap/Heap.h:
  • runtime/VM.cpp:

(JSC::VM::nextID):
(JSC::VM::VM):

  • runtime/VM.h:

(JSC::VM::numberOfIDs):
(JSC::VM::id const):
(JSC::VM::isEntered const):

Source/WTF:

  1. Rename STUFF_FOR_CRASH_REGISTERx to CRASH_GPRx. These are only used in locally in Assertions.cpp. There is little to no chance of a name collision, and the shorter names will be much easier to read and grok in the code.
  1. Added an additional 2 registers so that we can pass more info.
  1. Change the WTFCrashWithInfo() implementations to issue only a single asm statement so that the compiler does not inadvertently move values out of the CRASH_GPRs that we want them to be in.
  1. Use register targeting for local variables to get the compiler to put our desired values in specific registers. For how this works, see https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables

"The only supported use for this feature is to specify registers for input and
output operands when calling Extended asm (see Extended Asm). This may be
necessary if the constraints for a particular machine don’t provide sufficient
control to select the desired register."

  1. Enhance ASSERT, ASSERT_UNUSED, RELEASE_ASSERT, RELEASE_ASSERT_NOT_REACHED to accept crash info arguments. We no longer need to use an if statement with a call to CRASH_WITH_INFO instead of these assertions. The only case not handled yet is one where we might want to dataLog some info before the crash. I'll add that functionality in a subsequent patch.
  1. Move UNREACHABLE_FOR_PLATFORM to the bottom of Assertions.h because it depends on the definition of RELEASE_ASSERT_NOT_REACHED, which now depends on the definiton of CRASH_WITH_INFO.
  • wtf/Assertions.cpp:

(WTFCrashWithInfo):

  • wtf/Assertions.h:
Location:
trunk/Source
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r234331 r234335  
     12018-07-27  Mark Lam  <mark.lam@apple.com>
     2
     3        Add some crash info to Heap::checkConn() RELEASE_ASSERTs.
     4        https://bugs.webkit.org/show_bug.cgi?id=188123
     5        <rdar://problem/42672268>
     6
     7        Reviewed by Keith Miller.
     8
     9        1. Add VM::m_id and Heap::m_lastPhase fields.  Both of these fit within existing
     10           padding space in VM and Heap, and should not cost any measurable perf to
     11           initialize and update.
     12
     13        2. Add some crash info to the RELEASE_ASSERTs in Heap::checkConn():
     14
     15           worldState tells us the value we failed the assertion on.
     16
     17           m_lastPhase, m_currentPhase, and m_nextPhase tells us the GC phase transition
     18           that led us here.
     19
     20           VM::id(), and VM::numberOfIDs() tells us how many VMs may be in play.
     21
     22           VM::isEntered() tells us if the current VM is currently executing JS code.
     23
     24           Some of this data may be redundant, but the redundancy is intentional so that
     25           we can double check what is really happening at the time of crash.
     26
     27        * heap/Heap.cpp:
     28        (JSC::asInt):
     29        (JSC::Heap::checkConn):
     30        (JSC::Heap::changePhase):
     31        * heap/Heap.h:
     32        * runtime/VM.cpp:
     33        (JSC::VM::nextID):
     34        (JSC::VM::VM):
     35        * runtime/VM.h:
     36        (JSC::VM::numberOfIDs):
     37        (JSC::VM::id const):
     38        (JSC::VM::isEntered const):
     39
    1402018-07-25  Yusuke Suzuki  <utatane.tea@gmail.com>
    241
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r233765 r234335  
    11221122}
    11231123
     1124ALWAYS_INLINE int asInt(CollectorPhase phase)
     1125{
     1126    return static_cast<int>(phase);
     1127}
     1128
    11241129void Heap::checkConn(GCConductor conn)
    11251130{
     1131    unsigned worldState = m_worldState.load();
    11261132    switch (conn) {
    11271133    case GCConductor::Mutator:
    1128         RELEASE_ASSERT(m_worldState.load() & mutatorHasConnBit);
     1134        RELEASE_ASSERT(worldState & mutatorHasConnBit, worldState, asInt(m_lastPhase), asInt(m_currentPhase), asInt(m_nextPhase), vm()->id(), VM::numberOfIDs(), vm()->isEntered());
    11291135        return;
    11301136    case GCConductor::Collector:
    1131         RELEASE_ASSERT(!(m_worldState.load() & mutatorHasConnBit));
     1137        RELEASE_ASSERT(!(worldState & mutatorHasConnBit), worldState, asInt(m_lastPhase), asInt(m_currentPhase), asInt(m_nextPhase), vm()->id(), VM::numberOfIDs(), vm()->isEntered());
    11321138        return;
    11331139    }
     
    15201526    checkConn(conn);
    15211527
     1528    m_lastPhase = m_currentPhase;
    15221529    m_nextPhase = nextPhase;
    15231530
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r233123 r234335  
    694694    Ticket m_lastServedTicket { 0 };
    695695    Ticket m_lastGrantedTicket { 0 };
     696    CollectorPhase m_lastPhase { CollectorPhase::NotRunning };
    696697    CollectorPhase m_currentPhase { CollectorPhase::NotRunning };
    697698    CollectorPhase m_nextPhase { CollectorPhase::NotRunning };
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r234171 r234335  
    183183#endif
    184184
     185Atomic<unsigned> VM::s_numberOfIDs;
     186
    185187// Note: Platform.h will enforce that ENABLE(ASSEMBLER) is true if either
    186188// ENABLE(JIT) or ENABLE(YARR_JIT) or both are enabled. The code below
     
    248250}
    249251
     252inline unsigned VM::nextID()
     253{
     254    for (;;) {
     255        unsigned currentNumberOfIDs = s_numberOfIDs.load();
     256        unsigned newID = currentNumberOfIDs + 1;
     257        if (s_numberOfIDs.compareExchangeWeak(currentNumberOfIDs, newID))
     258            return newID;
     259    }
     260}
     261
     262
    250263VM::VM(VMType vmType, HeapType heapType)
    251     : m_apiLock(adoptRef(new JSLock(this)))
     264    : m_id(nextID())
     265    , m_apiLock(adoptRef(new JSLock(this)))
    252266#if USE(CF)
    253267    , m_runLoop(CFRunLoopGetCurrent())
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r234171 r234335  
    290290#endif
    291291
     292    static unsigned numberOfIDs() { return s_numberOfIDs.load(); }
     293    unsigned id() const { return m_id; }
     294    bool isEntered() const { return !!entryScope; }
     295
    292296private:
     297    unsigned nextID();
     298
     299    static Atomic<unsigned> s_numberOfIDs;
     300
     301    unsigned m_id;
    293302    RefPtr<JSLock> m_apiLock;
    294303#if USE(CF)
  • trunk/Source/WTF/ChangeLog

    r234332 r234335  
     12018-07-27  Mark Lam  <mark.lam@apple.com>
     2
     3        Add some crash info to Heap::checkConn() RELEASE_ASSERTs.
     4        https://bugs.webkit.org/show_bug.cgi?id=188123
     5        <rdar://problem/42672268>
     6
     7        Reviewed by Keith Miller.
     8
     9        1. Rename STUFF_FOR_CRASH_REGISTERx to CRASH_GPRx.  These are only used in
     10           locally in Assertions.cpp.  There is little to no chance of a name collision,
     11           and the shorter names will be much easier to read and grok in the code.
     12
     13        2. Added an additional 2 registers so that we can pass more info.
     14
     15        3. Change the WTFCrashWithInfo() implementations to issue only a single asm
     16           statement so that the compiler does not inadvertently move values out of the
     17           CRASH_GPRs that we want them to be in.
     18
     19        4. Use register targeting for local variables to get the compiler to put our
     20           desired values in specific registers.  For how this works, see
     21           https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables
     22
     23           "The only supported use for this feature is to specify registers for input and
     24           output operands when calling Extended asm (see Extended Asm).  This may be
     25           necessary if the constraints for a particular machine don’t provide sufficient
     26           control to select the desired register."
     27
     28        5. Enhance ASSERT, ASSERT_UNUSED, RELEASE_ASSERT, RELEASE_ASSERT_NOT_REACHED to
     29           accept crash info arguments.  We no longer need to use an if statement with a
     30           call to CRASH_WITH_INFO instead of these assertions.  The only case not handled
     31           yet is one where we might want to dataLog some info before the crash.  I'll
     32           add that functionality in a subsequent patch.
     33
     34        6. Move UNREACHABLE_FOR_PLATFORM to the bottom of Assertions.h because it depends
     35           on the definition of RELEASE_ASSERT_NOT_REACHED, which now depends on the
     36           definiton of CRASH_WITH_INFO.
     37
     38        * wtf/Assertions.cpp:
     39        (WTFCrashWithInfo):
     40        * wtf/Assertions.h:
     41
    1422018-07-27  Alex Christensen  <achristensen@webkit.org>
    243
  • trunk/Source/WTF/wtf/Assertions.cpp

    r234278 r234335  
    567567#if OS(DARWIN) && (CPU(X86_64) || CPU(ARM64))
    568568#if CPU(X86_64)
    569 #define STUFF_REGISTER_FOR_CRASH(reg, info) __asm__ volatile ("movq %0, %%" reg : : "r" (static_cast<uint64_t>(info)) : reg)
     569
     570#define CRASH_INST "int3"
    570571
    571572// This ordering was chosen to be consistent with JSC's JIT asserts. We probably shouldn't change this ordering
    572573// since it would make tooling crash reports much harder. If, for whatever reason, we decide to change the ordering
    573574// here we should update the abortWithuint64_t functions.
    574 #define STUFF_FOR_CRASH_REGISTER1 "r11"
    575 #define STUFF_FOR_CRASH_REGISTER2 "r10"
    576 #define STUFF_FOR_CRASH_REGISTER3 "r9"
    577 #define STUFF_FOR_CRASH_REGISTER4 "r8"
    578 #define STUFF_FOR_CRASH_REGISTER5 "r15"
     575#define CRASH_GPR0 "r11"
     576#define CRASH_GPR1 "r10"
     577#define CRASH_GPR2 "r9"
     578#define CRASH_GPR3 "r8"
     579#define CRASH_GPR4 "r15"
     580#define CRASH_GPR5 "r14"
     581#define CRASH_GPR6 "r13"
    579582
    580583#elif CPU(ARM64) // CPU(X86_64)
    581 #define STUFF_REGISTER_FOR_CRASH(reg, info) __asm__ volatile ("mov " reg ", %0" : : "r" (static_cast<uint64_t>(info)) : reg)
     584
     585#define CRASH_INST "brk #0"
    582586
    583587// See comment above on the ordering.
    584 #define STUFF_FOR_CRASH_REGISTER1 "x16"
    585 #define STUFF_FOR_CRASH_REGISTER2 "x17"
    586 #define STUFF_FOR_CRASH_REGISTER3 "x18"
    587 #define STUFF_FOR_CRASH_REGISTER4 "x19"
    588 #define STUFF_FOR_CRASH_REGISTER5 "x20"
     588#define CRASH_GPR0 "x16"
     589#define CRASH_GPR1 "x17"
     590#define CRASH_GPR2 "x18"
     591#define CRASH_GPR3 "x19"
     592#define CRASH_GPR4 "x20"
     593#define CRASH_GPR5 "x21"
     594#define CRASH_GPR6 "x22"
    589595
    590596#endif // CPU(ARM64)
    591597
     598void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6)
     599{
     600    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     601    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     602    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     603    register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
     604    register uint64_t misc4GPR asm(CRASH_GPR4) = misc4;
     605    register uint64_t misc5GPR asm(CRASH_GPR5) = misc5;
     606    register uint64_t misc6GPR asm(CRASH_GPR6) = misc6;
     607    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR), "r"(misc6GPR));
     608    __builtin_unreachable();
     609}
     610
     611void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5)
     612{
     613    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     614    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     615    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     616    register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
     617    register uint64_t misc4GPR asm(CRASH_GPR4) = misc4;
     618    register uint64_t misc5GPR asm(CRASH_GPR5) = misc5;
     619    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR));
     620    __builtin_unreachable();
     621}
     622
    592623void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4)
    593624{
    594     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
    595     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
    596     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
    597     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3);
    598     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER5, misc4);
    599     CRASH();
     625    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     626    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     627    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     628    register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
     629    register uint64_t misc4GPR asm(CRASH_GPR4) = misc4;
     630    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR));
     631    __builtin_unreachable();
    600632}
    601633
    602634void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3)
    603635{
    604     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
    605     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
    606     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
    607     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER4, misc3);
    608     CRASH();
     636    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     637    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     638    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     639    register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
     640    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR));
     641    __builtin_unreachable();
    609642}
    610643
    611644void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1, uint64_t misc2)
    612645{
    613     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
    614     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
    615     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER3, misc2);
    616     CRASH();
     646    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     647    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     648    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     649    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR));
     650    __builtin_unreachable();
    617651}
    618652
    619653void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason, uint64_t misc1)
    620654{
    621     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
    622     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER2, misc1);
    623     CRASH();
     655    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     656    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     657    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR));
     658    __builtin_unreachable();
    624659}
    625660
    626661void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t reason)
    627662{
    628     STUFF_REGISTER_FOR_CRASH(STUFF_FOR_CRASH_REGISTER1, reason);
    629     CRASH();
     663    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     664    __asm__ volatile (CRASH_INST : : "r"(reasonGPR));
     665    __builtin_unreachable();
    630666}
    631667
    632668void WTFCrashWithInfo(int, const char*, const char*, int)
    633669{
    634     CRASH();
     670    __asm__ volatile (CRASH_INST : : );
     671    __builtin_unreachable();
    635672}
    636673
    637674#else
    638675
     676void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); }
     677void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); }
    639678void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); }
    640679void WTFCrashWithInfo(int, const char*, const char*, int, uint64_t, uint64_t, uint64_t, uint64_t) { CRASH(); }
  • trunk/Source/WTF/wtf/Assertions.h

    r233577 r234335  
    290290#if ASSERT_DISABLED
    291291
    292 #define ASSERT(assertion) ((void)0)
     292#define ASSERT(assertion, ...) ((void)0)
    293293#define ASSERT_UNDER_CONSTEXPR_CONTEXT(assertion) ((void)0)
    294294#define ASSERT_AT(assertion, file, line, function) ((void)0)
    295 #define ASSERT_NOT_REACHED() ((void)0)
     295#define ASSERT_NOT_REACHED(...) ((void)0)
    296296#define ASSERT_NOT_IMPLEMENTED_YET() ((void)0)
    297297#define ASSERT_IMPLIES(condition, assertion) ((void)0)
    298298#define NO_RETURN_DUE_TO_ASSERT
    299299
    300 #define ASSERT_UNUSED(variable, assertion) ((void)variable)
     300#define ASSERT_UNUSED(variable, assertion, ...) ((void)variable)
    301301
    302302#if ENABLE(SECURITY_ASSERTIONS)
     
    315315#else
    316316
    317 #define ASSERT(assertion) do { \
     317#define ASSERT(assertion, ...) do { \
    318318    if (!(assertion)) { \
    319319        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
    320         CRASH(); \
     320        CRASH_WITH_INFO(__VA_ARGS__); \
    321321    } \
    322322} while (0)
     
    336336} while (0)
    337337
    338 #define ASSERT_NOT_REACHED() do { \
     338#define ASSERT_NOT_REACHED(...) do { \
    339339    WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
    340     CRASH(); \
     340    CRASH_WITH_INFO(__VA_ARGS__); \
    341341} while (0)
    342342
     
    353353} while (0)
    354354
    355 #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
     355#define ASSERT_UNUSED(variable, assertion, ...) ASSERT(assertion, __VA_ARGS__)
    356356
    357357#define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
     
    511511
    512512#if ASSERT_DISABLED
    513 #define RELEASE_ASSERT(assertion) do { \
     513#define RELEASE_ASSERT(assertion, ...) do { \
    514514    if (UNLIKELY(!(assertion))) \
    515         CRASH(); \
     515        CRASH_WITH_INFO(__VA_ARGS__); \
    516516} while (0)
    517517#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
    518518#define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) RELEASE_ASSERT(assertion)
    519 #define RELEASE_ASSERT_NOT_REACHED() CRASH()
    520 #else
    521 #define RELEASE_ASSERT(assertion) ASSERT(assertion)
     519#define RELEASE_ASSERT_NOT_REACHED(...) CRASH_WITH_INFO(__VA_ARGS__)
     520#else
     521#define RELEASE_ASSERT(assertion, ...) ASSERT(assertion, __VA_ARGS__)
    522522#define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
    523523#define RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT_WITH_SECURITY_IMPLICATION(assertion)
    524524#define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
    525525#endif
     526
     527#ifdef __cplusplus
     528
     529// The combination of line, file, function, and counter should be a unique number per call to this crash. This tricks the compiler into not coalescing calls to WTFCrashWithInfo.
     530// The easiest way to fill these values per translation unit is to pass __LINE__, __FILE__, WTF_PRETTY_FUNCTION, and __COUNTER__.
     531WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6);
     532WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5);
     533WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4);
     534WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3);
     535WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2);
     536WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1);
     537WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason);
     538WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);
     539
     540
     541namespace WTF {
     542inline void isIntegralType() { }
     543
     544template<typename T, typename... Types>
     545void isIntegralType(T, Types... types)
     546{
     547    static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "All types need to be integral bitwise_cast to integral type for logging");
     548    isIntegralType(types...);
     549}
     550}
     551
     552inline void compilerFenceForCrash()
     553{
     554#if OS(WINDOWS) && !COMPILER(GCC_OR_CLANG)
     555    _ReadWriteBarrier();
     556#else
     557    asm volatile("" ::: "memory");
     558#endif
     559}
     560
     561#ifndef CRASH_WITH_INFO
     562// This is useful if you are going to stuff data into registers before crashing. Like the crashWithInfo functions below...
     563// GCC doesn't like the ##__VA_ARGS__ here since this macro is called from another macro so we just CRASH instead there.
     564#if COMPILER(CLANG) || COMPILER(MSVC)
     565#define CRASH_WITH_INFO(...) do { \
     566        WTF::isIntegralType(__VA_ARGS__); \
     567        compilerFenceForCrash(); \
     568        WTFCrashWithInfo(__LINE__, __FILE__, WTF_PRETTY_FUNCTION, __COUNTER__, ##__VA_ARGS__); \
     569    } while (false)
     570#else
     571#define CRASH_WITH_INFO(...) CRASH()
     572#endif
     573#endif // CRASH_WITH_INFO
     574
     575#ifndef CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
     576#define CRASH_WITH_SECURITY_IMPLICATION_AND_INFO CRASH_WITH_INFO
     577#endif // CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
     578
     579#else /* not __cplusplus */
     580
     581#ifndef CRASH_WITH_INFO
     582#define CRASH_WITH_INFO() CRASH()
     583#endif
     584
     585#endif /* __cplusplus */
    526586
    527587/* UNREACHABLE_FOR_PLATFORM */
     
    543603#endif
    544604
    545 #ifdef __cplusplus
    546 
    547 // The combination of line, file, function, and counter should be a unique number per call to this crash. This tricks the compiler into not coalescing calls to WTFCrashWithInfo.
    548 // The easiest way to fill these values per translation unit is to pass __LINE__, __FILE__, WTF_PRETTY_FUNCTION, and __COUNTER__.
    549 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4);
    550 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3);
    551 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1, uint64_t misc2);
    552 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason, uint64_t misc1);
    553 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter, uint64_t reason);
    554 WTF_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH NOT_TAIL_CALLED void WTFCrashWithInfo(int line, const char* file, const char* function, int counter);
    555 
    556 
    557 namespace WTF {
    558 inline void isIntegralType() { }
    559 
    560 template<typename T, typename... Types>
    561 void isIntegralType(T, Types... types)
    562 {
    563     static_assert(std::is_integral<T>::value || std::is_enum<T>::value, "All types need to be integral bitwise_cast to integral type for logging");
    564     isIntegralType(types...);
    565 }
    566 }
    567 
    568 inline void compilerFenceForCrash()
    569 {
    570 #if OS(WINDOWS) && !COMPILER(GCC_OR_CLANG)
    571     _ReadWriteBarrier();
    572 #else
    573     asm volatile("" ::: "memory");
    574 #endif
    575 }
    576 
    577 #ifndef CRASH_WITH_INFO
    578 // This is useful if you are going to stuff data into registers before crashing. Like the crashWithInfo functions below...
    579 // GCC doesn't like the ##__VA_ARGS__ here since this macro is called from another macro so we just CRASH instead there.
    580 #if COMPILER(CLANG) || COMPILER(MSVC)
    581 #define CRASH_WITH_INFO(...) do { \
    582         WTF::isIntegralType(__VA_ARGS__); \
    583         compilerFenceForCrash(); \
    584         WTFCrashWithInfo(__LINE__, __FILE__, WTF_PRETTY_FUNCTION, __COUNTER__, ##__VA_ARGS__); \
    585     } while (false)
    586 #else
    587 #define CRASH_WITH_INFO(...) CRASH()
    588 #endif
    589 #endif // CRASH_WITH_INFO
    590 
    591 #ifndef CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
    592 #define CRASH_WITH_SECURITY_IMPLICATION_AND_INFO CRASH_WITH_INFO
    593 #endif // CRASH_WITH_SECURITY_IMPLICATION_AND_INFO
    594 
    595 #endif // __cplusplus
    596 
    597605#endif /* WTF_Assertions_h */
Note: See TracChangeset for help on using the changeset viewer.