mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-19 01:10:57 -08:00
1. Being on the critical path is a property of the code location where the event is emitted, not of the event type, so indicate this using EVENT_CRITICAL macros rather than a field in the event table. 2. Compile out events on the critical path in hot varieties. 3. Remove TraceFixWhite event (redundant with TraceFixSeg). 4. No need for special handling of PoolFree event -- this are already skipped in hot varieties by dispatching directly to the pool class via PoolFreeMacro. Copied from Perforce Change: 195261
246 lines
14 KiB
C
246 lines
14 KiB
C
/* <code/event.h> -- Event Logging Interface
|
|
*
|
|
* Copyright (c) 2001-2018 Ravenbrook Limited. See end of file for license.
|
|
* $Id$
|
|
*
|
|
* READERSHIP
|
|
*
|
|
* .readership: MPS developers.
|
|
*
|
|
* DESIGN
|
|
*
|
|
* .design: <design/telemetry/>.
|
|
*/
|
|
|
|
#ifndef event_h
|
|
#define event_h
|
|
|
|
#include "eventcom.h"
|
|
#include "mpm.h"
|
|
#include "eventdef.h"
|
|
#include "mpslib.h"
|
|
|
|
|
|
typedef Word EventStringId;
|
|
typedef Word EventControlSet;
|
|
|
|
extern void EventSync(void);
|
|
extern void EventInit(void);
|
|
extern void EventFinish(void);
|
|
extern EventControlSet EventControl(EventControlSet resetMask,
|
|
EventControlSet flipMask);
|
|
extern EventStringId EventInternString(const char *label);
|
|
extern EventStringId EventInternGenString(size_t, const char *label);
|
|
extern void EventLabelAddr(Addr addr, Word id);
|
|
extern void EventLabelPointer(Pointer pointer, Word id);
|
|
extern void EventFlush(EventKind kind);
|
|
extern Res EventDescribe(Event event, mps_lib_FILE *stream, Count depth);
|
|
extern Res EventWrite(Event event, mps_lib_FILE *stream);
|
|
extern void EventDump(mps_lib_FILE *stream);
|
|
|
|
|
|
#ifdef EVENT
|
|
|
|
/* Event writing support */
|
|
|
|
extern char EventBuffer[EventKindLIMIT][EventBufferSIZE];
|
|
extern char *EventLast[EventKindLIMIT];
|
|
extern Word EventKindControl;
|
|
|
|
|
|
/* EVENT_BEGIN -- flush buffer if necessary and write event header */
|
|
|
|
#define EVENT_BEGIN(name, structSize) \
|
|
BEGIN \
|
|
Event##name##Struct *_event; \
|
|
EventKind _kind = Event##name##Kind; \
|
|
size_t _size = size_tAlignUp(structSize, EVENT_ALIGN); \
|
|
AVER(Event##name##Used); \
|
|
if (_size > (size_t)(EventLast[Event##name##Kind] \
|
|
- EventBuffer[Event##name##Kind])) \
|
|
EventFlush(Event##name##Kind); \
|
|
AVER(_size <= (size_t)(EventLast[Event##name##Kind] \
|
|
- EventBuffer[Event##name##Kind])); \
|
|
_event = (void *)(EventLast[Event##name##Kind] - _size); \
|
|
_event->code = Event##name##Code; \
|
|
_event->size = (EventSize)_size; \
|
|
EVENT_CLOCK(_event->clock);
|
|
|
|
#define EVENT_END \
|
|
EventLast[_kind] -= _size; \
|
|
END
|
|
|
|
|
|
/* EVENTn -- event emitting macros
|
|
*
|
|
* The macros EVENT0, EVENT1, etc. are used throughout the MPS to emit an
|
|
* event with parameters. They work by appending the event parameters to
|
|
* an event buffer, which is flushed to the telemetry output stream when
|
|
* full. EVENT2S is a special case that takes a variable length string.
|
|
*/
|
|
|
|
#define EVENT2S(name, p0, length, string) \
|
|
BEGIN \
|
|
size_t _string_len = (length); \
|
|
size_t size; \
|
|
AVER(_string_len <= EventStringLengthMAX); \
|
|
size = offsetof(Event##name##Struct, f1) + _string_len + sizeof('\0'); \
|
|
EVENT_BEGIN(name, size) \
|
|
_event->f0 = (p0); \
|
|
(void)mps_lib_memcpy(_event->f1, (string), _string_len); \
|
|
_event->f1[_string_len] = '\0'; \
|
|
EVENT_END; \
|
|
END
|
|
|
|
#define EVENT0 EVENT_RECORD0
|
|
#define EVENT1 EVENT_RECORD1
|
|
#define EVENT2 EVENT_RECORD2
|
|
#define EVENT3 EVENT_RECORD3
|
|
#define EVENT4 EVENT_RECORD4
|
|
#define EVENT5 EVENT_RECORD5
|
|
#define EVENT6 EVENT_RECORD6
|
|
#define EVENT7 EVENT_RECORD7
|
|
#define EVENT8 EVENT_RECORD8
|
|
#define EVENT9 EVENT_RECORD9
|
|
#define EVENT10 EVENT_RECORD10
|
|
#define EVENT11 EVENT_RECORD11
|
|
#define EVENT12 EVENT_RECORD12
|
|
#define EVENT13 EVENT_RECORD13
|
|
#define EVENT14 EVENT_RECORD14
|
|
|
|
#else /* !EVENT */
|
|
|
|
#define EVENT0 EVENT_IGNORE0
|
|
#define EVENT1 EVENT_IGNORE1
|
|
#define EVENT2 EVENT_IGNORE2
|
|
#define EVENT3 EVENT_IGNORE3
|
|
#define EVENT4 EVENT_IGNORE4
|
|
#define EVENT5 EVENT_IGNORE5
|
|
#define EVENT6 EVENT_IGNORE6
|
|
#define EVENT7 EVENT_IGNORE7
|
|
#define EVENT8 EVENT_IGNORE8
|
|
#define EVENT9 EVENT_IGNORE9
|
|
#define EVENT10 EVENT_IGNORE10
|
|
#define EVENT11 EVENT_IGNORE11
|
|
#define EVENT12 EVENT_IGNORE12
|
|
#define EVENT13 EVENT_IGNORE13
|
|
#define EVENT14 EVENT_IGNORE14
|
|
|
|
#endif /* !EVENT */
|
|
|
|
#if EVENT_ALL
|
|
|
|
#define EVENT_CRITICAL0 EVENT0
|
|
#define EVENT_CRITICAL1 EVENT1
|
|
#define EVENT_CRITICAL2 EVENT2
|
|
#define EVENT_CRITICAL3 EVENT3
|
|
#define EVENT_CRITICAL4 EVENT4
|
|
#define EVENT_CRITICAL5 EVENT5
|
|
#define EVENT_CRITICAL6 EVENT6
|
|
#define EVENT_CRITICAL7 EVENT7
|
|
#define EVENT_CRITICAL8 EVENT8
|
|
#define EVENT_CRITICAL9 EVENT9
|
|
#define EVENT_CRITICAL10 EVENT10
|
|
#define EVENT_CRITICAL11 EVENT11
|
|
#define EVENT_CRITICAL12 EVENT12
|
|
#define EVENT_CRITICAL13 EVENT13
|
|
#define EVENT_CRITICAL14 EVENT14
|
|
|
|
#else /* !EVENT_ALL */
|
|
|
|
#define EVENT_CRITICAL0 EVENT_IGNORE0
|
|
#define EVENT_CRITICAL1 EVENT_IGNORE1
|
|
#define EVENT_CRITICAL2 EVENT_IGNORE2
|
|
#define EVENT_CRITICAL3 EVENT_IGNORE3
|
|
#define EVENT_CRITICAL4 EVENT_IGNORE4
|
|
#define EVENT_CRITICAL5 EVENT_IGNORE5
|
|
#define EVENT_CRITICAL6 EVENT_IGNORE6
|
|
#define EVENT_CRITICAL7 EVENT_IGNORE7
|
|
#define EVENT_CRITICAL8 EVENT_IGNORE8
|
|
#define EVENT_CRITICAL9 EVENT_IGNORE9
|
|
#define EVENT_CRITICAL10 EVENT_IGNORE10
|
|
#define EVENT_CRITICAL11 EVENT_IGNORE11
|
|
#define EVENT_CRITICAL12 EVENT_IGNORE12
|
|
#define EVENT_CRITICAL13 EVENT_IGNORE13
|
|
#define EVENT_CRITICAL14 EVENT_IGNORE14
|
|
|
|
#endif /* !EVENT_ALL */
|
|
|
|
|
|
/* The following lines were generated with
|
|
python -c 'for i in range(15): print("#define EVENT_RECORD{i}(name{args}) EVENT_BEGIN(name, sizeof(Event##name##Struct)) {assign} EVENT_END\n#define EVENT_IGNORE{i}(name{args}) BEGIN {unused} END".format(i=i, args="".join(map(", p{}".format, range(i))), assign=" ".join(map("_event->f{0} = (p{0});".format, range(i))), unused=" ".join(map("UNUSED(p{});".format, range(i)))))'
|
|
*/
|
|
#define EVENT_RECORD0(name) EVENT_BEGIN(name, sizeof(Event##name##Struct)) EVENT_END
|
|
#define EVENT_IGNORE0(name) BEGIN END
|
|
#define EVENT_RECORD1(name, p0) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); EVENT_END
|
|
#define EVENT_IGNORE1(name, p0) BEGIN UNUSED(p0); END
|
|
#define EVENT_RECORD2(name, p0, p1) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); EVENT_END
|
|
#define EVENT_IGNORE2(name, p0, p1) BEGIN UNUSED(p0); UNUSED(p1); END
|
|
#define EVENT_RECORD3(name, p0, p1, p2) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); EVENT_END
|
|
#define EVENT_IGNORE3(name, p0, p1, p2) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); END
|
|
#define EVENT_RECORD4(name, p0, p1, p2, p3) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); EVENT_END
|
|
#define EVENT_IGNORE4(name, p0, p1, p2, p3) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); END
|
|
#define EVENT_RECORD5(name, p0, p1, p2, p3, p4) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); EVENT_END
|
|
#define EVENT_IGNORE5(name, p0, p1, p2, p3, p4) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); END
|
|
#define EVENT_RECORD6(name, p0, p1, p2, p3, p4, p5) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); EVENT_END
|
|
#define EVENT_IGNORE6(name, p0, p1, p2, p3, p4, p5) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); END
|
|
#define EVENT_RECORD7(name, p0, p1, p2, p3, p4, p5, p6) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); EVENT_END
|
|
#define EVENT_IGNORE7(name, p0, p1, p2, p3, p4, p5, p6) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); END
|
|
#define EVENT_RECORD8(name, p0, p1, p2, p3, p4, p5, p6, p7) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); EVENT_END
|
|
#define EVENT_IGNORE8(name, p0, p1, p2, p3, p4, p5, p6, p7) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); END
|
|
#define EVENT_RECORD9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); EVENT_END
|
|
#define EVENT_IGNORE9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); END
|
|
#define EVENT_RECORD10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); _event->f9 = (p9); EVENT_END
|
|
#define EVENT_IGNORE10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); UNUSED(p9); END
|
|
#define EVENT_RECORD11(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); _event->f9 = (p9); _event->f10 = (p10); EVENT_END
|
|
#define EVENT_IGNORE11(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); UNUSED(p9); UNUSED(p10); END
|
|
#define EVENT_RECORD12(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); _event->f9 = (p9); _event->f10 = (p10); _event->f11 = (p11); EVENT_END
|
|
#define EVENT_IGNORE12(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); UNUSED(p9); UNUSED(p10); UNUSED(p11); END
|
|
#define EVENT_RECORD13(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); _event->f9 = (p9); _event->f10 = (p10); _event->f11 = (p11); _event->f12 = (p12); EVENT_END
|
|
#define EVENT_IGNORE13(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); UNUSED(p9); UNUSED(p10); UNUSED(p11); UNUSED(p12); END
|
|
#define EVENT_RECORD14(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13) EVENT_BEGIN(name, sizeof(Event##name##Struct)) _event->f0 = (p0); _event->f1 = (p1); _event->f2 = (p2); _event->f3 = (p3); _event->f4 = (p4); _event->f5 = (p5); _event->f6 = (p6); _event->f7 = (p7); _event->f8 = (p8); _event->f9 = (p9); _event->f10 = (p10); _event->f11 = (p11); _event->f12 = (p12); _event->f13 = (p13); EVENT_END
|
|
#define EVENT_IGNORE14(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13) BEGIN UNUSED(p0); UNUSED(p1); UNUSED(p2); UNUSED(p3); UNUSED(p4); UNUSED(p5); UNUSED(p6); UNUSED(p7); UNUSED(p8); UNUSED(p9); UNUSED(p10); UNUSED(p11); UNUSED(p12); UNUSED(p13); END
|
|
|
|
#endif /* event_h */
|
|
|
|
|
|
/* C. COPYRIGHT AND LICENSE
|
|
*
|
|
* Copyright (C) 2001-2018 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
|
* All rights reserved. This is an open source license. Contact
|
|
* Ravenbrook for commercial licensing options.
|
|
*
|
|
* 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.
|
|
*
|
|
* 3. Redistributions in any form must be accompanied by information on how
|
|
* to obtain complete source code for this software and any accompanying
|
|
* software that uses this software. The source code must either be
|
|
* included in the distribution or be available for no more than the cost
|
|
* of distribution plus a nominal fee, and must be freely redistributable
|
|
* under reasonable conditions. For an executable file, complete source
|
|
* code means the source code for all modules it contains. It does not
|
|
* include source code for modules or files that typically accompany the
|
|
* major components of the operating system on which the executable file
|
|
* runs.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDERS AND 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.
|
|
*/
|