static jl_typemap_level_t *jl_new_typemap_level(void) { jl_typemap_level_t *cache = (jl_typemap_level_t*)jl_gc_allocobj(sizeof(jl_typemap_level_t)); jl_set_typeof(cache, jl_typemap_level_type); cache->key = NULL; cache->linear = (jl_typemap_entry_t*)jl_nothing; cache->arg1 = (jl_array_t*)jl_nothing; cache->targ = (jl_array_t*)jl_nothing; return cache; }
JL_DLLEXPORT jl_methtable_t *jl_new_method_table(jl_sym_t *name, jl_module_t *module) { jl_methtable_t *mt = (jl_methtable_t*)jl_gc_allocobj(sizeof(jl_methtable_t)); jl_set_typeof(mt, jl_methtable_type); mt->name = jl_demangle_typename(name); mt->module = module; mt->defs.unknown = jl_nothing; mt->cache.unknown = jl_nothing; mt->max_args = 0; mt->kwsorter = NULL; #ifdef JL_GF_PROFILE mt->ncalls = 0; #endif return mt; }
// own_buffer != 0 iff GC should call free() on this pointer eventually jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data, size_t nel, int own_buffer) { size_t elsz; jl_array_t *a; jl_value_t *el_type = jl_tparam0(atype); int isunboxed = store_unboxed(el_type); if (isunboxed) elsz = jl_datatype_size(el_type); else elsz = sizeof(void*); int ndimwords = jl_array_ndimwords(1); int tsz = JL_ARRAY_ALIGN(sizeof(jl_array_t) + ndimwords*sizeof(size_t), 16); a = (jl_array_t*)jl_gc_allocobj(tsz); jl_set_typeof(a, atype); a->pooled = tsz <= GC_MAX_SZCLASS; a->data = data; #ifdef STORE_ARRAY_LEN a->length = nel; #endif a->elsize = elsz; a->ptrarray = !isunboxed; a->ndims = 1; a->isshared = 1; a->isaligned = 0; // TODO: allow passing memalign'd buffers if (own_buffer) { a->how = 2; jl_gc_track_malloced_array(a); jl_gc_count_allocd(nel*elsz + (elsz == 1 ? 1 : 0)); } else { a->how = 0; } a->nrows = nel; a->maxsize = nel; a->offset = 0; return a; }
JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name) { jl_module_t *m = (jl_module_t*)jl_gc_allocobj(sizeof(jl_module_t)); jl_set_typeof(m, jl_module_type); JL_GC_PUSH1(&m); assert(jl_is_symbol(name)); m->name = name; m->parent = NULL; m->istopmod = 0; m->uuid = uv_now(uv_default_loop()); m->counter = 0; htable_new(&m->bindings, 0); arraylist_new(&m->usings, 0); if (jl_core_module) { jl_module_using(m, jl_core_module); } // export own name, so "using Foo" makes "Foo" itself visible jl_set_const(m, name, (jl_value_t*)m); jl_module_export(m, name); JL_GC_POP(); return m; }
jl_typemap_entry_t *jl_typemap_insert(union jl_typemap_t *cache, jl_value_t *parent, jl_tupletype_t *type, jl_svec_t *tvars, jl_tupletype_t *simpletype, jl_svec_t *guardsigs, jl_value_t *newvalue, int8_t offs, const struct jl_typemap_info *tparams, jl_value_t **overwritten) { assert(jl_is_tuple_type(type)); if (!simpletype) { simpletype = (jl_tupletype_t*)jl_nothing; } if ((jl_value_t*)simpletype == jl_nothing) { jl_typemap_entry_t *ml = jl_typemap_assoc_by_type(*cache, type, NULL, 1, 0, offs); if (ml && ml->simplesig == (void*)jl_nothing) { if (overwritten != NULL) *overwritten = ml->func.value; if (newvalue == NULL) // don't overwrite with guard entries return ml; // sigatomic begin ml->sig = type; jl_gc_wb(ml, ml->sig); ml->simplesig = simpletype; jl_gc_wb(ml, ml->simplesig); ml->tvars = tvars; jl_gc_wb(ml, ml->tvars); ml->va = jl_is_va_tuple(type); // TODO: `l->func` or `l->func->roots` might need to be rooted ml->func.value = newvalue; if (newvalue) jl_gc_wb(ml, newvalue); // sigatomic end return ml; } } if (overwritten != NULL) *overwritten = NULL; jl_typemap_entry_t *newrec = (jl_typemap_entry_t*)jl_gc_allocobj(sizeof(jl_typemap_entry_t)); jl_set_typeof(newrec, jl_typemap_entry_type); newrec->sig = type; newrec->simplesig = simpletype; newrec->tvars = tvars; newrec->func.value = newvalue; newrec->guardsigs = guardsigs; newrec->next = (jl_typemap_entry_t*)jl_nothing; // compute the complexity of this type signature newrec->va = jl_is_va_tuple(type); newrec->issimplesig = (tvars == jl_emptysvec); // a TypeVar environment needs an complex matching test newrec->isleafsig = newrec->issimplesig && !newrec->va; // entirely leaf types don't need to be sorted JL_GC_PUSH1(&newrec); size_t i, l; for (i = 0, l = jl_datatype_nfields(type); i < l && newrec->issimplesig; i++) { jl_value_t *decl = jl_field_type(type, i); if (decl == (jl_value_t*)jl_datatype_type) newrec->isleafsig = 0; // Type{} may have a higher priority than DataType else if (decl == (jl_value_t*)jl_typector_type) newrec->isleafsig = 0; // Type{} may have a higher priority than TypeConstructor else if (jl_is_type_type(decl)) newrec->isleafsig = 0; // Type{} may need special processing to compute the match else if (jl_is_vararg_type(decl)) newrec->isleafsig = 0; // makes iteration easier when the endpoints are the same else if (decl == (jl_value_t*)jl_any_type) newrec->isleafsig = 0; // Any needs to go in the general cache else if (!jl_is_leaf_type(decl)) // anything else can go through the general subtyping test newrec->isleafsig = newrec->issimplesig = 0; } // TODO: assert that guardsigs == jl_emptysvec && simplesig == jl_nothing if isleafsig and optimize with that knowledge? jl_typemap_insert_generic(cache, parent, newrec, NULL, offs, tparams); JL_GC_POP(); return newrec; }
static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims, int isunboxed, int elsz) { size_t i, tot, nel=1; wideint_t prod; void *data; jl_array_t *a; for(i=0; i < ndims; i++) { prod = (wideint_t)nel * (wideint_t)dims[i]; if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array dimensions"); nel = prod; } if (isunboxed) { prod = (wideint_t)elsz * (wideint_t)nel; if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array size"); tot = prod; if (elsz == 1) { // hidden 0 terminator for all byte arrays tot++; } } else { prod = (wideint_t)sizeof(void*) * (wideint_t)nel; if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array size"); tot = prod; } int ndimwords = jl_array_ndimwords(ndims); int tsz = JL_ARRAY_ALIGN(sizeof(jl_array_t) + ndimwords*sizeof(size_t), 16); if (tot <= ARRAY_INLINE_NBYTES) { if (isunboxed && elsz >= 4) tsz = JL_ARRAY_ALIGN(tsz, 16); // align data area 16 size_t doffs = tsz; tsz += tot; tsz = JL_ARRAY_ALIGN(tsz, 16); // align whole object 16 a = (jl_array_t*)jl_gc_allocobj(tsz); jl_set_typeof(a, atype); a->how = 0; data = (char*)a + doffs; if (tot > 0 && !isunboxed) { memset(data, 0, tot); } } else { tsz = JL_ARRAY_ALIGN(tsz, 16); // align whole object 16 a = (jl_array_t*)jl_gc_allocobj(tsz); JL_GC_PUSH1(&a); jl_set_typeof(a, atype); // temporarily initialize to make gc-safe a->data = NULL; a->how = 2; data = jl_gc_managed_malloc(tot); jl_gc_track_malloced_array(a); if (!isunboxed) memset(data, 0, tot); JL_GC_POP(); } a->pooled = tsz <= GC_MAX_SZCLASS; a->data = data; if (elsz == 1) ((char*)data)[tot-1] = '\0'; #ifdef STORE_ARRAY_LEN a->length = nel; #endif a->ndims = ndims; a->ptrarray = !isunboxed; a->elsize = elsz; a->isshared = 0; a->isaligned = 1; a->offset = 0; if (ndims == 1) { a->nrows = nel; a->maxsize = nel; } else { size_t *adims = &a->nrows; for(i=0; i < ndims; i++) adims[i] = dims[i]; } return a; }
jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data, jl_value_t *dims, int own_buffer) { size_t i, elsz, nel=1; jl_array_t *a; size_t ndims = jl_nfields(dims); wideint_t prod; for(i=0; i < ndims; i++) { prod = (wideint_t)nel * (wideint_t)jl_unbox_long(jl_fieldref(dims, i)); if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array dimensions"); nel = prod; } jl_value_t *el_type = jl_tparam0(atype); int isunboxed = store_unboxed(el_type); if (isunboxed) elsz = jl_datatype_size(el_type); else elsz = sizeof(void*); int ndimwords = jl_array_ndimwords(ndims); int tsz = JL_ARRAY_ALIGN(sizeof(jl_array_t) + ndimwords*sizeof(size_t), 16); a = (jl_array_t*)jl_gc_allocobj(tsz); jl_set_typeof(a, atype); a->pooled = tsz <= GC_MAX_SZCLASS; a->data = data; #ifdef STORE_ARRAY_LEN a->length = nel; #endif a->elsize = elsz; a->ptrarray = !isunboxed; a->ndims = ndims; a->offset = 0; a->isshared = 1; a->isaligned = 0; if (own_buffer) { a->how = 2; jl_gc_track_malloced_array(a); jl_gc_count_allocd(nel*elsz + (elsz == 1 ? 1 : 0)); } else { a->how = 0; } if (ndims == 1) { a->nrows = nel; a->maxsize = nel; } else { size_t *adims = &a->nrows; // jl_fieldref can allocate JL_GC_PUSH1(&a); for(i=0; i < ndims; i++) { adims[i] = jl_unbox_long(jl_fieldref(dims, i)); } JL_GC_POP(); } return a; }
jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data, jl_value_t *dims) { size_t i; jl_array_t *a; size_t ndims = jl_nfields(dims); int ndimwords = jl_array_ndimwords(ndims); int tsz = JL_ARRAY_ALIGN(sizeof(jl_array_t) + ndimwords*sizeof(size_t) + sizeof(void*), 16); a = (jl_array_t*)jl_gc_allocobj(tsz); jl_set_typeof(a, atype); a->pooled = tsz <= GC_MAX_SZCLASS; a->ndims = ndims; a->offset = 0; a->data = NULL; a->isaligned = data->isaligned; jl_value_t *el_type = jl_tparam0(atype); if (store_unboxed(el_type)) { a->elsize = jl_datatype_size(el_type); a->ptrarray = 0; } else { a->elsize = sizeof(void*); a->ptrarray = 1; } JL_GC_PUSH1(&a); jl_array_t *owner = data; // if data is itself a shared wrapper, // owner should point back to the original array if (owner->how == 3) { owner = (jl_array_t*)jl_array_data_owner(owner); } assert(owner->how != 3); jl_array_data_owner(a) = (jl_value_t*)owner; a->how = 3; a->data = data->data; a->isshared = 1; data->isshared = 1; if (ndims == 1) { size_t l = ((size_t*)jl_data_ptr(dims))[0]; #ifdef STORE_ARRAY_LEN a->length = l; #endif a->nrows = l; a->maxsize = l; } else { size_t *adims = &a->nrows; size_t l=1; wideint_t prod; for(i=0; i < ndims; i++) { adims[i] = ((size_t*)jl_data_ptr(dims))[i]; prod = (wideint_t)l * (wideint_t)adims[i]; if (prod > (wideint_t) MAXINTVAL) jl_error("invalid Array dimensions"); l = prod; } #ifdef STORE_ARRAY_LEN a->length = l; #endif } JL_GC_POP(); return a; }