Пример #1
0
/* Initializes a new thread context. Note that this doesn't set up a
 * thread itself, it just creates the data structure that exists in
 * MoarVM per thread. */
MVMThreadContext * MVM_tc_create(MVMThreadContext *parent, MVMInstance *instance) {
    MVMThreadContext *tc = MVM_calloc(1, sizeof(MVMThreadContext));
    MVMint32 i;

    /* Associate with VM instance. */
    tc->instance = instance;

    /* Set up GC nursery. We only allocate tospace initially, and allocate
     * fromspace the first time this thread GCs, provided it ever does. */
    tc->nursery_tospace_size = MVM_gc_new_thread_nursery_size(instance);
    tc->nursery_tospace     = MVM_calloc(1, tc->nursery_tospace_size);
    tc->nursery_alloc       = tc->nursery_tospace;
    tc->nursery_alloc_limit = (char *)tc->nursery_alloc + tc->nursery_tospace_size;

    /* Set up temporary root handling. */
    tc->num_temproots   = 0;
    tc->alloc_temproots = MVM_TEMP_ROOT_BASE_ALLOC;
    tc->temproots       = MVM_malloc(sizeof(MVMCollectable **) * tc->alloc_temproots);

    /* Set up intergenerational root handling. */
    tc->num_gen2roots   = 0;
    tc->alloc_gen2roots = 64;
    tc->gen2roots       = MVM_malloc(sizeof(MVMCollectable *) * tc->alloc_gen2roots);

    /* Set up the second generation allocator. */
    tc->gen2 = MVM_gc_gen2_create(instance);

    /* The fixed size allocator also keeps pre-thread state. */
    MVM_fixed_size_create_thread(tc);

    /* Allocate an initial call stack region for the thread. */
    MVM_callstack_region_init(tc);

    /* Initialize random number generator state. */
    MVM_proc_seed(tc, (MVM_platform_now() / 10000) * MVM_proc_getpid(tc));

    /* Allocate temporary big integers. */
    for (i = 0; i < MVM_NUM_TEMP_BIGINTS; i++) {
        tc->temp_bigints[i] = MVM_malloc(sizeof(mp_int));
        mp_init(tc->temp_bigints[i]);
    }

    /* Initialize frame sequence numbers */
    tc->next_frame_nr = 0;
    tc->current_frame_nr = 0;

    /* Initialize last_payload, so we can be sure it's never NULL and don't
     * need to check. */
    tc->last_payload = instance->VMNull;

    /* Initialize plugin_guard_args so we never have to do a NULL check */
    tc->plugin_guard_args = instance->VMNull;

    /* Note that these two assignments above are repeated in
     * MVM_6model_bootstrap because VMNull doesn't exist yet when the very
     * first tc is created. */

    return tc;
}
Пример #2
0
/* Initializes a new thread context. Note that this doesn't set up a
 * thread itself, it just creates the data structure that exists in
 * MoarVM per thread. */
MVMThreadContext * MVM_tc_create(MVMThreadContext *parent, MVMInstance *instance) {
    MVMThreadContext *tc = MVM_calloc(1, sizeof(MVMThreadContext));

    /* Associate with VM instance. */
    tc->instance = instance;

    /* Use default loop for main thread; create a new one for others. */
    if (instance->main_thread) {
        int r;

        tc->loop = MVM_calloc(1, sizeof(uv_loop_t));
        r = uv_loop_init(tc->loop);
        if (r < 0) {
            MVM_free(tc->loop);
            MVM_free(tc);
            MVM_exception_throw_adhoc(parent, "Could not create a new Thread: %s", uv_strerror(r));
        }
    } else {
        tc->loop = uv_default_loop();
    }

    /* Set up GC nursery. We only allocate tospace initially, and allocate
     * fromspace the first time this thread GCs, provided it ever does. */
    tc->nursery_tospace     = MVM_calloc(1, MVM_NURSERY_SIZE);
    tc->nursery_alloc       = tc->nursery_tospace;
    tc->nursery_alloc_limit = (char *)tc->nursery_alloc + MVM_NURSERY_SIZE;

    /* Set up temporary root handling. */
    tc->num_temproots   = 0;
    tc->alloc_temproots = MVM_TEMP_ROOT_BASE_ALLOC;
    tc->temproots       = MVM_malloc(sizeof(MVMCollectable **) * tc->alloc_temproots);

    /* Set up intergenerational root handling. */
    tc->num_gen2roots   = 0;
    tc->alloc_gen2roots = 64;
    tc->gen2roots       = MVM_malloc(sizeof(MVMCollectable *) * tc->alloc_gen2roots);

    /* Set up the second generation allocator. */
    tc->gen2 = MVM_gc_gen2_create(instance);

    /* Allocate an initial call stack region for the thread. */
    MVM_callstack_region_init(tc);

    /* Initialize random number generator state. */
    MVM_proc_seed(tc, (MVM_platform_now() / 10000) * MVM_proc_getpid(tc));

    /* Initialize frame sequence numbers */
    tc->next_frame_nr = 0;
    tc->current_frame_nr = 0;

    /* Initialize last_payload, so we can be sure it's never NULL and don't
     * need to check. */
    tc->last_payload = instance->VMNull;

    return tc;
}
Пример #3
0
/* Initializes a new thread context. Note that this doesn't set up a
 * thread itself, it just creates the data structure that exists in
 * MoarVM per thread. */
MVMThreadContext * MVM_tc_create(MVMInstance *instance) {
    MVMThreadContext *tc = calloc(1, sizeof(MVMThreadContext));

    /* Associate with VM instance. */
    tc->instance = instance;

    /* Set up GC nursery. */
    tc->nursery_fromspace   = calloc(1, MVM_NURSERY_SIZE);
    tc->nursery_tospace     = calloc(1, MVM_NURSERY_SIZE);
    tc->nursery_alloc       = tc->nursery_tospace;
    tc->nursery_alloc_limit = (char *)tc->nursery_alloc + MVM_NURSERY_SIZE;

    /* Set up temporary root handling. */
    tc->num_temproots   = 0;
    tc->alloc_temproots = 16;
    tc->temproots       = malloc(sizeof(MVMCollectable **) * tc->alloc_temproots);

    /* Set up intergenerational root handling. */
    tc->num_gen2roots   = 0;
    tc->alloc_gen2roots = 64;
    tc->gen2roots       = malloc(sizeof(MVMCollectable *) * tc->alloc_gen2roots);

    /* Set up the second generation allocator. */
    tc->gen2 = MVM_gc_gen2_create(instance);

    /* Set up table of per-static-frame chains. */
    /* XXX For non-first threads, make them start with the size of the
       main thread's table. or, look into lazily initializing this. */
    tc->frame_pool_table_size = MVMInitialFramePoolTableSize;
    tc->frame_pool_table = calloc(MVMInitialFramePoolTableSize, sizeof(MVMFrame *));

    tc->loop = instance->default_loop ? uv_loop_new() : uv_default_loop();

    /* Create a CallCapture for usecapture instructions in this thread (needs
     * special handling in initial thread as this runs before bootstrap). */
    if (instance->CallCapture)
        tc->cur_usecapture = MVM_repr_alloc_init(tc, instance->CallCapture);

    /* Initialize random number generator state. */
    MVM_proc_seed(tc, (MVM_platform_now() / 10000) * MVM_proc_getpid(tc));

#if MVM_HLL_PROFILE_CALLS
#define PROFILE_INITIAL_SIZE (1 << 29)
    tc->profile_data_size = PROFILE_INITIAL_SIZE;
    tc->profile_data = malloc(sizeof(MVMProfileRecord) * PROFILE_INITIAL_SIZE);
    tc->profile_index = 0;
#endif

    return tc;
}