// Resize the buffer to a max size of `newlen` // The buffer can either be newly allocated or realloc'd, the return // value is 1 if a new buffer is allocated and 0 if it is realloc'd. // the caller needs to take care of moving the data from the old buffer // to the new one if necessary. // When this function returns, the `->data` pointer always points to // the **beginning** of the new buffer. static int NOINLINE array_resize_buffer(jl_array_t *a, size_t newlen) { jl_ptls_t ptls = jl_get_ptls_states(); assert(!a->flags.isshared || a->flags.how == 3); size_t elsz = a->elsize; size_t nbytes = newlen * elsz; size_t oldnbytes = a->maxsize * elsz; size_t oldoffsnb = a->offset * elsz; size_t oldlen = a->nrows; assert(nbytes >= oldnbytes); if (elsz == 1) { nbytes++; oldnbytes++; } int newbuf = 0; if (a->flags.how == 2) { // already malloc'd - use realloc char *olddata = (char*)a->data - oldoffsnb; a->data = jl_gc_managed_realloc(olddata, nbytes, oldnbytes, a->flags.isaligned, (jl_value_t*)a); } else { newbuf = 1; if ( #ifdef _P64 nbytes >= MALLOC_THRESH #else elsz > 4 #endif ) { a->data = jl_gc_managed_malloc(nbytes); jl_gc_track_malloced_array(ptls, a); a->flags.how = 2; a->flags.isaligned = 1; } else { a->data = jl_gc_alloc_buf(ptls, nbytes); a->flags.how = 1; jl_gc_wb_buf(a, a->data, nbytes); } } if (JL_ARRAY_IMPL_NUL && elsz == 1) memset((char*)a->data + oldnbytes - 1, 0, nbytes - oldnbytes + 1); (void)oldlen; assert(oldlen == a->nrows && "Race condition detected: recursive resizing on the same array."); a->flags.isshared = 0; a->maxsize = newlen; return newbuf; }
static jl_binding_t *new_binding(jl_sym_t *name) { jl_ptls_t ptls = jl_get_ptls_states(); assert(jl_is_symbol(name)); jl_binding_t *b = (jl_binding_t*)jl_gc_alloc_buf(ptls, sizeof(jl_binding_t)); b->name = name; b->value = NULL; b->owner = NULL; b->globalref = NULL; b->constp = 0; b->exportp = 0; b->imported = 0; b->deprecated = 0; return b; }
void jl_copy_excstack(jl_excstack_t *dest, jl_excstack_t *src) JL_NOTSAFEPOINT { assert(dest->reserved_size >= src->top); memcpy(jl_excstack_raw(dest), jl_excstack_raw(src), sizeof(uintptr_t)*src->top); dest->top = src->top; } void jl_reserve_excstack(jl_excstack_t **stack JL_REQUIRE_ROOTED_SLOT, size_t reserved_size) { jl_excstack_t *s = *stack; if (s && s->reserved_size >= reserved_size) return; size_t bufsz = sizeof(jl_excstack_t) + sizeof(uintptr_t)*reserved_size; jl_excstack_t *new_s = (jl_excstack_t*)jl_gc_alloc_buf(jl_get_ptls_states(), bufsz); new_s->top = 0; new_s->reserved_size = reserved_size; if (s) jl_copy_excstack(new_s, s); *stack = new_s; } void jl_push_excstack(jl_excstack_t **stack JL_REQUIRE_ROOTED_SLOT JL_ROOTING_ARGUMENT, jl_value_t *exception JL_ROOTED_ARGUMENT, uintptr_t *bt_data, size_t bt_size) { jl_reserve_excstack(stack, (*stack ? (*stack)->top : 0) + bt_size + 2); jl_excstack_t *s = *stack; memcpy(jl_excstack_raw(s) + s->top, bt_data, sizeof(uintptr_t)*bt_size); s->top += bt_size + 2;