/* Destroys a given thread context. This will also free the nursery. * This means that it must no longer be in use, at all; this can be * ensured by a GC run at thread exit that forces evacuation of all * objects from this nursery to the second generation. Only after * that is true should this be called. */ void MVM_tc_destroy(MVMThreadContext *tc) { MVMint32 i; /* Free specialization state. */ MVM_spesh_sim_stack_destroy(tc, tc->spesh_sim_stack); /* Free the nursery and finalization queue. */ MVM_free(tc->nursery_fromspace); MVM_free(tc->nursery_tospace); MVM_free(tc->finalizing); /* Destroy the second generation allocator. */ MVM_gc_gen2_destroy(tc->instance, tc->gen2); /* Destory the per-thread fixed size allocator state. */ MVM_fixed_size_destroy_thread(tc); /* Destroy all callstack regions. */ MVM_callstack_region_destroy_all(tc); /* Free the thread-specific storage */ MVM_free(tc->gc_work); MVM_free(tc->temproots); MVM_free(tc->gen2roots); MVM_free(tc->finalize); /* Free any memory allocated for NFAs and multi-dim indices. */ MVM_free(tc->nfa_done); MVM_free(tc->nfa_curst); MVM_free(tc->nfa_nextst); MVM_free(tc->nfa_fates); MVM_free(tc->nfa_longlit); MVM_free(tc->multi_dim_indices); /* Free temporary working big integers. */ for (i = 0; i < MVM_NUM_TEMP_BIGINTS; i++) { mp_clear(tc->temp_bigints[i]); MVM_free(tc->temp_bigints[i]); } /* Free the thread context itself. */ memset(tc, 0, sizeof(MVMThreadContext)); MVM_free(tc); }
/* Destroys a given thread context. This will also free the nursery. * This means that it must no longer be in use, at all; this can be * ensured by a GC run at thread exit that forces evacuation of all * objects from this nursery to the second generation. Only after * that is true should this be called. */ void MVM_tc_destroy(MVMThreadContext *tc) { /* We run once again (non-blocking) to eventually close filehandles. */ uv_run(tc->loop, UV_RUN_NOWAIT); /* Free the nursery and finalization queue. */ MVM_free(tc->nursery_fromspace); MVM_free(tc->nursery_tospace); MVM_free(tc->finalizing); /* Destroy the second generation allocator. */ MVM_gc_gen2_destroy(tc->instance, tc->gen2); /* Destroy all callstack regions. */ MVM_callstack_region_destroy_all(tc); /* Free the thread-specific storage */ MVM_free(tc->gc_work); MVM_free(tc->temproots); MVM_free(tc->gen2roots); MVM_free(tc->finalize); /* Free any memory allocated for NFAs and multi-dim indices. */ MVM_free(tc->nfa_done); MVM_free(tc->nfa_curst); MVM_free(tc->nfa_nextst); MVM_free(tc->nfa_fates); MVM_free(tc->nfa_longlit); MVM_free(tc->multi_dim_indices); /* Free per-thread lexotic cache. */ MVM_free(tc->lexotic_cache); /* Destroy the libuv event loop */ uv_loop_delete(tc->loop); /* Free the thread context itself. */ memset(tc, 0, sizeof(MVMThreadContext)); MVM_free(tc); }