| 1 | /*
|
|---|
| 2 | * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
|
|---|
| 3 | * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
|
|---|
| 4 | * Copyright (c) 1997 by Silicon Graphics. All rights reserved.
|
|---|
| 5 | * Copyright (c) 1999 by Hewlett-Packard Company. All rights reserved.
|
|---|
| 6 | *
|
|---|
| 7 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
|
|---|
| 8 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
|
|---|
| 9 | *
|
|---|
| 10 | * Permission is hereby granted to use or copy this program
|
|---|
| 11 | * for any purpose, provided the above notices are retained on all copies.
|
|---|
| 12 | * Permission to modify the code and to distribute modified code is granted,
|
|---|
| 13 | * provided the above notices are retained, and a notice that the code was
|
|---|
| 14 | * modified is included with the above copyright notice.
|
|---|
| 15 | */
|
|---|
| 16 |
|
|---|
| 17 | /*
|
|---|
| 18 | * This is mostly an internal header file. Typical clients should
|
|---|
| 19 | * not use it. Clients that define their own object kinds with
|
|---|
| 20 | * debugging allocators will probably want to include this, however.
|
|---|
| 21 | * No attempt is made to keep the namespace clean. This should not be
|
|---|
| 22 | * included from header files that are frequently included by clients.
|
|---|
| 23 | */
|
|---|
| 24 |
|
|---|
| 25 | #ifndef _DBG_MLC_H
|
|---|
| 26 |
|
|---|
| 27 | #define _DBG_MLC_H
|
|---|
| 28 |
|
|---|
| 29 | # define I_HIDE_POINTERS
|
|---|
| 30 | # include "gc_priv.h"
|
|---|
| 31 | # ifdef KEEP_BACK_PTRS
|
|---|
| 32 | # include "gc_backptr.h"
|
|---|
| 33 | # endif
|
|---|
| 34 |
|
|---|
| 35 | #ifndef HIDE_POINTER
|
|---|
| 36 | /* Gc.h was previously included, and hence the I_HIDE_POINTERS */
|
|---|
| 37 | /* definition had no effect. Repeat the gc.h definitions here to */
|
|---|
| 38 | /* get them anyway. */
|
|---|
| 39 | typedef GC_word GC_hidden_pointer;
|
|---|
| 40 | # define HIDE_POINTER(p) (~(GC_hidden_pointer)(p))
|
|---|
| 41 | # define REVEAL_POINTER(p) ((GC_PTR)(HIDE_POINTER(p)))
|
|---|
| 42 | #endif /* HIDE_POINTER */
|
|---|
| 43 |
|
|---|
| 44 | # define START_FLAG ((word)0xfedcedcb)
|
|---|
| 45 | # define END_FLAG ((word)0xbcdecdef)
|
|---|
| 46 | /* Stored both one past the end of user object, and one before */
|
|---|
| 47 | /* the end of the object as seen by the allocator. */
|
|---|
| 48 |
|
|---|
| 49 | # if defined(KEEP_BACK_PTRS) || defined(PRINT_BLACK_LIST) \
|
|---|
| 50 | || defined(MAKE_BACK_GRAPH)
|
|---|
| 51 | /* Pointer "source"s that aren't real locations. */
|
|---|
| 52 | /* Used in oh_back_ptr fields and as "source" */
|
|---|
| 53 | /* argument to some marking functions. */
|
|---|
| 54 | # define NOT_MARKED (ptr_t)(0)
|
|---|
| 55 | # define MARKED_FOR_FINALIZATION (ptr_t)(2)
|
|---|
| 56 | /* Object was marked because it is finalizable. */
|
|---|
| 57 | # define MARKED_FROM_REGISTER (ptr_t)(4)
|
|---|
| 58 | /* Object was marked from a rgister. Hence the */
|
|---|
| 59 | /* source of the reference doesn't have an address. */
|
|---|
| 60 | # endif /* KEEP_BACK_PTRS || PRINT_BLACK_LIST */
|
|---|
| 61 |
|
|---|
| 62 | /* Object header */
|
|---|
| 63 | typedef struct {
|
|---|
| 64 | # if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
|
|---|
| 65 | /* We potentially keep two different kinds of back */
|
|---|
| 66 | /* pointers. KEEP_BACK_PTRS stores a single back */
|
|---|
| 67 | /* pointer in each reachable object to allow reporting */
|
|---|
| 68 | /* of why an object was retained. MAKE_BACK_GRAPH */
|
|---|
| 69 | /* builds a graph containing the inverse of all */
|
|---|
| 70 | /* "points-to" edges including those involving */
|
|---|
| 71 | /* objects that have just become unreachable. This */
|
|---|
| 72 | /* allows detection of growing chains of unreachable */
|
|---|
| 73 | /* objects. It may be possible to eventually combine */
|
|---|
| 74 | /* both, but for now we keep them separate. Both */
|
|---|
| 75 | /* kinds of back pointers are hidden using the */
|
|---|
| 76 | /* following macros. In both cases, the plain version */
|
|---|
| 77 | /* is constrained to have an least significant bit of 1,*/
|
|---|
| 78 | /* to allow it to be distinguished from a free list */
|
|---|
| 79 | /* link. This means the plain version must have an */
|
|---|
| 80 | /* lsb of 0. */
|
|---|
| 81 | /* Note that blocks dropped by black-listing will */
|
|---|
| 82 | /* also have the lsb clear once debugging has */
|
|---|
| 83 | /* started. */
|
|---|
| 84 | /* We're careful never to overwrite a value with lsb 0. */
|
|---|
| 85 | # if ALIGNMENT == 1
|
|---|
| 86 | /* Fudge back pointer to be even. */
|
|---|
| 87 | # define HIDE_BACK_PTR(p) HIDE_POINTER(~1 & (GC_word)(p))
|
|---|
| 88 | # else
|
|---|
| 89 | # define HIDE_BACK_PTR(p) HIDE_POINTER(p)
|
|---|
| 90 | # endif
|
|---|
| 91 |
|
|---|
| 92 | # ifdef KEEP_BACK_PTRS
|
|---|
| 93 | GC_hidden_pointer oh_back_ptr;
|
|---|
| 94 | # endif
|
|---|
| 95 | # ifdef MAKE_BACK_GRAPH
|
|---|
| 96 | GC_hidden_pointer oh_bg_ptr;
|
|---|
| 97 | # endif
|
|---|
| 98 | # if defined(ALIGN_DOUBLE) && \
|
|---|
| 99 | (defined(KEEP_BACK_PTRS) != defined(MAKE_BACK_GRAPH))
|
|---|
| 100 | word oh_dummy;
|
|---|
| 101 | # endif
|
|---|
| 102 | # endif
|
|---|
| 103 | GC_CONST char * oh_string; /* object descriptor string */
|
|---|
| 104 | word oh_int; /* object descriptor integers */
|
|---|
| 105 | # ifdef NEED_CALLINFO
|
|---|
| 106 | struct callinfo oh_ci[NFRAMES];
|
|---|
| 107 | # endif
|
|---|
| 108 | # ifndef SHORT_DBG_HDRS
|
|---|
| 109 | word oh_sz; /* Original malloc arg. */
|
|---|
| 110 | word oh_sf; /* start flag */
|
|---|
| 111 | # endif /* SHORT_DBG_HDRS */
|
|---|
| 112 | } oh;
|
|---|
| 113 | /* The size of the above structure is assumed not to dealign things, */
|
|---|
| 114 | /* and to be a multiple of the word length. */
|
|---|
| 115 |
|
|---|
| 116 | #ifdef SHORT_DBG_HDRS
|
|---|
| 117 | # define DEBUG_BYTES (sizeof (oh))
|
|---|
| 118 | # define UNCOLLECTABLE_DEBUG_BYTES DEBUG_BYTES
|
|---|
| 119 | #else
|
|---|
| 120 | /* Add space for END_FLAG, but use any extra space that was already */
|
|---|
| 121 | /* added to catch off-the-end pointers. */
|
|---|
| 122 | /* For uncollectable objects, the extra byte is not added. */
|
|---|
| 123 | # define UNCOLLECTABLE_DEBUG_BYTES (sizeof (oh) + sizeof (word))
|
|---|
| 124 | # define DEBUG_BYTES (UNCOLLECTABLE_DEBUG_BYTES - EXTRA_BYTES)
|
|---|
| 125 | #endif
|
|---|
| 126 |
|
|---|
| 127 | /* Round bytes to words without adding extra byte at end. */
|
|---|
| 128 | #define SIMPLE_ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1)
|
|---|
| 129 |
|
|---|
| 130 | /* ADD_CALL_CHAIN stores a (partial) call chain into an object */
|
|---|
| 131 | /* header. It may be called with or without the allocation */
|
|---|
| 132 | /* lock. */
|
|---|
| 133 | /* PRINT_CALL_CHAIN prints the call chain stored in an object */
|
|---|
| 134 | /* to stderr. It requires that we do not hold the lock. */
|
|---|
| 135 | #ifdef SAVE_CALL_CHAIN
|
|---|
| 136 | # define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci)
|
|---|
| 137 | # define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
|
|---|
| 138 | #else
|
|---|
| 139 | # ifdef GC_ADD_CALLER
|
|---|
| 140 | # define ADD_CALL_CHAIN(base, ra) ((oh *)(base)) -> oh_ci[0].ci_pc = (ra)
|
|---|
| 141 | # define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
|
|---|
| 142 | # else
|
|---|
| 143 | # define ADD_CALL_CHAIN(base, ra)
|
|---|
| 144 | # define PRINT_CALL_CHAIN(base)
|
|---|
| 145 | # endif
|
|---|
| 146 | #endif
|
|---|
| 147 |
|
|---|
| 148 | # ifdef GC_ADD_CALLER
|
|---|
| 149 | # define OPT_RA ra,
|
|---|
| 150 | # else
|
|---|
| 151 | # define OPT_RA
|
|---|
| 152 | # endif
|
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 | /* Check whether object with base pointer p has debugging info */
|
|---|
| 156 | /* p is assumed to point to a legitimate object in our part */
|
|---|
| 157 | /* of the heap. */
|
|---|
| 158 | #ifdef SHORT_DBG_HDRS
|
|---|
| 159 | # define GC_has_other_debug_info(p) TRUE
|
|---|
| 160 | #else
|
|---|
| 161 | GC_bool GC_has_other_debug_info(/* p */);
|
|---|
| 162 | #endif
|
|---|
| 163 |
|
|---|
| 164 | #if defined(KEEP_BACK_PTRS) || defined(MAKE_BACK_GRAPH)
|
|---|
| 165 | # define GC_HAS_DEBUG_INFO(p) \
|
|---|
| 166 | ((*((word *)p) & 1) && GC_has_other_debug_info(p))
|
|---|
| 167 | #else
|
|---|
| 168 | # define GC_HAS_DEBUG_INFO(p) GC_has_other_debug_info(p)
|
|---|
| 169 | #endif
|
|---|
| 170 |
|
|---|
| 171 | /* Store debugging info into p. Return displaced pointer. */
|
|---|
| 172 | /* Assumes we don't hold allocation lock. */
|
|---|
| 173 | ptr_t GC_store_debug_info(/* p, sz, string, integer */);
|
|---|
| 174 |
|
|---|
| 175 | #endif /* _DBG_MLC_H */
|
|---|