Skip to content

Commit

Permalink
Fixed code issues raised by cotto.
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.parrot.org/parrot/branches/gsoc_instrument@48031 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
khairul committed Jul 7, 2010
1 parent 4d83739 commit d69dae8
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 68 deletions.
10 changes: 5 additions & 5 deletions runtime/parrot/library/Instrument/Event.nqp
Expand Up @@ -112,12 +112,12 @@ Helper sub that creates a Task instance and schedules it.
=end

sub _raise_event ($evt, $data) {
my $hash := Q:PIR { %r = new ['Hash'] };
pir::set_p_k_p($hash, 'type', 'event');
pir::set_p_k_p($hash, 'subtype', $evt);
pir::set_p_k_p($hash, 'data', $data);
my %hash := {};
%hash<type> := 'event';
%hash<subtype> := $evt;
%hash<data> := $data;

my $task := pir::new_p_s_p__PSP('Task', $hash);
my $task := pir::new__PSP('Task', %hash);

pir::schedule($task);
}
Expand Down
64 changes: 58 additions & 6 deletions runtime/parrot/library/Instrument/EventLibrary.nqp
Expand Up @@ -146,14 +146,14 @@ Usage (in PIR):
=end

class Instrument::Event::GC is Instrument::Event {
has $!probe_list;
has @!probe_list;

method _self_init() {
$!probe_list := Q:PIR { %r = new ['ResizablePMCArray'] };
@!probe_list := ();
};

method inspect($item) {
$!probe_list.push($item);
@!probe_list.push($item);
};

method _on_attach() {
Expand All @@ -173,10 +173,10 @@ class Instrument::Event::GC is Instrument::Event {
# For each item in $!probe_list, insert the gc hook
# and register the event handler.
for $!probe_list {
my $hooks := $gc.get_hook_list($_);
for @!probe_list {
my @hooks := $gc.get_hook_list($_);

for $hooks {
for @hooks {
$gc.insert_gc_hook($_);

my $tokens := pir::split__PSS('_', $_);
Expand All @@ -192,6 +192,58 @@ class Instrument::Event::GC is Instrument::Event {
}
}
};

method disable() {
}
};

# Incomplete.
class Instrument::Event::Class is Instrument::Event {
has $!class_name;
has @!vtable_probes;
has @!method_probes;

method _self_init() {
@!vtable_probes := ();
@!method_probes := ();
};

method inspect_class($class) {
$!class_name := $class;
};

method inspect_vtable($item) {
@!vtable_probes.push($item);
};

method inspect_method($item) {
@!method_probes.push($item);
};

method _on_attach() {
self.enable();
};

method enable() {
my $dispatcher := Q:PIR {
$P0 = getattribute self, '$!instr_obj'
%r = $P0['eventdispatcher']
};
my $class := $!instr_obj.instrument_class($!class_name);
my $event_prefix := 'Class::' ~ $!class_name ~ '::';

# Register the vtable probes.
for @!vtable_probes {
$class.insert_vtable_hook($_);

my $event := $event_prefix ~ $_;
$dispatcher.register($event, $!callback);
}
};

method disable() {
};
};

# vim: ft=perl6 expandtab shiftwidth=4:
51 changes: 26 additions & 25 deletions runtime/parrot/library/Instrument/Probe.nqp
Expand Up @@ -35,10 +35,10 @@ runtime/parrot/library/Instrument/Probe.nqp - Helper class to automate inserting

class Instrument::Probe is Instrument::Base {
has $!is_catchall;
has $!oplist;
has $!todo_oplist;
has @!oplist;
has @!todo_oplist;
our $loadlib_evt;
our $loadlib_probelist := Q:PIR { %r = new ['ResizablePMCArray'] };
our @loadlib_probelist := ();

=begin

Expand All @@ -51,8 +51,8 @@ Private method to perform additional initialisation.
=end

method _self_init () {
$!todo_oplist := Q:PIR { %r = new ['ResizablePMCArray'] };
$!oplist := Q:PIR { %r = new ['ResizablePMCArray'] };
@!todo_oplist := ();
@!oplist := ();
$!is_catchall := 0;
};

Expand Down Expand Up @@ -94,18 +94,18 @@ everytime a dynlib is loaded.
}
else {
# $op is singular.
my $oplib := Q:PIR { %r = new ['OpLib'] };
my $oplib := pir::new__PS('OpLib');
my $type := pir::typeof__PP($op);

if $type eq 'Integer' {
# $op = op number.
if $op > pir::set__IP($oplib) {
# op number is invalid.
# Put it in the todo list.
$!todo_oplist.push($op);
@!todo_oplist.push($op);
}
else {
$!oplist.push($op);
@!oplist.push($op);
}
}
else {
Expand All @@ -118,20 +118,20 @@ everytime a dynlib is loaded.
# $op = short name.
for $op_ret {
$op_num := pir::set__IP($_);
$!oplist.push($op_num);
@!oplist.push($op_num);
}
}
else {
# $op = long name.
$op_ret := pir::set_p_p_k__PPP($oplib, $op);
$op_num := pir::set__IP($op_ret);
$!oplist.push($op_num);
@!oplist.push($op_num);
}
}
}
CATCH {
# Push to todo_oplist
$!todo_oplist.push($op);
@!todo_oplist.push($op);
}
};

Expand All @@ -157,22 +157,23 @@ eg,
}

# Check for any todo_oplist.
if pir::set__IP($!todo_oplist) != 0 {
if pir::set__IP(@!todo_oplist) != 0 {
# Double check the todo_oplist.
my $list := $!todo_oplist;
$!todo_oplist := Q:PIR { %r = new ['ResizablePMCArray'] };
for $list {
my @list := @!todo_oplist;
@!todo_oplist := ();
for @list {
self.inspect($_);
}

# If there is still a todo_oplist,
# set up an event handler to update.
if pir::set__IP($!todo_oplist) != 0 {
$Instrument::Probe::loadlib_probelist.push(self);
if pir::set__IP(@!todo_oplist) != 0 {
@Instrument::Probe::loadlib_probelist.push(self);

if !pir::defined__IP($Instrument::Probe::loadlib_evt) {
my $callback := pir::get_global__PS('loadlib_callback');
$Instrument::Probe::loadlib_evt := Instrument::Event::Internal::loadlib.new();
$Instrument::Probe::loadlib_evt.callback(pir::get_global__PS('loadlib_callback'));
$Instrument::Probe::loadlib_evt.callback($callback);
$Instrument::Probe::loadlib_evt.data(self);
$!instr_obj.attach($Instrument::Probe::loadlib_evt);
}
Expand All @@ -185,7 +186,7 @@ eg,
$!instr_obj.insert_op_catchall(self);
} else {
# Attach a hook to each op in @!oplist.
for $!oplist {
for @!oplist {
$!instr_obj.insert_op_hook(self, $_);
}
}
Expand Down Expand Up @@ -219,7 +220,7 @@ You can dynamically attach and remove hooks dynamically.
$!instr_obj.remove_op_catchall(self);
} else {
# Attach a hook to each op in @!oplist.
for $!oplist {
for @!oplist {
$!instr_obj.remove_op_hook(self, $_);
}
}
Expand All @@ -237,7 +238,7 @@ Returns the list of op numbers inspected by this probe.
=end

method get_op_list () {
return $!oplist;
return @!oplist;
}

=begin
Expand All @@ -249,16 +250,16 @@ Returns the list of items passed to inspect
=end

method get_op_todo_list () {
return $!todo_oplist;
return @!todo_oplist;
}

# Internal helper: Callback for loadlib events registered when the probe has
# any outstanding ops in $!todo_oplist.
sub loadlib_callback ($data) {
# Simply disable and reenable the probe.
my $list := $Instrument::Probe::loadlib_probelist;
$Instrument::Probe::loadlib_probelist := Q:PIR { %r = new ['ResizablePMCArray'] };
for $list {
my @list := @Instrument::Probe::loadlib_probelist;
@Instrument::Probe::loadlib_probelist := ();
for @list {
$_.disable();
$_.enable();
}
Expand Down
14 changes: 14 additions & 0 deletions src/dynpmc/instrument.pmc
Expand Up @@ -537,6 +537,20 @@ Returns the number of enabled op catchall probes.

RETURN(INTVAL count);
}


METHOD instrument_class(STRING *classname) {
INTVAL class_type;
PMC *class_instr;

class_type = Parrot_pmc_get_type_str(INTERP, CONST_STRING(INTERP, "InstrumentVtable"));
class_instr = Parrot_pmc_new_init(INTERP, class_type, SELF);

() = PCCINVOKE(INTERP, class_instr, "attach_to_class", STRING *classname);

RETURN(PMC *class_instr);
}

}

/*
Expand Down
20 changes: 8 additions & 12 deletions src/dynpmc/instrumentgc.pmc
Expand Up @@ -162,9 +162,9 @@ Initialises and prepares the supervised interpreter for GC instrumenting.
supervised->gc_sys = (GC_Subsystem *) attr->gc_instrumented;

/* Initialise the hashes. */
attr->stub_hash = parrot_new_pointer_hash(INTERP);
attr->original_hash = parrot_new_pointer_hash(INTERP);
attr->entry_hash = parrot_new_pointer_hash(INTERP);
attr->stub_hash = parrot_new_hash(INTERP);
attr->original_hash = parrot_new_hash(INTERP);
attr->entry_hash = parrot_new_hash(INTERP);
build_gc_func_hash(INTERP, attr->stub_hash, attr->original_hash, attr->entry_hash,
attr->gc_instrumented, attr->gc_original);

Expand Down Expand Up @@ -375,22 +375,18 @@ the names of the gc entries to instrument.
VTABLE_push_string(INTERP, list, CONST_STRING(INTERP, "unblock_sweep"));
}
else {
/* Convert name to a constant string since we use the address of the
constant string as the key to the various hashes. */
/* Ensure that con_str is the name of a hook before pushing it in. */
size_t *check;
Hash *stub_hash;
char *c_str = Parrot_str_to_cstring(INTERP, name);
STRING *con_str = CONST_STRING(INTERP, c_str);
VTABLE_push_string(INTERP, list, con_str);
Parrot_free_cstring(c_str);

/* Ensure that con_str is the name of a hook. */
GETATTR_InstrumentGC_stub_hash(INTERP, SELF, stub_hash);
check = (size_t *) parrot_hash_get(INTERP, stub_hash, con_str);
check = (size_t *) parrot_hash_get(INTERP, stub_hash, name);
if (check == NULL) {
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"Unknown GC function: %Ss", con_str);
"Unknown GC function: %Ss", name);
}

VTABLE_push_string(INTERP, list, name);
}

RETURN(PMC *list);
Expand Down
28 changes: 8 additions & 20 deletions src/dynpmc/instrumentvtable.pmc
Expand Up @@ -242,13 +242,13 @@ pmclass InstrumentVtable auto_attrs dynpmc group instrument_group {
attr->instrument = instrument;
attr->original_vtable = NULL;
attr->instrumented_vtable = NULL;
attr->original_hash = parrot_new_pointer_hash(INTERP);
attr->instrumented_hash = parrot_new_pointer_hash(INTERP);
attr->original_hash = parrot_new_hash(INTERP);
attr->instrumented_hash = parrot_new_hash(INTERP);

/* Initialise the Instrumented Vtable registry if needed. */
if (Instrument_Vtable_Entries == NULL) {
Instrument_Vtable_Entries = parrot_new_pointer_hash(INTERP);
Instrument_Vtable_Stubs = parrot_new_pointer_hash(INTERP);
Instrument_Vtable_Entries = parrot_new_hash(INTERP);
Instrument_Vtable_Stubs = parrot_new_hash(INTERP);
}

PObj_custom_destroy_SET(SELF);
Expand Down Expand Up @@ -293,44 +293,32 @@ pmclass InstrumentVtable auto_attrs dynpmc group instrument_group {
attr->original_vtable, attr->instrumented_vtable);
}

METHOD insert_vtable_hook(STRING *vtable_str) {
METHOD insert_vtable_hook(STRING *key) {
Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
STRING *key;
char *con_string;
size_t **instr, *stub;

/* Convert vtable_str to a constant STRING so that it can be used as a key. */
con_string = Parrot_str_to_cstring(INTERP, vtable_str);
key = CONST_STRING(INTERP, con_string);
Parrot_free_cstring(con_string);

/* Modify the entry. */
instr = (size_t **) parrot_hash_get(INTERP, attr->instrumented_hash, key);
stub = (size_t *) parrot_hash_get(INTERP, Instrument_Vtable_Stubs, key);
if (instr == NULL || stub == NULL) {
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"Unknown VTABLE entry: %Ss", vtable_str);
"Unknown VTABLE entry: %Ss", key);
}
*instr = stub;
}

METHOD remove_vtable_hook(STRING *vtable_str) {
METHOD remove_vtable_hook(STRING *key) {
Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
STRING *key;
char *con_string;
size_t **instr, *orig;

/* Convert vtable_str to a constant STRING so that it can be used as a key. */
con_string = Parrot_str_to_cstring(INTERP, vtable_str);
key = CONST_STRING(INTERP, con_string);
Parrot_free_cstring(con_string);

/* Modify the entry. */
instr = (size_t **) parrot_hash_get(INTERP, attr->instrumented_hash, key);
orig = (size_t *) parrot_hash_get(INTERP, attr->original_hash, key);
if (instr == NULL || orig == NULL) {
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
"Unknown VTABLE entry: %Ss", vtable_str);
"Unknown VTABLE entry: %Ss", key);
}
*instr = orig;
}
Expand Down

0 comments on commit d69dae8

Please sign in to comment.