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 */
176