Confirmed users, Bureaucrats and Sysops emeriti
1,217
edits
(The allocator API) |
|||
| Line 84: | Line 84: | ||
== Tracing == | == Tracing == | ||
Some SpiderMonkey 1.8 JSAPI features, yet to be documented, need this. See [[mdc:JSAPI Reference#Memory_management]]. | Some SpiderMonkey 1.8 JSAPI features, yet to be documented, need this. See [[mdc:JSAPI Reference#Memory_management]]. | ||
== The Memory API == | |||
This is a description of the API that the allocator needs to provide to the GC engine which runs atop it: | |||
/* GC Heap API */ | |||
typedef struct gcheap gcheap; | |||
gcheap * gc_create_heap(); | |||
void gc_destroy_heap(gcheap *heap); | |||
/* Layout API */ | |||
typedef struct gclayout gclayout; | |||
/* Create a layout object which represents the layout of pointers within | |||
an object type. | |||
@param bitmap An array of bytes. Each byte represents one word of the | |||
target object (there must be size / 4 entries) | |||
0 - the word is not a pointer | |||
1 - the word is a pointer, perhaps an interior pointer, and | |||
perhaps a pointer to an rcobject | |||
2 - the word is a jsval | |||
3 - the word is a ttbox | |||
*/ | |||
gclayout * gc_create_layout(gcheap *heap, size_t size, | |||
char *bitmap); | |||
/* Allocation API */ | |||
typedef enum gcallocflags { | |||
GC_HAS_FINALIZER | |||
}; | |||
/* allocate memory which has no pointers */ | |||
void * gc_alloc_no_pointers(gcheap *heap, size_t size, | |||
int gcallocflags); | |||
/* allocate memory in which every word is a pointer */ | |||
void * gc_alloc_all_pointers(gcheap *heap, size_t size, | |||
int gcallocflags); | |||
/* allocate memory in which every word must be conservatively scanned | |||
for pointers */ | |||
void * gc_alloc_conservative(gcheap *heap, size_t size, | |||
int gcallocflags); | |||
/* allocate memory using a layout object */ | |||
void * gc_alloc_with_layout(gcheap *heap, gclayout *layout, | |||
int gcallocflags); | |||
/* allocate an array of objects */ | |||
void * gc_alloc_array_with_layout(gcheap *heap, gclayout *header_layout, | |||
gclayout *entry_layout, size_t entrycount, | |||
gcallocflags); | |||
void gc_free(gcheap *heap); | |||
/* APIs for marking */ | |||
/* Begin the process of mark/sweep: after this call, gc_is_marked should | |||
return GC_UNMARKED for all allocations */ | |||
void gc_begin_mark(gcheap *heap); | |||
/* @param object must be the outermost pointer to the allocation */ | |||
void gc_mark_object(gcheap *heap, void *object); | |||
/* Get the "next" object which has been marked but not yet processed. | |||
The GC engine needs to know about the object layout, but I don't know | |||
the best way to expose this (or whether the allocator ought to do that?) */ | |||
void * gc_get_next_unprocessed(gcheap *heap, some_kind_of_layout_object); | |||
typedef enum gcmarkstate { | |||
GC_NOT_GCOBJECT, /* this pointer is not a gc allocation */ | |||
GC_UNMARKED, | |||
GC_MARKED, /* gc_mark_object, but not yet gc_get_next_unprocessed */ | |||
GC_PROCESSED /* processed by gc_get_next_unprocessed */ | |||
} gcmarkstate; | |||
/* @param object must be an exterior pointer to an object in this heap */ | |||
gcmarkstate gc_get_markstate(gcheap *heap, void *object); | |||
/* @param object inout - in is a conservative pointer | |||
if the function returns something other than GC_NOT_GCOBJECT, | |||
it will be set to the "outer" pointer */ | |||
gcmarkstate gc_conservative_beginning(gcheap *heap, void **object); | |||
void gc_mark_stack(gcheap *heap); | |||
/* Inform the allocator that we're done marking. The allocator will sweep | |||
all unmarked objects, firing finalizers where appropriate. */ | |||
gc_end_mark(gcheap *heap); | |||
Things to be specified: | |||
* Synchronization | |||
* RCObjects - other than write barriers and a flag bit, I don't think the allocator itself needs to know anything about RCObjects | |||