Skip to content
Newer
Older
100644 378 lines (292 sloc) 18.6 KB
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
1 /*
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
2 auto_zone.h
3 Automatic Garbage Collection.
4aca101 @drernie Added 2010 Copyrights
drernie authored
4 Copyright (c) 2002-2010 Apple Inc. All rights reserved.
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
5 */
6
7 #ifndef __AUTO_ZONE__
8 #define __AUTO_ZONE__
9
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <malloc/malloc.h>
14
15 __BEGIN_DECLS
16
17 typedef malloc_zone_t auto_zone_t;
18 // an auto zone carries a little more state but can be cast into a malloc_zone_t
19
20 extern auto_zone_t *auto_zone_create(const char *name);
21 // create an garbage collected zone. Can be (theoretically) done more than once.
22 // memory can be allocated by malloc_zone_malloc(result, size)
23 // by default, this memory must be malloc_zone_free(result, ptr) as well (or generic free())
24
25 extern struct malloc_introspection_t auto_zone_introspection();
26 // access the zone introspection functions independent of any particular auto zone instance.
27 // this is used by tools to be able to introspect a zone in another process.
28 // the introspection functions returned are required to do version checking on the zone.
29
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
30 #define AUTO_RETAINED_BLOCK_TYPE 0x100 /* zone enumerator returns only blocks with nonzero retain count */
31
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
32 /********* External (Global) Use counting ************/
33
34 extern void auto_zone_retain(auto_zone_t *zone, void *ptr);
35 extern unsigned int auto_zone_release(auto_zone_t *zone, void *ptr);
36 extern unsigned int auto_zone_retain_count(auto_zone_t *zone, const void *ptr);
37 // All pointer in the auto zone have an explicit retain count
38 // Objects will not be collected when the retain count is non-zero
39
40 /********* Object information ************/
41
42 extern const void *auto_zone_base_pointer(auto_zone_t *zone, const void *ptr);
43 // return base of interior pointer (or NULL).
44 extern boolean_t auto_zone_is_valid_pointer(auto_zone_t *zone, const void *ptr);
45 // is this a pointer to the base of an allocated block?
46 extern size_t auto_zone_size(auto_zone_t *zone, const void *ptr);
47
48 /********* Write-barrier ************/
49
50 extern boolean_t auto_zone_set_write_barrier(auto_zone_t *zone, const void *dest, const void *new_value);
51 // must be used when an object field/slot in the auto zone is set to another object in the auto zone
52 // returns true if the dest was a valid target whose write-barrier was set
53
54 boolean_t auto_zone_atomicCompareAndSwap(auto_zone_t *zone, void *existingValue, void *newValue, void *volatile *location, boolean_t isGlobal, boolean_t issueBarrier);
55 // Atomically update a location with a new GC value. These use OSAtomicCompareAndSwapPtr{Barrier} with appropriate write-barrier interlocking logic.
56
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
57 boolean_t auto_zone_atomicCompareAndSwapPtr(auto_zone_t *zone, void *existingValue, void *newValue, void *volatile *location, boolean_t issueBarrier);
58 // Atomically update a location with a new GC value. These use OSAtomicCompareAndSwapPtr{Barrier} with appropriate write-barrier interlocking logic.
59 // This version checks location, and if it points into global storage, registers a root.
60
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
61 extern void *auto_zone_write_barrier_memmove(auto_zone_t *zone, void *dst, const void *src, size_t size);
62 // copy content from an arbitrary source area to an arbitrary destination area
63 // marking write barrier if necessary
64
65 /********* Statistics ************/
66
67 typedef uint64_t auto_date_t;
68
69 typedef struct {
70 auto_date_t total_duration;
71 auto_date_t scan_duration;
72 auto_date_t enlivening_duration;
73 auto_date_t finalize_duration;
74 auto_date_t reclaim_duration;
75 } auto_collection_durations_t;
76
77 typedef struct {
78 /* Memory usage */
79 malloc_statistics_t malloc_statistics;
80 /* GC stats */
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
81 // version 0
82 uint32_t version; // set to 1 before calling
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
83 /* When there is an array, 0 stands for full collection, 1 for generational */
84 size_t num_collections[2];
85 boolean_t last_collection_was_generational;
86 size_t bytes_in_use_after_last_collection[2];
87 size_t bytes_allocated_after_last_collection[2];
88 size_t bytes_freed_during_last_collection[2];
89 // durations
90 auto_collection_durations_t total[2]; // running total of each field
91 auto_collection_durations_t last[2]; // most recent result
92 auto_collection_durations_t maximum[2]; // on a per item basis, the max. Thus, total != scan + finalize ...
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
93 // version 1 additions
94 size_t thread_collections_total;
95 size_t thread_blocks_recovered_total;
96 size_t thread_bytes_recovered_total;
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
97 } auto_statistics_t;
98
99 extern void auto_zone_statistics(auto_zone_t *zone, auto_statistics_t *stats); // set version to 0
100
101 /********* Garbage Collection ************/
102
103 enum {
104 AUTO_COLLECT_RATIO_COLLECTION = (0 << 0), // run generational or full depending on applying AUTO_COLLECTION_RATIO
105 AUTO_COLLECT_GENERATIONAL_COLLECTION = (1 << 0), // collect young objects. Internal only.
106 AUTO_COLLECT_FULL_COLLECTION = (2 << 0), // collect entire heap. Internal only.
107 AUTO_COLLECT_EXHAUSTIVE_COLLECTION = (3 << 0), // run full collections until object count stabilizes.
108 AUTO_COLLECT_SYNCHRONOUS = (1 << 2), // block caller until scanning is finished.
109 AUTO_COLLECT_IF_NEEDED = (1 << 3), // only collect if AUTO_COLLECTION_THRESHOLD exceeded.
110 };
111 typedef uint32_t auto_collection_mode_t;
112
113 enum {
114 AUTO_LOG_COLLECTIONS = (1 << 1), // log whenever a collection occurs
115 AUTO_LOG_REGIONS = (1 << 4), // log whenever a new region is allocated
116 AUTO_LOG_UNUSUAL = (1 << 5), // log unusual circumstances
117 AUTO_LOG_WEAK = (1 << 6), // log weak reference manipulation
118 AUTO_LOG_ALL = (~0u),
119 AUTO_LOG_NONE = 0
120 };
121 typedef uint32_t auto_log_mask_t;
122
123 enum {
124 AUTO_HEAP_HOLES_SHRINKING = 1, // total size of holes is approaching zero
125 AUTO_HEAP_HOLES_EXHAUSTED = 2, // all holes exhausted, will use hitherto unused memory in "subzone"
126 AUTO_HEAP_SUBZONE_EXHAUSTED = 3, // will add subzone
127 AUTO_HEAP_REGION_EXHAUSTED = 4, // no more subzones available, need to add region
128 AUTO_HEAP_ARENA_EXHAUSTED = 5, // arena exhausted. (64-bit only)
129 };
130 typedef uint32_t auto_heap_growth_info_t;
131
132 typedef struct auto_zone_cursor *auto_zone_cursor_t;
133 typedef void (*auto_zone_foreach_object_t) (auto_zone_cursor_t cursor, void (*op) (void *ptr, void *data), void* data);
134
135 typedef struct {
136 uint32_t version; // reserved - 0 for now
137 void (*batch_invalidate) (auto_zone_t *zone, auto_zone_foreach_object_t foreach, auto_zone_cursor_t cursor, size_t cursor_size);
138 // After unreached objects are found, collector calls this routine with internal context.
139 // Typically, one enters a try block to call back into the collector with a function pointer to be used to
140 // invalidate each object. This amortizes the cost of the try block as well as allows the collector to use
141 // efficient contexts.
142 void (*resurrect) (auto_zone_t *zone, void *ptr);
143 // Objects on the garbage list may be assigned into live objects in an attempted resurrection. This is not allowed.
144 // This function, if supplied, is called for these objects to turn them into zombies. The zombies may well hold
145 // pointers to other objects on the garbage list. No attempt is made to preserved these objects beyond this collection.
146 const unsigned char* (*layout_for_address)(auto_zone_t *zone, void *ptr);
147 // The collector assumes that the first word of every "object" is a class pointer.
148 // For each class pointer discovered this function is called to return a layout, or NULL
149 // if the object should be scanned conservatively.
150 // The layout format is nibble pairs {skipcount, scancount} XXX
151 const unsigned char* (*weak_layout_for_address)(auto_zone_t *zone, void *ptr);
152 // called once for each allocation encountered for which we don't know the weak layout
153 // the callee returns a weak layout for the allocation or NULL if the allocation has no weak references.
154 char* (*name_for_address) (auto_zone_t *zone, vm_address_t base, vm_address_t offset);
155 // if supplied, is used during logging for errors such as resurrections
156 auto_log_mask_t log;
157 // set to auto_log_mask_t bits as desired
158 boolean_t disable_generational;
159 // if true, ignores requests to do generational GC.
160 boolean_t malloc_stack_logging;
161 // if true, logs allocations for malloc stack logging. Automatically set if MallocStackLogging{NoCompact} is set
162 void (*scan_external_callout)(void *context, void (*scanner)(void *context, void *start, void *end));
163 // an external function that is passed a memory scanner entry point
164 // if set, the function will be called during scanning so that the
165 // function the collector supplies will be called on all external memory that might
166 // have references. Useful, for example, for green thread systems.
167
168 void (*will_grow)(auto_zone_t *zone, auto_heap_growth_info_t);
169 // collector calls this when it is about to grow the heap. Advise if memory was returned to the collector, or not.
170 // if memory was returned, return 0 and the allocation will be attempted again, otherwise the heap will be grown.
171 size_t collection_threshold;
172 // if_needed threshold: collector will initiate a collection after this number of bytes is allocated.
173 size_t full_vs_gen_frequency;
174 // after full_vs_gen_frequency generational collections, a full collection will occur, if the if_needed threshold exceeded
175 } auto_collection_control_t;
176
177 extern auto_collection_control_t *auto_collection_parameters(auto_zone_t *zone);
178 // FIXME: API is to get the control struct and slam it
179 // sets a parameter that decides when callback gets called
180
181 extern void auto_collector_disable(auto_zone_t *zone);
182 extern void auto_collector_reenable(auto_zone_t *zone);
183 // these two functions turn off/on the collector
184 // default is on
185 // use with great care.
186
187 extern boolean_t auto_zone_is_enabled(auto_zone_t *zone);
188 extern boolean_t auto_zone_is_collecting(auto_zone_t *zone);
189
190 extern void auto_collect(auto_zone_t *zone, auto_collection_mode_t mode, void *collection_context);
191 // request a collection. By default, the collection will occur only on the main thread.
192
193 extern void auto_collect_multithreaded(auto_zone_t *zone);
194 // start a dedicated thread to do collections. The invalidate callback will subsequently be called from this new thread.
195
196 /********* Object layout for compaction ************/
197
198 // For compaction of the zone, we need to know for sure where are the pointers
199 // each object is assumed to have a class pointer as word 0 (the "isa")
200 // This layout information is also used for collection (for "tracing" pointers)
201
202 // Exact layout knowledge is also important for ignoring weak references
203
204 enum {
205 AUTO_TYPE_UNKNOWN = -1, // this is an error value
206 AUTO_UNSCANNED = 1,
207 AUTO_OBJECT = 2,
208 AUTO_MEMORY_SCANNED = 0, // holds conservatively scanned pointers
209 AUTO_MEMORY_UNSCANNED = AUTO_UNSCANNED, // holds unscanned memory (bits)
210 AUTO_OBJECT_SCANNED = AUTO_OBJECT, // first word is 'isa', may have 'exact' layout info elsewhere
211 AUTO_OBJECT_UNSCANNED = AUTO_OBJECT | AUTO_UNSCANNED, // first word is 'isa', good for bits or auto_zone_retain'ed items
212 };
213 typedef int auto_memory_type_t;
214
215 extern auto_memory_type_t auto_zone_get_layout_type(auto_zone_t *zone, void *ptr);
216
217
218 extern void* auto_zone_allocate_object(auto_zone_t *zone, size_t size, auto_memory_type_t type, boolean_t initial_refcount_to_one, boolean_t clear);
219
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
220 // Create copy of AUTO_MEMORY object preserving "scanned" attribute
221 // If not auto memory then create unscanned memory copy
222 void *auto_zone_create_copy(auto_zone_t *zone, void *ptr);
223
224
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
225 extern void auto_zone_register_thread(auto_zone_t *zone);
226
227 extern void auto_zone_unregister_thread(auto_zone_t *zone);
228
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
229 extern void auto_zone_assert_thread_registered(auto_zone_t *zone);
230
231 extern void auto_zone_register_datasegment(auto_zone_t *zone, void *address, size_t size);
232 extern void auto_zone_unregister_datasegment(auto_zone_t *zone, void *address, size_t size);
233
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
234
235 // Weak references
236
237 // The collector maintains a weak reference system.
238 // Essentially, locations in which references are stored are registered along with the reference itself.
239 // The location should not be within scanned GC memory.
240 // After a collection, before finalization, all registered locations are examined and any containing references to
241 // newly discovered garbage will be "zeroed" and the registration cancelled.
242 //
243 // Reading values from locations must be done through the weak read function because there is a race with such
244 // reads and the collector having just determined that that value read is in fact otherwise garbage.
245 //
246 // The address of a callback block may be supplied optionally. If supplied, if the location is zeroed, the callback
247 // block is queued to be called later with the arguments supplied in the callback block. The same callback block both
248 // can and should be used as an aggregation point. A table of weak locations could supply each registration with the
249 // same pointer to a callback block that will call that table if items are zerod. The callbacks are made before
250 // finalization. Note that only thread-safe operations may be performed by this callback.
251 //
252 // It is important to cancel all registrations before deallocating the memory containing locations or callback blocks.
253 // Cancellation is done by calling the registration function with a NULL "reference" parameter for that location.
254
255 typedef struct auto_weak_callback_block {
256 struct auto_weak_callback_block *next; // must be set to zero before first use
257 void (*callback_function)(void *arg1, void *arg2);
258 void *arg1;
259 void *arg2;
260 } auto_weak_callback_block_t;
261
7ef7eab Fix auto_zone header for SL
Thibault Martin-Lagardette authored
262 extern void auto_assign_weak_reference(auto_zone_t *zone, const void *value, const void **location, auto_weak_callback_block_t *block);
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
263
264 // Read a weak-reference, informing the collector that it is now strongly referenced.
265 extern void* auto_read_weak_reference(auto_zone_t *zone, void **referrer);
266
267 extern void auto_zone_add_root(auto_zone_t *zone, void *address_of_root_ptr, void *value);
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
268 extern void auto_zone_remove_root(auto_zone_t *zone, void *address_of_root_ptr);
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
269
270 extern void auto_zone_root_write_barrier(auto_zone_t *zone, void *address_of_possible_root_ptr, void *value);
271
272
273 // Associative references.
274
275 // This informs the collector that an object A wishes to associate one or more secondary objects with object A's lifetime.
276 // This can be used to implement GC-safe associations that will neither cause uncollectable cycles, nor suffer the limitations
277 // of weak references.
278
279 extern void auto_zone_set_associative_ref(auto_zone_t *zone, void *object, void *key, void *value);
280 extern void *auto_zone_get_associative_ref(auto_zone_t *zone, void *object, void *key);
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
281 extern void auto_zone_erase_associative_refs(auto_zone_t *zone, void *object);
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
282
283 /***** SPI ******/
284
285
286
287 extern void auto_zone_start_monitor(boolean_t force);
288 extern void auto_zone_set_class_list(int (*get_class_list)(void **buffer, int count));
289 extern boolean_t auto_zone_is_finalized(auto_zone_t *zone, const void *ptr);
290 extern void auto_zone_stats(void); // write stats to stdout
291 extern void auto_zone_write_stats(FILE *f); // write stats to the given stream
292 extern char *auto_zone_stats_string(); // return a char * containing the stats string, which should be free()'d
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
293 extern void auto_zone_set_nofinalize(auto_zone_t *zone, void *ptr);
294 extern void auto_zone_set_unscanned(auto_zone_t *zone, void *ptr);
295 extern void auto_zone_clear_stack(auto_zone_t *zone, unsigned long options);
296
297 // Reference count logging support for ObjectAlloc et. al.
298
299 enum {
300 AUTO_RETAIN_EVENT = 14,
301 AUTO_RELEASE_EVENT = 15
302 };
303 extern void (*__auto_reference_logger)(uint32_t eventtype, void *ptr, uintptr_t data);
304
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
305
306 // Reference tracing
307
308 // referrer_base[referrer_offset] -> referent
309 typedef struct
310 {
311 vm_address_t referent;
312 vm_address_t referrer_base;
313 intptr_t referrer_offset;
314 } auto_reference_t;
315
316 typedef void (*auto_reference_recorder_t)(auto_zone_t *zone, void *ctx,
317 auto_reference_t reference);
318
319 extern void auto_enumerate_references(auto_zone_t *zone, void *referent,
320 auto_reference_recorder_t callback,
321 void *stack_bottom, void *ctx);
322
323
324 void **auto_weak_find_first_referrer(auto_zone_t *zone, void **location, unsigned long count);
325
326
327 /************ DEPRECATED ***********/
328
329 extern auto_zone_t *auto_zone(void);
330 // returns a pointer to the first garbage collected zone created.
331 extern unsigned auto_zone_touched_size(auto_zone_t *zone);
332 // conservative (upper bound) on memory touched by the allocator itself.
333
334 extern double auto_zone_utilization(auto_zone_t *zone);
335 // conservative measure of utilization of allocator touched memory.
1e7a011 sync with latest SL's auto_zone.h
Laurent Sansonetti authored
336
337
338 /************* EXPERIMENTAL *********/
339 #ifdef __BLOCKS__
340
341 typedef void (^auto_zone_stack_dump)(const void *base, unsigned long byte_size);
342 typedef void (^auto_zone_register_dump)(const void *base, unsigned long byte_size);
343 typedef void (^auto_zone_node_dump)(const void *address, unsigned long size, unsigned int layout, unsigned long refcount);
344 typedef void (^auto_zone_root_dump)(const void **address);
345 typedef void (^auto_zone_weak_dump)(const void **address, const void *item);
346
347 // Instruments.app utility; causes significant disruption.
348 // This is SPI for Apple's use only. Can and likely will change without regard to 3rd party use.
349 void auto_zone_dump(auto_zone_t *zone,
350 auto_zone_stack_dump stack_dump,
351 auto_zone_register_dump register_dump,
352 auto_zone_node_dump thread_local_node_dump, // unsupported
353 auto_zone_root_dump root_dump,
354 auto_zone_node_dump global_node_dump,
355 auto_zone_weak_dump weak_dump
356 );
357
358 #endif
359
360 enum {
361 auto_is_not_auto = 0,
362 auto_is_auto = (1 << 1), // always on for a start of a node
363 auto_is_local = (1 << 2), // is/was node local
364 };
365
366 typedef int auto_probe_results_t;
367
368 // Instruments.app utility; causes significant disruption.
369 // This is SPI for Apple's use only. Can and likely will change without regard to 3rd party use.
370 auto_probe_results_t auto_zone_probe_unlocked(auto_zone_t *zone, void *address);
371 #ifdef __BLOCKS__
372 void auto_zone_scan_exact(auto_zone_t *zone, void *address, void (^callback)(void *base, unsigned long byte_offset, void *candidate));
373 #endif
a65e5b5 adding auto_zone.h header file, copied from http://www.opensource.app…
Laurent Sansonetti authored
374
375 __END_DECLS
376
377 #endif /* __AUTO_ZONE__ */
Something went wrong with that request. Please try again.