Skip to content

Commit

Permalink
Merge branch 'gen_gc2_smart_ops2c' into gen_gc2
Browse files Browse the repository at this point in the history
  • Loading branch information
bacek committed Feb 15, 2011
2 parents ef3e968 + a6bc49b commit 1164769
Show file tree
Hide file tree
Showing 11 changed files with 2,541 additions and 1,063 deletions.
9 changes: 8 additions & 1 deletion compilers/opsc/src/Ops/Compiler/Actions.pm
Expand Up @@ -88,6 +88,13 @@ method op($/) {
$op<type> := ~$<op_type>;
$op<normalized_args> := @norm_args;

if $op.need_write_barrier {
$op.push(PAST::Op.new(
:pasttype<inline>,
:inline(" PARROT_GC_WRITE_BARRIER(interp, CURRENT_CONTEXT(interp));\n")
));
}

if !%flags<flow> {
my $goto_next := PAST::Op.new(
:pasttype('call'),
Expand All @@ -106,7 +113,7 @@ method op($/) {
$op.push($goto_next);
$op.push(PAST::Op.new(
:pasttype<inline>,
:inline<;>
:inline(";\n"),
));
}

Expand Down
11 changes: 11 additions & 0 deletions compilers/opsc/src/Ops/Op.pm
Expand Up @@ -126,6 +126,17 @@ method name($name?) { self.attr('name', $name, defined($name)) }

method args($args?) { self.attr('args', $args, defined($args)) }

method need_write_barrier() {
my $need := 0;
# We need write barriers only for (in)out PMC|STR
for self.args -> $a {
$need := ($a<type> eq 'STR' || $a<type> eq 'PMC')
&& ($a<direction> eq 'out' || $a<direction> eq 'inout');
return $need if $need;
}
$need;
}

method arg_types($args?) {
my $res := self.attr('arg_types', $args, defined($args));

Expand Down
60 changes: 20 additions & 40 deletions include/parrot/context.h
Expand Up @@ -32,25 +32,17 @@ typedef struct Parrot_CallContext_attributes Parrot_Context;
* Macros to make accessing registers more convenient/readable.
*/

/* Define these macros unconditionally for now until someone can rewrite them
* to use non-function access for NDEBUG builds for great speed; for now they
* need to use this approach to use PMC write barriers effectively */

#define CTX_REG_PMC(i, p, x) (*Parrot_pcc_get_PMC_reg((i), (p), (x)))
#define CTX_REG_STR(i, p, x) (*Parrot_pcc_get_STRING_reg((i), (p), (x)))

#ifndef NDEBUG

# define CTX_REG_PMC(i, p, x) (*Parrot_pcc_get_PMC_reg((i), (p), (x)))
# define CTX_REG_STR(i, p, x) (*Parrot_pcc_get_STRING_reg((i), (p), (x)))
# define CTX_REG_NUM(i, p, x) (*Parrot_pcc_get_FLOATVAL_reg((i), (p), (x)))
# define CTX_REG_INT(i, p, x) (*Parrot_pcc_get_INTVAL_reg((i), (p), (x)))

#else /* NDEBUG */

/* Manually inlined macros. Used in optimized builds */

# define CTX_REG_PMC(i, p, x) (CONTEXT_STRUCT(p)->bp_ps.regs_p[-1L - (x)])
# define CTX_REG_STR(i, p, x) (CONTEXT_STRUCT(p)->bp_ps.regs_s[(x)])
# define CTX_REG_NUM(i, p, x) (CONTEXT_STRUCT(p)->bp.regs_n[-1L - (x)])
# define CTX_REG_INT(i, p, x) (CONTEXT_STRUCT(p)->bp.regs_i[(x)])

#endif

#define REG_NUM(interp, x) CTX_REG_NUM((interp), (interp)->ctx, (x))
Expand Down Expand Up @@ -442,7 +434,7 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
/* HEADERIZER END: src/call/context_accessors.c */

/* Map Context manipulating functions to functions or macros */
#if 0
#ifdef NDEBUG
# define Parrot_pcc_get_context_struct(i, c) CONTEXT_STRUCT(c)

# define Parrot_pcc_get_num_constants(i, c) (CONTEXT_STRUCT(c)->num_constants)
Expand All @@ -455,34 +447,21 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
} while (0)

# define Parrot_pcc_get_continuation(i, c) (CONTEXT_STRUCT(c)->current_cont)
# define Parrot_pcc_set_continuation(i, c, value) (CONTEXT_STRUCT(c)->current_cont = (value))

# define Parrot_pcc_get_caller_ctx(i, c) (CONTEXT_STRUCT(c)->caller_ctx)
# define Parrot_pcc_set_caller_ctx(i, c, value) (CONTEXT_STRUCT(c)->caller_ctx = (value))

# define Parrot_pcc_get_namespace(i, c) (CONTEXT_STRUCT(c)->current_namespace)
# define Parrot_pcc_set_namespace(i, c, value) (CONTEXT_STRUCT(c)->current_namespace = (value))
# define Parrot_pcc_get_object(i, c) (CONTEXT_STRUCT(c)->current_object)
# define Parrot_pcc_get_lex_pad(i, c) (CONTEXT_STRUCT(c)->lex_pad)
# define Parrot_pcc_get_handlers(i, c) (CONTEXT_STRUCT(c)->handlers)

# define Parrot_pcc_get_pc(i, c) (CONTEXT_STRUCT(c)->current_pc)
# define Parrot_pcc_set_pc(i, c, value) (CONTEXT_STRUCT(c)->current_pc = (value))

# define Parrot_pcc_get_HLL(i, c) (CONTEXT_STRUCT(c)->current_HLL)
# define Parrot_pcc_set_HLL(i, c, value) (CONTEXT_STRUCT(c)->current_HLL = (value))

# define Parrot_pcc_get_object(i, c) (CONTEXT_STRUCT(c)->current_object)
# define Parrot_pcc_set_object(i, c, value) (CONTEXT_STRUCT(c)->current_object = (value))

# define Parrot_pcc_get_lex_pad(i, c) (CONTEXT_STRUCT(c)->lex_pad)
# define Parrot_pcc_set_lex_pad(i, c, value) (CONTEXT_STRUCT(c)->lex_pad = (value))

# define Parrot_pcc_get_handlers(i, c) (CONTEXT_STRUCT(c)->handlers)
# define Parrot_pcc_set_handlers(i, c, value) (CONTEXT_STRUCT(c)->handlers = (value))

# define Parrot_pcc_get_outer_ctx(i, c) (CONTEXT_STRUCT(c)->outer_ctx)
# define Parrot_pcc_set_outer_ctx(i, c, value) (CONTEXT_STRUCT(c)->outer_ctx = (value))

# define Parrot_pcc_get_signature(i, c) (CONTEXT_STRUCT(c)->current_sig)
# define Parrot_pcc_set_signature(i, c, value) (CONTEXT_STRUCT(c)->current_sig = (value))

# define Parrot_pcc_get_num_constant(i, c, idx) (CONTEXT_STRUCT(c)->num_constants[(idx)])
# define Parrot_pcc_get_string_constant(i, c, idx) (CONTEXT_STRUCT(c)->str_constants[(idx)])
Expand All @@ -504,8 +483,6 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
# define Parrot_pcc_trace_flags_off(i, c, flags) (CONTEXT_STRUCT(c)->trace_flags &= ~(flags))
# define Parrot_pcc_trace_flags_test(i, c, flags) (CONTEXT_STRUCT(c)->trace_flags & (flags))

# define Parrot_pcc_set_context(i, c) (CURRENT_CONTEXT(i) = (c))

#else

# define Parrot_pcc_get_context_struct(i, c) Parrot_pcc_get_context_struct_func((i), (c))
Expand All @@ -516,13 +493,10 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
# define Parrot_pcc_set_constants(i, c, value) Parrot_pcc_set_constants_func((i), (c), (value))

# define Parrot_pcc_get_continuation(i, c) Parrot_pcc_get_continuation_func((i), (c))
# define Parrot_pcc_set_continuation(i, c, value) Parrot_pcc_set_continuation_func((i), (c), (value))

# define Parrot_pcc_get_caller_ctx(i, c) Parrot_pcc_get_caller_ctx_func((i), (c))
# define Parrot_pcc_set_caller_ctx(i, c, value) Parrot_pcc_set_caller_ctx_func((i), (c), (value))

# define Parrot_pcc_get_namespace(i, c) Parrot_pcc_get_namespace_func((i), (c))
# define Parrot_pcc_set_namespace(i, c, value) Parrot_pcc_set_namespace_func((i), (c), (value))

# define Parrot_pcc_get_pc(i, c) Parrot_pcc_get_pc_func((i), (c))
# define Parrot_pcc_set_pc(i, c, value) Parrot_pcc_set_pc_func((i), (c), (value))
Expand All @@ -531,19 +505,14 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
# define Parrot_pcc_set_HLL(i, c, value) Parrot_pcc_set_HLL_func((i), (c), (value))

# define Parrot_pcc_get_object(i, c) Parrot_pcc_get_object_func((i), (c))
# define Parrot_pcc_set_object(i, c, value) Parrot_pcc_set_object_func((i), (c), (value))

# define Parrot_pcc_get_lex_pad(i, c) Parrot_pcc_get_lex_pad_func((i), (c))
# define Parrot_pcc_set_lex_pad(i, c, value) Parrot_pcc_set_lex_pad_func((i), (c), (value))

# define Parrot_pcc_get_handlers(i, c) Parrot_pcc_get_handlers_func((i), (c))
# define Parrot_pcc_set_handlers(i, c, value) Parrot_pcc_set_handlers_func((i), (c), (value))

# define Parrot_pcc_get_outer_ctx(i, c) Parrot_pcc_get_outer_ctx_func((i), (c))
# define Parrot_pcc_set_outer_ctx(i, c, value) Parrot_pcc_set_outer_ctx_func((i), (c), (value))

# define Parrot_pcc_get_signature(i, c) Parrot_pcc_get_signature_func((i), (c))
# define Parrot_pcc_set_signature(i, c, value) Parrot_pcc_set_signature_func((i), (c), (value))

# define Parrot_pcc_get_num_constant(i, c, idx) Parrot_pcc_get_num_constant_func((i), (c), (idx))
# define Parrot_pcc_get_string_constant(i, c, idx) Parrot_pcc_get_string_constant_func((i), (c), (idx))
Expand All @@ -565,9 +534,20 @@ UINTVAL Parrot_pcc_warnings_test_func(SHIM_INTERP,
# define Parrot_pcc_trace_flags_off(i, c, flags) Parrot_pcc_trace_flags_off_func((i), (c), (flags))
# define Parrot_pcc_trace_flags_test(i, c, flags) Parrot_pcc_trace_flags_test_func((i), (c), (flags))

#endif /* ifndef NDEBUG */


/* TODO Drop defines if set_foo_func in favour set_foo functions */
# define Parrot_pcc_set_continuation(i, c, value) Parrot_pcc_set_continuation_func((i), (c), (value))
# define Parrot_pcc_set_caller_ctx(i, c, value) Parrot_pcc_set_caller_ctx_func((i), (c), (value))
# define Parrot_pcc_set_namespace(i, c, value) Parrot_pcc_set_namespace_func((i), (c), (value))
# define Parrot_pcc_set_object(i, c, value) Parrot_pcc_set_object_func((i), (c), (value))
# define Parrot_pcc_set_lex_pad(i, c, value) Parrot_pcc_set_lex_pad_func((i), (c), (value))
# define Parrot_pcc_set_handlers(i, c, value) Parrot_pcc_set_handlers_func((i), (c), (value))
# define Parrot_pcc_set_outer_ctx(i, c, value) Parrot_pcc_set_outer_ctx_func((i), (c), (value))
# define Parrot_pcc_set_signature(i, c, value) Parrot_pcc_set_signature_func((i), (c), (value))
# define Parrot_pcc_set_context(i, c) Parrot_pcc_set_context_func((i), (c))

#endif /* ifndef NDEBUG */

#endif /* PARROT_CONTEXT_H_GUARD */

Expand Down
2 changes: 0 additions & 2 deletions src/call/context_accessors.c
Expand Up @@ -103,7 +103,6 @@ Parrot_pcc_set_constants_func(PARROT_INTERP, ARGIN(PMC *ctx),
ASSERT_ARGS(Parrot_pcc_set_constants_func)
Parrot_Context * const c = CONTEXT_STRUCT(ctx);
PARROT_ASSERT(ctx->vtable->base_type == enum_class_CallContext);
PARROT_GC_WRITE_BARRIER(interp, ctx);
c->num_constants = ct->num.constants;
c->str_constants = ct->str.constants;
c->pmc_constants = ct->pmc.constants;
Expand Down Expand Up @@ -523,7 +522,6 @@ Parrot_pcc_set_pc_func(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN_NULLOK(opcode_t *pc
ASSERT_ARGS(Parrot_pcc_set_pc_func)
Parrot_Context * const c = CONTEXT_STRUCT(ctx);
PARROT_ASSERT(ctx->vtable->base_type == enum_class_CallContext);
PARROT_GC_WRITE_BARRIER(interp, ctx);
c->current_pc = pc;
}

Expand Down
21 changes: 21 additions & 0 deletions src/gc/fixed_allocator.c
Expand Up @@ -269,6 +269,12 @@ check that pointer is probably owned by pool.
Calculate size of memory allocated by pool.
=item C<void* Parrot_gc_pool_low_ptr(PARROT_INTERP, Pool_Allocator *pool)>
=item C<void* Parrot_gc_pool_high_ptr(PARROT_INTERP, Pool_Allocator *pool)>
Get low/high boundaries of allocated memory.
=back
=cut
Expand Down Expand Up @@ -367,6 +373,21 @@ Parrot_gc_pool_allocated_size(SHIM_INTERP, ARGIN(Pool_Allocator *pool))
return count * arena_size(pool);
}

PARROT_CAN_RETURN_NULL
void*
Parrot_gc_pool_low_ptr(SHIM_INTERP, ARGIN(Pool_Allocator *pool))
{
ASSERT_ARGS(Parrot_gc_pool_low_ptr)
return pool->lo_arena_ptr;
}

PARROT_CAN_RETURN_NULL
void*
Parrot_gc_pool_high_ptr(SHIM_INTERP, ARGIN(Pool_Allocator *pool))
{
ASSERT_ARGS(Parrot_gc_pool_high_ptr)
return pool->hi_arena_ptr;
}

/*
Expand Down
12 changes: 12 additions & 0 deletions src/gc/fixed_allocator.h
Expand Up @@ -134,6 +134,14 @@ int Parrot_gc_pool_is_owned(SHIM_INTERP,
FUNC_MODIFIES(*pool)
FUNC_MODIFIES(*ptr);

PARROT_CAN_RETURN_NULL
void* Parrot_gc_pool_high_ptr(SHIM_INTERP, ARGIN(Pool_Allocator *pool))
__attribute__nonnull__(2);

PARROT_CAN_RETURN_NULL
void* Parrot_gc_pool_low_ptr(SHIM_INTERP, ARGIN(Pool_Allocator *pool))
__attribute__nonnull__(2);

PARROT_CANNOT_RETURN_NULL
PARROT_MALLOC
Pool_Allocator * Parrot_gc_pool_new(SHIM_INTERP, size_t object_size);
Expand Down Expand Up @@ -173,6 +181,10 @@ Pool_Allocator * Parrot_gc_pool_new(SHIM_INTERP, size_t object_size);
#define ASSERT_ARGS_Parrot_gc_pool_is_owned __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool) \
, PARROT_ASSERT_ARG(ptr))
#define ASSERT_ARGS_Parrot_gc_pool_high_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_Parrot_gc_pool_low_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pool))
#define ASSERT_ARGS_Parrot_gc_pool_new __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
/* HEADERIZER END: src/gc/fixed_allocator.c */
Expand Down
80 changes: 80 additions & 0 deletions src/gc/gc_gms.c
Expand Up @@ -305,6 +305,22 @@ static void gc_gms_free_string_header(PARROT_INTERP, ARGFREE(STRING *s))
static size_t gc_gms_get_gc_info(PARROT_INTERP, Interpinfo_enum which)
__attribute__nonnull__(1);

PARROT_CAN_RETURN_NULL
static void * gc_gms_get_high_pmc_ptr(PARROT_INTERP)
__attribute__nonnull__(1);

PARROT_CAN_RETURN_NULL
static void * gc_gms_get_high_str_ptr(PARROT_INTERP)
__attribute__nonnull__(1);

PARROT_CAN_RETURN_NULL
static void * gc_gms_get_low_pmc_ptr(PARROT_INTERP)
__attribute__nonnull__(1);

PARROT_CAN_RETURN_NULL
static void * gc_gms_get_low_str_ptr(PARROT_INTERP)
__attribute__nonnull__(1);

static unsigned int gc_gms_is_blocked_GC_mark(PARROT_INTERP)
__attribute__nonnull__(1);

Expand Down Expand Up @@ -504,6 +520,14 @@ static int pobj2gen(ARGIN(PObj *pmc))
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_get_gc_info __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_get_high_pmc_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_get_high_str_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_get_low_pmc_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_get_low_str_ptr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_is_blocked_GC_mark __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_gc_gms_is_blocked_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
Expand Down Expand Up @@ -688,6 +712,11 @@ Parrot_gc_gms_init(PARROT_INTERP, ARGIN(Parrot_GC_Init_Args *args))
= gc_gms_reallocate_memory_chunk_zeroed;
interp->gc_sys->free_memory_chunk = gc_gms_free_memory_chunk;

interp->gc_sys->get_low_str_ptr = gc_gms_get_low_str_ptr;
interp->gc_sys->get_high_str_ptr = gc_gms_get_high_str_ptr;
interp->gc_sys->get_low_pmc_ptr = gc_gms_get_low_pmc_ptr;
interp->gc_sys->get_high_pmc_ptr = gc_gms_get_high_pmc_ptr;

interp->gc_sys->iterate_live_strings = gc_gms_iterate_live_strings;
interp->gc_sys->write_barrier = gc_gms_write_barrier;

Expand Down Expand Up @@ -1951,6 +1980,57 @@ gc_gms_write_barrier(PARROT_INTERP, ARGIN(PMC *pmc))
gc_gms_unseal_object(interp, pmc);
}

/*
=item C<static void * gc_gms_get_low_str_ptr(PARROT_INTERP)>
=item C<static void * gc_gms_get_high_str_ptr(PARROT_INTERP)>
=item C<static void * gc_gms_get_low_pmc_ptr(PARROT_INTERP)>
=item C<static void * gc_gms_get_high_pmc_ptr(PARROT_INTERP)>
Get memory boudaries.
*/

PARROT_CAN_RETURN_NULL
static void *
gc_gms_get_low_str_ptr(PARROT_INTERP)
{
ASSERT_ARGS(gc_gms_get_low_str_ptr)
MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
return Parrot_gc_pool_low_ptr(interp, self->string_allocator);
}

PARROT_CAN_RETURN_NULL
static void *
gc_gms_get_high_str_ptr(PARROT_INTERP)
{
ASSERT_ARGS(gc_gms_get_high_str_ptr)
MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
return Parrot_gc_pool_high_ptr(interp, self->string_allocator);
}

PARROT_CAN_RETURN_NULL
static void *
gc_gms_get_low_pmc_ptr(PARROT_INTERP)
{
ASSERT_ARGS(gc_gms_get_low_pmc_ptr)
MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
return Parrot_gc_pool_low_ptr(interp, self->pmc_allocator);
}

PARROT_CAN_RETURN_NULL
static void *
gc_gms_get_high_pmc_ptr(PARROT_INTERP)
{
ASSERT_ARGS(gc_gms_get_high_pmc_ptr)
MarkSweep_GC *self = (MarkSweep_GC *)interp->gc_sys->gc_private;
return Parrot_gc_pool_high_ptr(interp, self->pmc_allocator);
}


/*
=item C<static size_t gc_gms_count_used_string_memory(PARROT_INTERP,
Expand Down
6 changes: 6 additions & 0 deletions src/gc/gc_private.h
Expand Up @@ -186,6 +186,12 @@ typedef struct GC_Subsystem {
/* Return by value to simplify memory management */
size_t (*get_gc_info)(PARROT_INTERP, Interpinfo_enum);

/* Get boundaries of allocated memory. Used during scanning of C stack */
void* (*get_low_str_ptr)(PARROT_INTERP);
void* (*get_high_str_ptr)(PARROT_INTERP);
void* (*get_low_pmc_ptr)(PARROT_INTERP);
void* (*get_high_pmc_ptr)(PARROT_INTERP);

/* Iterate over _live_ strings. Used for string pool compacting */
void (*iterate_live_strings)(PARROT_INTERP, string_iterator_callback callback, void *data);

Expand Down

0 comments on commit 1164769

Please sign in to comment.