Skip to content

Commit

Permalink
Add a non-allocating version of fieldref
Browse files Browse the repository at this point in the history
Similar to the commit for arrayref, a non-allocating version of fieldref
allows the static analyzer to know about these invariants.
  • Loading branch information
Keno committed Jan 23, 2018
1 parent 42a9fbb commit 2171c41
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v)
if (jl_typeis(v, jl_labelnode_type))
return julia_to_list2(fl_ctx, (jl_value_t*)label_sym, jl_fieldref(v,0));
if (jl_typeis(v, jl_linenumbernode_type)) {
jl_value_t *file = jl_fieldref(v,1); // non-allocating
jl_value_t *file = jl_fieldref_noalloc(v,1); // non-allocating
jl_value_t *line = jl_fieldref(v,0); // allocating
value_t args = julia_to_list2(fl_ctx, line, file);
fl_gc_handle(fl_ctx, &args);
Expand Down
2 changes: 1 addition & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3742,7 +3742,7 @@ static jl_cgval_t emit_expr(jl_codectx_t &ctx, jl_value_t *expr)
if (!jl_is_expr(expr)) {
int needroot = true;
if (jl_is_quotenode(expr)) {
expr = jl_fieldref(expr,0);
expr = jl_fieldref_noalloc(expr,0);
}
// numeric literals
if (jl_is_int32(expr)) {
Expand Down
9 changes: 9 additions & 0 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,15 @@ JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i)
return jl_new_bits(ty, (char*)v + offs);
}

JL_DLLEXPORT jl_value_t *jl_get_nth_field_noalloc(jl_value_t *v JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT
{
jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v);
assert(i < jl_datatype_nfields(st));
size_t offs = jl_field_offset(st,i);
assert(jl_field_isptr(st,i));
return *(jl_value_t**)((char*)v + offs);
}

JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i)
{
jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v);
Expand Down
3 changes: 3 additions & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ STATIC_INLINE void jl_array_uint8_set(void *a, size_t i, uint8_t x)
#define jl_expr_nargs(e) jl_array_len(((jl_expr_t*)(e))->args)

#define jl_fieldref(s,i) jl_get_nth_field(((jl_value_t*)(s)),i)
#define jl_fieldref_noalloc(s,i) jl_get_nth_field_noalloc(((jl_value_t*)(s)),i)
#define jl_nfields(v) jl_datatype_nfields(jl_typeof(v))

// Not using jl_fieldref to avoid allocations
Expand Down Expand Up @@ -1212,6 +1213,8 @@ STATIC_INLINE jl_vararg_kind_t jl_va_tuple_kind(jl_datatype_t *t)
// structs
JL_DLLEXPORT int jl_field_index(jl_datatype_t *t, jl_sym_t *fld, int err);
JL_DLLEXPORT jl_value_t *jl_get_nth_field(jl_value_t *v, size_t i);
// Like jl_get_nth_field above, but asserts if it needs to allocate
JL_DLLEXPORT jl_value_t *jl_get_nth_field_noalloc(jl_value_t *v JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT;
JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i);
JL_DLLEXPORT void jl_set_nth_field(jl_value_t *v, size_t i,
jl_value_t *rhs);
Expand Down
2 changes: 1 addition & 1 deletion src/rtutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt
}
if (vt == jl_typemap_entry_type) {
n += jl_printf(out, ", next=↩︎\n ");
n += jl_static_show_x(out, jl_fieldref(v, 0), depth);
n += jl_static_show_x(out, jl_fieldref_noalloc(v, 0), depth);
}
}
n += jl_printf(out, ")");
Expand Down

0 comments on commit 2171c41

Please sign in to comment.