GC_DBG_COLLECT_AT_MALLOC(lb);
if(SMALL_OBJ(lb)) {
- word lg = GC_size_map[lb];
+ word lg;
LOCK();
+ lg = GC_size_map[lb];
op = GC_gcjobjfreelist[lg];
if(EXPECT(0 == op, FALSE)) {
maybe_finalize();
GC_DBG_COLLECT_AT_MALLOC(lb);
if(SMALL_OBJ(lb)) {
- word lg = GC_size_map[lb];
+ word lg;
LOCK();
+ lg = GC_size_map[lb];
op = GC_gcjobjfreelist[lg];
if (EXPECT(0 == op, FALSE)) {
maybe_finalize();
/* Get the element value (converted to bytes) at a given index of */
/* size_map table which provides requested-to-actual allocation size */
/* mapping. Assumes the collector is initialized. Returns -1 if the */
-/* index is out of size_map table bounds. Does not use synchronization. */
+/* index is out of size_map table bounds. Does not use synchronization, */
+/* thus clients should call it using GC_call_with_alloc_lock typically */
+/* to avoid data races on multiprocessors. */
GC_API size_t GC_CALL GC_get_size_map_at(int i);
/* Count total memory use in bytes by all allocated blocks. Acquires */
# endif
size_t _size_map[MAXOBJBYTES+1];
/* Number of granules to allocate when asked for a certain */
- /* number of bytes. */
+ /* number of bytes. Should be accessed with the allocation */
+ /* lock held. */
# ifdef STUBBORN_ALLOC
# define GC_sobjfreelist GC_arrays._sobjfreelist
ptr_t _sobjfreelist[MAXOBJGRANULES+1];
if (SMALL_OBJ(lb)) {
void *op;
void **opp;
- size_t lg = GC_size_map[lb];
+ size_t lg;
DCL_LOCK_STATE;
GC_DBG_COLLECT_AT_MALLOC(lb);
LOCK();
+ lg = GC_size_map[lb];
opp = &GC_obj_kinds[k].ok_freelist[lg];
op = *opp;
if (EXPECT(op != NULL, TRUE)) {
if (EXTRA_BYTES != 0 && lb != 0) lb--;
/* We don't need the extra byte, since this won't be */
/* collected anyway. */
- lg = GC_size_map[lb];
LOCK();
+ lg = GC_size_map[lb];
opp = &GC_obj_kinds[k].ok_freelist[lg];
op = *opp;
if (EXPECT(op != NULL, TRUE)) {
lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES);
if (SMALL_OBJ(lb)) {
GC_DBG_COLLECT_AT_MALLOC(lb);
- lg = GC_size_map[lb];
LOCK();
+ lg = GC_size_map[lb];
op = GC_eobjfreelist[lg];
if (EXPECT(0 == op, FALSE)) {
UNLOCK();