| 1 | /* |
| 2 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. |
| 3 | * Copyright (c) 1996 by Silicon Graphics. All rights reserved. |
| 4 | * Copyright (c) 1998 by Fergus Henderson. All rights reserved. |
| 5 | * Copyright (c) 2000-2009 by Hewlett-Packard Development Company. |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED |
| 9 | * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. |
| 10 | * |
| 11 | * Permission is hereby granted to use or copy this program |
| 12 | * for any purpose, provided the above notices are retained on all copies. |
| 13 | * Permission to modify the code and to distribute modified code is granted, |
| 14 | * provided the above notices are retained, and a notice that the code was |
| 15 | * modified is included with the above copyright notice. |
| 16 | */ |
| 17 | |
| 18 | /* |
| 19 | * This is a simple API to implement pointer back tracing, i.e. |
| 20 | * to answer questions such as "who is pointing to this" or |
| 21 | * "why is this object being retained by the collector". |
| 22 | * Most of these calls yield useful information on only after |
| 23 | * a garbage collection. Usually the client will first force |
| 24 | * a full collection and then gather information, preferably |
| 25 | * before much intervening allocation. |
| 26 | * The implementation of the interface is only about 99.9999% |
| 27 | * correct. It is intended to be good enough for profiling, |
| 28 | * but is not intended to be used with production code. |
| 29 | * Results are likely to be much more useful if all allocation |
| 30 | * is accomplished through the debugging allocators. |
| 31 | */ |
| 32 | |
| 33 | /* The implementation idea is due to A. Demers. */ |
| 34 | |
| 35 | #ifndef GC_BACKPTR_H |
| 36 | #define GC_BACKPTR_H |
| 37 | |
| 38 | #ifndef GC_H |
| 39 | # include "gc.h" |
| 40 | #endif |
| 41 | |
| 42 | #ifdef __cplusplus |
| 43 | extern "C" { |
| 44 | #endif |
| 45 | |
| 46 | typedef enum { |
| 47 | /** No reference info available. */ |
| 48 | GC_UNREFERENCED, |
| 49 | /** `dest` is not allocated with a debug allocation routine. */ |
| 50 | GC_NO_SPACE, |
| 51 | /** Referenced directly by root `*base_p`. */ |
| 52 | GC_REFD_FROM_ROOT, |
| 53 | /** Referenced from a register, i.e. a root without an address. */ |
| 54 | GC_REFD_FROM_REG, |
| 55 | /** Referenced from another heap object. */ |
| 56 | GC_REFD_FROM_HEAP, |
| 57 | /** Finalizable and hence accessible. */ |
| 58 | GC_FINALIZER_REFD |
| 59 | } GC_ref_kind; |
| 60 | |
| 61 | /** |
| 62 | * Store information about the source object referencing `dest` in |
| 63 | * `*base_p` and `*offset_p`. If multiple objects or roots point to |
| 64 | * `dest`, then the one reported will be the last one used by the |
| 65 | * garbage collector to trace the object. If the source is root, then |
| 66 | * `*base_p` is the address and `*offset_p` is zero. If the source is |
| 67 | * a heap object, then `*base_p` is non-`NULL` and `*offset_p` is the |
| 68 | * offset. `dest` can be any address within a heap object. |
| 69 | * The allocator lock is not acquired by design (despite of the |
| 70 | * possibility of a race); anyway the function should not be used in |
| 71 | * production code. |
| 72 | */ |
| 73 | GC_API GC_ref_kind GC_CALL GC_get_back_ptr_info(void * /* `dest` */, |
| 74 | void ** /* `base_p` */, |
| 75 | size_t * /* `offset_p` */) |
| 76 | GC_ATTR_NONNULL(1); |
| 77 | |
| 78 | /** |
| 79 | * Generate a random heap address. The resulting address is |
| 80 | * in the heap, but not necessarily inside a valid object. |
| 81 | * The caller should hold the allocator lock. |
| 82 | */ |
| 83 | GC_API void *GC_CALL GC_generate_random_heap_address(void); |
| 84 | |
| 85 | /** |
| 86 | * Generate a random address inside a valid marked heap object. |
| 87 | * The caller should hold the allocator lock. |
| 88 | */ |
| 89 | GC_API void *GC_CALL GC_generate_random_valid_address(void); |
| 90 | |
| 91 | /** |
| 92 | * Force a garbage collection and generate a backtrace from a random |
| 93 | * heap address. This uses the collector logging mechanism (`GC_printf`) |
| 94 | * to produce output. It can often be called from a debugger. |
| 95 | */ |
| 96 | GC_API void GC_CALL GC_generate_random_backtrace(void); |
| 97 | |
| 98 | /** |
| 99 | * Print a backtrace from a specific address. The client should call |
| 100 | * `GC_gcollect()` right before the invocation. Used e.g. by |
| 101 | * `GC_generate_random_backtrace()`. |
| 102 | */ |
| 103 | GC_API void GC_CALL GC_print_backtrace(void *) GC_ATTR_NONNULL(1); |
| 104 | |
| 105 | #ifdef __cplusplus |
| 106 | } /* extern "C" */ |
| 107 | #endif |
| 108 | |
| 109 | #endif /* GC_BACKPTR_H */ |
| 110 | |