/*-------------------------------------------------------------------------*/ void count_struct_type_ref (struct_type_t * pSType) /* Count all references held by struct typeobject <pSType> */ { unsigned short num; pSType->ref++; if (test_memory_reference(pSType)) { note_malloced_block_ref(pSType); if (pSType->member) note_malloced_block_ref(pSType->member); count_struct_name_ref(pSType->name); /* If we're a newer definition, remember us in the name. */ if (!pSType->name->current || pSType->name->current->prog_id < pSType->prog_id) pSType->name->current = pSType; if (pSType->unique_name) count_ref_from_string(pSType->unique_name); if (pSType->base) count_struct_type_ref(pSType->base); for (num = struct_t_size(pSType); num-- > 0; ) { count_ref_from_string(pSType->member[num].name); count_lpctype_ref(pSType->member[num].type); } } } /* count_struct_type_ref() */
/*-------------------------------------------------------------------------*/ void count_simul_efun_refs (void) /* GC support: count the references of all memory held by the module. */ { if (simul_efun_file_name) count_ref_from_string(simul_efun_file_name); if (simul_efunp) { int i; note_malloced_block_ref((char *)simul_efunp); for (i = num_simul_efun; --i >= 0; ) count_ref_from_string(simul_efunp[i].name); } if (simul_efun_vector && !simul_efun_vector->ref++) { note_malloced_block_ref((char *)simul_efun_vector); count_ref_in_vector( simul_efun_vector->item, VEC_SIZE(simul_efun_vector) ); } if (simul_efun_program) mark_program_ref(simul_efun_program); } /* count_simul_efun_refs() */
void mempool_note_refs (Mempool pPool) /* GC Support: Note the refs of all memory associated with <pPool> and * its dependees. */ { Memblock pBlock; note_malloced_block_ref(pPool); for (pBlock = pPool->pBlocks; pBlock; pBlock = pBlock->pNext) note_malloced_block_ref(pBlock); for (pBlock = pPool->pFree; pBlock; pBlock = pBlock->pNext) note_malloced_block_ref(pBlock); for (pPool = pPool->pSubPools; pPool != NULL; pPool = pPool->pNextSub) mempool_note_refs(pPool); } /* mempool_note_refs() */
void mb_note_refs (void) /* GC Support: Note the refs of all memory associated with the * memory buffers. */ { int i; for (i = 0; i < mbMax; i++) { if (membuffers[i].mem != NULL) note_malloced_block_ref(membuffers[i].mem); } } /* mb_note_refs() */
/*-------------------------------------------------------------------------*/ void count_struct_name_ref (struct_name_t * pSName) /* Count all references held by struct name object <pSName> */ { pSName->ref++; if (test_memory_reference(pSName)) { note_malloced_block_ref(pSName); count_ref_from_string(pSName->name); count_ref_from_string(pSName->prog_name); } } /* count_struct_name_ref() */
/*-------------------------------------------------------------------------*/ void count_struct_ref (struct_t * pStruct) /* Count all references held by struct <pStruct> */ { pStruct->ref++; if (test_memory_reference(pStruct)) { note_malloced_block_ref(pStruct); count_struct_type_ref(pStruct->type); if (struct_size(pStruct)) { count_ref_in_vector(pStruct->member, struct_size(pStruct)); } } } /* count_struct_ref() */
/*-------------------------------------------------------------------------*/ void count_ref_from_wiz_list (void) /* GC support: Count the refs for the wiz_list memory. */ { wiz_list_t *w; for (w = all_wiz; w; w = w->next) { count_ref_from_string(w->name); count_ref_in_vector(&w->extra, 1); if(w->file_name) count_ref_from_string(w->file_name); if (w->error_message) count_ref_from_string(w->error_message); note_malloced_block_ref((char *)w); } count_ref_in_vector(&default_wizlist_entry.extra, 1); } /* count_ref_from_wiz_list() */
/*-------------------------------------------------------------------------*/ void count_lpctype_ref (lpctype_t *t) /* Count all references by <t>. */ { bool repair = false; if (!t) return; if (t->t_static) { /* Just repair not-refcounted references. */ repair = true; } else { t->ref++; if (test_memory_reference(t)) { note_malloced_block_ref(t); repair = true; switch(t->t_class) { case TCLASS_PRIMARY: break; /* Can't happen. See above. */ case TCLASS_STRUCT: if (t->t_struct) { count_struct_type_ref(t->t_struct); t->t_struct->lpctype = t; } break; case TCLASS_ARRAY: count_lpctype_ref(t->t_array.element); break; case TCLASS_UNION: count_lpctype_ref(t->t_union.head); count_lpctype_ref(t->t_union.member); break; } } } if (repair) { switch(t->t_class) { case TCLASS_PRIMARY: case TCLASS_STRUCT: break; /* Nothing to do. */ case TCLASS_ARRAY: t->t_array.element->array_of = t; break; case TCLASS_UNION: /* Did we already set the pointers back? */ if (t->t_union.next == NULL) { t->t_union.next = t->t_union.head->unions_of; t->t_union.head->unions_of = t; } break; } } } /* count_lpctype_ref() */
/*-------------------------------------------------------------------------*/ void remove_unreferenced_structs (void) /* Free all structs in the table which are not marked as referenced. * This function must be called before freeing all unreferenced strings! */ { size_t num; if (!table || !table_size) return; for (num = 0; num < table_size; num++) { struct_name_t * this, * prev; for (prev = NULL, this = table[num]; this != NULL; ) { if (!test_memory_reference(this)) { prev = this; this = this->next; } else { struct_name_t * next = this->next; if (prev) prev->next = next; else table[num] = next; num_types--; /* Now we deallocate the memory for the struct name * structure. */ size_struct_type -= STRUCT_NAME_MEMSIZE; dprintf2(gcollect_outfd, "struct name %x '%s' was left " "unreferenced, freeing now.\n" , (p_int) this , (p_int) get_txt(this->name) ); /* Reference all strings and free them, to avoid unnecessary * 'string unreferenced' diagnostics. */ count_ref_from_string(this->name); free_mstring(this->name); count_ref_from_string(this->prog_name); free_mstring(this->prog_name); /* Reference the memory (to update its flags) and free it */ note_malloced_block_ref(this); xfree(this); this = next; } } } /* for (num) */ } /* remove_unreferenced_structs() */