GC_API void GC_CALL GC_debug_end_stubborn_change(const void *p) { const void * q = GC_base_C(p); if (NULL == q) { ABORT_ARG1("GC_debug_end_stubborn_change: bad arg", ": %p", p); } GC_end_stubborn_change(q); }
GC_API void GC_CALL GC_debug_change_stubborn(const void *p) { const void * q = GC_base_C(p); hdr * hhdr; if (q == 0) { ABORT_ARG1("GC_debug_change_stubborn: bad arg", ": %p", p); } hhdr = HDR(q); if (hhdr -> hb_obj_kind != STUBBORN) { ABORT_ARG1("GC_debug_change_stubborn: arg not stubborn", ": %p", p); } GC_change_stubborn(q); }
STATIC int GC_register_disappearing_link_inner( struct dl_hashtbl_s *dl_hashtbl, void **link, const void *obj, const char *tbl_log_name) { struct disappearing_link *curr_dl; size_t index; struct disappearing_link * new_dl; DCL_LOCK_STATE; LOCK(); GC_ASSERT(obj != NULL && GC_base_C(obj) == obj); if (dl_hashtbl -> log_size == -1 || dl_hashtbl -> entries > ((word)1 << dl_hashtbl -> log_size)) { GC_grow_table((struct hash_chain_entry ***)&dl_hashtbl -> head, &dl_hashtbl -> log_size); GC_COND_LOG_PRINTF("Grew %s table to %u entries\n", tbl_log_name, 1 << (unsigned)dl_hashtbl -> log_size); } index = HASH2(link, dl_hashtbl -> log_size); for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); UNLOCK(); return GC_DUPLICATE; } } new_dl = (struct disappearing_link *) GC_INTERNAL_MALLOC(sizeof(struct disappearing_link),NORMAL); if (0 == new_dl) { GC_oom_func oom_fn = GC_oom_fn; UNLOCK(); new_dl = (struct disappearing_link *) (*oom_fn)(sizeof(struct disappearing_link)); if (0 == new_dl) { return GC_NO_MEMORY; } /* It's not likely we'll make it here, but ... */ LOCK(); /* Recalculate index since the table may grow. */ index = HASH2(link, dl_hashtbl -> log_size); /* Check again that our disappearing link not in the table. */ for (curr_dl = dl_hashtbl -> head[index]; curr_dl != 0; curr_dl = dl_next(curr_dl)) { if (curr_dl -> dl_hidden_link == GC_HIDE_POINTER(link)) { curr_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); UNLOCK(); # ifndef DBG_HDRS_ALL /* Free unused new_dl returned by GC_oom_fn() */ GC_free((void *)new_dl); # endif return GC_DUPLICATE; } } } new_dl -> dl_hidden_obj = GC_HIDE_POINTER(obj); new_dl -> dl_hidden_link = GC_HIDE_POINTER(link); dl_set_next(new_dl, dl_hashtbl -> head[index]); dl_hashtbl -> head[index] = new_dl; dl_hashtbl -> entries++; UNLOCK(); return GC_SUCCESS; }