Skip to content

Commit

Permalink
Always generate write_barrier for VTABLE.
Browse files Browse the repository at this point in the history
Reason for it next:
1. Aggregate PMC in Gen0.
2. We invoke write_barrier(PMC). Which is ignored.
3. VTABLE_foo() allocate new PMC.
4. Aggregate PMC moved into Gen1.
5. Content of PMC gets updated without triggering write barrier.

To avoid it we store result of original VTABLE and invoke write_barrier
after.
  • Loading branch information
bacek committed Feb 7, 2011
1 parent 1959d92 commit be32682
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/Parrot/Pmc2c/MethodEmitter.pm
Expand Up @@ -39,8 +39,14 @@ sub generate_body {

my $body = $self->body;

if ( $self->is_vtable ) {
if ( $self->is_vtable || $self->name =~ '_orig') {
# UGLY HACK to rewrite original body of write-barriered vtable
my $orig_name = $self->name;
my $n = $self->name;
$n =~ s/_orig$//;
$self->name($n);
$self->rewrite_vtable_method($pmc);
$self->name($orig_name);
}
else {
$self->rewrite_nci_method($pmc);
Expand Down
42 changes: 42 additions & 0 deletions lib/Parrot/Pmc2c/PMCEmitter.pm
Expand Up @@ -278,6 +278,48 @@ sub pre_method_gen {
1;
}

sub post_method_gen {
my ($self) = @_;

# vtables
foreach my $method ( @{ $self->vtable->methods } ) {
my $name = $method->name;
next if $name eq 'class_init';
next unless $self->implements_vtable($name);
# Skip non-updating methods
next unless $self->{has_method}{$name}
&& $self->vtable_method_does_write($name);

$method = $self->get_method($name);

#warn "Rewriting " . $self->name . "." . $name;
$self->add_method(
$method->clone({
name => $name.'_orig',
type => "ORIG",
})
);

# Rewrite body with write barrier.
my $body;
my $need_result = $method->return_type && $method->return_type !~ 'void';

$body .= $method->return_type . " result;\nresult = " if $need_result;

# Get parameters. strip type from param
my $parameters = join ', ',
'INTERP', 'SELF', map { /\s*\*?(\S+)$/; $1 }
split (/,/, $method->parameters);
$body .= $method->full_method_name($self->name) . "_orig($parameters);\n";

$body .= "PARROT_GC_WRITE_BARRIER(interp, _self);\n";
$body .= "return result;" if $need_result;

$method->body(Parrot::Pmc2c::Emitter->text($body) );
}

}

=item C<gen_methods()>
Returns the C code for the pmc methods.
Expand Down
1 change: 1 addition & 0 deletions lib/Parrot/Pmc2c/Parser.pm
Expand Up @@ -89,6 +89,7 @@ sub parse_pmc {
$pmc->add_method($class_init) if $class_init;
$pmc->vtable( $pmc2cMain->read_dump("vtable.pmc") );
$pmc->pre_method_gen();
$pmc->post_method_gen();

return $pmc;
}
Expand Down

0 comments on commit be32682

Please sign in to comment.