[svn:parrot] r48076 - in branches/gsoc_instrument: runtime/parrot/library/Instrument src/dynpmc tools/build
khairul at svn.parrot.org
khairul at svn.parrot.org
Tue Jul 13 03:32:12 UTC 2010
Author: khairul
Date: Tue Jul 13 03:32:11 2010
New Revision: 48076
URL: https://trac.parrot.org/parrot/changeset/48076
Log:
Added documentation.
Modified:
branches/gsoc_instrument/runtime/parrot/library/Instrument/Base.nqp
branches/gsoc_instrument/runtime/parrot/library/Instrument/EventDispatcher.nqp
branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
branches/gsoc_instrument/src/dynpmc/instrumentgc.pmc
branches/gsoc_instrument/src/dynpmc/instrumentstubbase.pmc
branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc
branches/gsoc_instrument/tools/build/gen_vtable_stubs.pl
Modified: branches/gsoc_instrument/runtime/parrot/library/Instrument/Base.nqp
==============================================================================
--- branches/gsoc_instrument/runtime/parrot/library/Instrument/Base.nqp Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/Base.nqp Tue Jul 13 03:32:11 2010 (r48076)
@@ -5,11 +5,11 @@
=begin
=head1 NAME
-
+
runtime/parrot/library/Instrument/Base.nqp - Abstract class for the Instruments library
=head1 SYNOPSIS
-
+
Abstract class for the Instruments library.
=cut
@@ -43,16 +43,18 @@
$P1 = getattribute $P0, 'parrotclass'
%r = new $P1
};
-
+
if !pir::defined__IP($id_count) {
$id_count := 0;
}
-
+
my $id := $id_count++;
$!identifier := "Instrument-" ~ $id;
-
+
+ $!is_enabled := 0;
+
self._self_init();
-
+
return self;
};
@@ -76,7 +78,7 @@
=item callback(sub) or callback('sub') or callback()
Set the sub callback to be called when the desired op is
-encountered. sub can be passed by name or reference through a
+encountered. sub can be passed by name or reference through a
Sub PMC object. Returns the current registered callback.
=cut
@@ -120,7 +122,7 @@
=cut
-=end
+=end
method data ($data?) {
if pir::defined__IP($data) {
Modified: branches/gsoc_instrument/runtime/parrot/library/Instrument/EventDispatcher.nqp
==============================================================================
--- branches/gsoc_instrument/runtime/parrot/library/Instrument/EventDispatcher.nqp Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/EventDispatcher.nqp Tue Jul 13 03:32:11 2010 (r48076)
@@ -162,8 +162,6 @@
to dispatch the events to all the appropriate handler(s) registered
with it.
-TODO: Update gc and vtable generator scripts before updating this.
-
=cut
=end
Modified: branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp
==============================================================================
--- branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/runtime/parrot/library/Instrument/EventLibrary.nqp Tue Jul 13 03:32:11 2010 (r48076)
@@ -161,6 +161,8 @@
};
method enable() {
+ if $!is_enabled { return; }
+
# Grab the InstrumentGC and EventDispatcher object.
my $gc := Q:PIR {
$P0 = getattribute self, '$!instr_obj'
@@ -191,27 +193,64 @@
$dispatcher.register($event, $!callback);
}
}
+
+ $!is_enabled := 1;
};
method disable() {
- }
+ if !$!is_enabled { return; }
+
+ # Grab the InstrumentGC and EventDispatcher object.
+ my $gc := Q:PIR {
+ $P0 = getattribute self, '$!instr_obj'
+ %r = $P0['gc']
+ };
+ my $dispatcher := Q:PIR {
+ $P0 = getattribute self, '$!instr_obj'
+ %r = $P0['eventdispatcher']
+ };
+
+ # 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 @hooks {
+ $gc.remove_hook($_);
+
+ my $tokens := pir::split__PSS('_', $_);
+ my $group := $tokens[0];
+ if $group ne 'allocate' && $group ne 'reallocate' && $group ne 'free' {
+ $group := 'administration';
+ }
+
+ my $event := 'GC::' ~ $group ~ '::' ~ $_;
+
+ # Register the callback.
+ $dispatcher.deregister($event, $!callback);
+ }
+ }
+
+ $!is_enabled := 0;
+ };
};
# Incomplete.
class Instrument::Event::Class is Instrument::Event {
- has $!class_name;
+ has @!class_names;
has @!vtable_probes;
has @!method_probes;
our @todo;
our $loadlib_event;
method _self_init() {
+ @!class_names := ();
@!vtable_probes := ();
@!method_probes := ();
};
method inspect_class($class) {
- $!class_name := $class;
+ @!class_names.push($class);
};
method inspect_vtable($item) {
@@ -227,23 +266,40 @@
};
method enable() {
+ if $!is_enabled { return; }
+
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 ~ '::';
+ for (@!class_names) {
+ my $class_name := $_;
+ my $class := $!instr_obj.instrument_class($class_name);
+ my $event_prefix := 'Class::' ~ $class_name ~ '::';
+
+ # Register the vtable probes.
+ my $vtable_prefix := $event_prefix ~ 'vtable::';
+ for @!vtable_probes {
+ my @hooks := $class.get_hook_list($_);
+
+ for @hooks {
+ $class.insert_hook($_);
+ my $group := ($class.get_hook_group($_)).shift();
- # Register the vtable probes.
- my $vtable_prefix := $event_prefix ~ 'vtable::';
- for @!vtable_probes {
- $class.insert_hook($_);
- my $group := ($class.get_hook_group($_)).shift();
+ my $event := $vtable_prefix ~ $group ~ '::' ~ $_;
+ $dispatcher.register($event, $!callback);
+ }
+ }
- my $event := $vtable_prefix ~ $group ~ '::' ~ $_;
- $dispatcher.register($event, $!callback);
+ CATCH {
+ # Something was not found.
+ # Push to todo list.
+ say("OH NOES! Class not found.");
+ }
}
+
+ $!is_enabled := 1;
};
method disable() {
Modified: branches/gsoc_instrument/src/dynpmc/instrumentgc.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentgc.pmc Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/src/dynpmc/instrumentgc.pmc Tue Jul 13 03:32:11 2010 (r48076)
@@ -158,7 +158,7 @@
*/
/*
- * raise_gc_event: Creates a Task of subtype Instrument::Event::GC::<*>
+ * raise_gc_event: Creates a Task of subtype Instrument
* and sets its data to the given data, adding file,
* sub, namespace and line information to the data hash.
*/
@@ -232,7 +232,7 @@
void setup_gc_common_hashes(PARROT_INTERP) {
PMC *temp;
- if(!gc_first_run) return;
+ if (!gc_first_run) return;
gc_first_run = 0;
gc_registry = parrot_new_pointer_hash(interp);
@@ -600,7 +600,7 @@
}
void destroy_gc_common_hashes(PARROT_INTERP) {
- if(parrot_hash_size(interp, gc_registry) == 0) {
+ if (parrot_hash_size(interp, gc_registry) == 0) {
parrot_hash_destroy(interp, gc_registry);
parrot_hash_destroy(interp, gc_name_stubs);
parrot_hash_destroy(interp, gc_group_items);
Modified: branches/gsoc_instrument/src/dynpmc/instrumentstubbase.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentstubbase.pmc Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/src/dynpmc/instrumentstubbase.pmc Tue Jul 13 03:32:11 2010 (r48076)
@@ -1,15 +1,15 @@
/*
Copyright (C) 2010, Parrot Foundation.
-$Id: instrumentgc.pmc 48073 2010-07-11 16:47:36Z khairul $
+$Id$
=head1 NAME
-src/dynpmc/instrumentgc.pmc - Interface to instrument the gc_sys entry of Parrot_Interp.
+src/dynpmc/instrumentstubbase.pmc - Provides common methods for InstrumentVtable and InstrumentGC.
=head1 DESCRIPTION
-C<InstrumentPMC> is a PMC class that provides an interface to
-instrument the gc_sys entry of Parrot_Interp.
+Since both InstrumentVtable and InstrumentGC work in a similar fashion,
+InstrumentStubBase serves as the base class for both of them.
=head2 Methods
@@ -33,6 +33,16 @@
ATTR void *original_struct; /* Reference to the original struct. */
ATTR void *instrumented_struct; /* Reference to the struct with stubs inserted. */
+/*
+
+=item C<void init()>
+
+Throws an exception since this class should be instantiated using init_pmc instead.
+
+=cut
+
+*/
+
VTABLE void init() {
/* Not supposed to be init on its own. */
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
@@ -40,6 +50,16 @@
VTABLE_name(INTERP, SELF));
}
+/*
+
+=item C<void init_pmc(PMC *instrument)>
+
+Initialises the common attributes.
+
+=cut
+
+*/
+
VTABLE void init_pmc(PMC *instrument) {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
@@ -58,12 +78,32 @@
PObj_custom_mark_destroy_SETALL(SELF);
}
+/*
+
+=item C<void mark()>
+
+Marks internal data structures as live to the gc.
+
+=cut
+
+*/
+
VTABLE void mark() {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
Parrot_gc_mark_PMC_alive_fun(INTERP, attr->hook_count);
}
+/*
+
+=item C<void destroy()>
+
+Perform common cleanup duties.
+
+=cut
+
+*/
+
VTABLE void destroy() {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
@@ -81,6 +121,17 @@
mem_gc_free(INTERP, attr->original_struct);
}
+/*
+
+=item C<void insert_hook(STRING *name)>
+
+Inserts the stub function for the entry given by name.
+If name denotes a group, inserts stubs for all functions in that group.
+
+=cut
+
+*/
+
METHOD insert_hook(STRING *name) {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
PMC *list;
@@ -102,7 +153,7 @@
func = (size_t *) parrot_hash_get(INTERP, attr->name_stubs, item);
if (entry == NULL || func == NULL) {
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
- "%Ss : Unknown function, '%Ss'",
+ "%Ss : c Unknown function, '%Ss'",
VTABLE_name(INTERP, SELF), item);
}
*entry = func;
@@ -114,6 +165,17 @@
}
}
+/*
+
+=item C<void remove_hook(STRING *name)>
+
+Removes the stub function for the given entry given by name.
+If name denotes a group, removes stubs for all functions in that group.
+
+=cut
+
+*/
+
METHOD remove_hook(STRING *name) {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
PMC *list;
@@ -153,6 +215,18 @@
}
}
+/*
+
+=item C<PMC* get_hook_list(STRING *name)>
+
+Returns a ResizableStringArray PMC filled with
+the names of the entries to attached to name.
+If name denotes a group, returns all the entries within that group.
+
+=cut
+
+*/
+
METHOD get_hook_list(STRING *name) {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
PMC *list;
@@ -166,7 +240,7 @@
check = (size_t *) parrot_hash_get(INTERP, attr->name_stubs, name);
if (check == NULL) {
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
- "%Ss : Unknown function, '%Ss'",
+ "%Ss : a Unknown function, '%Ss'",
VTABLE_name(INTERP, SELF), name);
}
@@ -177,6 +251,17 @@
RETURN(PMC *list);
}
+/*
+
+=item C<PMC* get_hook_group(STRING *name)>
+
+Returns a ResizableStringArray PMC filled with
+the names of the groups that the entry given by name belongs to.
+
+=cut
+
+*/
+
METHOD get_hook_group(STRING *name) {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
PMC *groups;
@@ -185,13 +270,24 @@
if(PMC_IS_NULL(groups)) {
/* Should not happen. All items should have a group mapping. */
Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
- "%Ss : Unknown function, '%Ss'",
+ "%Ss : b Unknown function, '%Ss'",
VTABLE_name(INTERP, SELF), name);
}
RETURN(PMC *groups);
}
+/*
+
+=item C<PMC* get_instrumented_list()>
+
+Returns a ResizableStringArray PMC filled with
+the names of the entries that has been instrumented.
+
+=cut
+
+*/
+
METHOD get_instrumented_list() {
Parrot_InstrumentStubBase_attributes * const attr = PARROT_INSTRUMENTSTUBBASE(SELF);
PMC *ret = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
Modified: branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc
==============================================================================
--- branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/src/dynpmc/instrumentvtable.pmc Tue Jul 13 03:32:11 2010 (r48076)
@@ -42,6 +42,17 @@
ATTR size_t class_index;
ATTR Parrot_Interp supervisor;
+/*
+
+=item C<void init_pmc(PMC *instrument)>
+
+Perform a partial initialization. The remaining attributes are initialised
+upon calling 'attach_to_class'.
+
+=cut
+
+*/
+
VTABLE void init_pmc(PMC *instrument) {
Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
SUPER(instrument);
@@ -59,13 +70,36 @@
attr->item_groups = vtable_item_groups;
}
+/*
+
+=item C<void destroy()>
+
+Cleanup internal data structures.
+
+=cut
+
+*/
+
VTABLE void destroy() {
Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
SUPER();
- parrot_hash_delete(INTERP, vtable_registry, attr->instrumented_struct);
+ if (attr->instrumented_struct != NULL) {
+ parrot_hash_delete(INTERP, vtable_registry, attr->instrumented_struct);
+ }
destroy_vtable_common_hashes(INTERP);
}
+/*
+
+=item C<void attach_to_class(STRING *classname)>
+
+Prepare the given class' vtable for instrumentation.
+If class is not found, throw an exception.
+
+=cut
+
+*/
+
METHOD attach_to_class(STRING *classname) {
Parrot_InstrumentVtable_attributes * const attr = PARROT_INSTRUMENTVTABLE(SELF);
Parrot_Interp supervised;
@@ -76,6 +110,13 @@
attr->class_index = Parrot_pmc_get_type_str(supervised, classname);
attr->original_struct = supervised->vtables[attr->class_index];
+ /* class_index must not be 0. (0 = default). */
+ if (attr->class_index == 0) {
+ Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
+ "%Ss : Class not found, '%Ss'",
+ VTABLE_name(INTERP, SELF), classname);
+ }
+
/* Prepare the class's vtable for instrumentation. */
attr->instrumented_struct = mem_gc_allocate_zeroed_typed(supervised, _vtable);
mem_copy_n_typed(attr->instrumented_struct, attr->original_struct, 1, _vtable);
@@ -107,7 +148,7 @@
/* Set the event type. */
event_arr = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
VTABLE_push_string(interp, event_arr, CONST_STRING(interp, "Class"));
- VTABLE_push_string(interp, event_arr, VTABLE_name(supervised, pmc));
+ VTABLE_push_string(interp, event_arr, pmc->vtable->whoami);
VTABLE_push_string(interp, event_arr, CONST_STRING(interp, "vtable"));
VTABLE_push_string(interp, event_arr, group);
VTABLE_push_string(interp, event_arr, type);
@@ -293,7 +334,7 @@
void setup_vtable_common_hashes(PARROT_INTERP) {
PMC *temp;
- if(!vtable_first_run) return;
+ if (!vtable_first_run) return;
vtable_first_run = 0;
vtable_registry = parrot_new_pointer_hash(interp);
@@ -2303,7 +2344,7 @@
}
void destroy_vtable_common_hashes(PARROT_INTERP) {
- if(parrot_hash_size(interp, vtable_registry) == 0) {
+ if (parrot_hash_size(interp, vtable_registry) == 0) {
parrot_hash_destroy(interp, vtable_registry);
parrot_hash_destroy(interp, vtable_name_stubs);
parrot_hash_destroy(interp, vtable_group_items);
Modified: branches/gsoc_instrument/tools/build/gen_vtable_stubs.pl
==============================================================================
--- branches/gsoc_instrument/tools/build/gen_vtable_stubs.pl Mon Jul 12 15:32:45 2010 (r48075)
+++ branches/gsoc_instrument/tools/build/gen_vtable_stubs.pl Tue Jul 13 03:32:11 2010 (r48076)
@@ -316,6 +316,7 @@
ENTRY
}
+ $key = lc $key;
$entry .= <<POST;
parrot_hash_put(interp, vtable_group_items,
CONST_STRING(interp, "$key"),
@@ -342,6 +343,7 @@
PRE
foreach $item (@{$data->[4]}) {
+ $item = lc $item;
$entry .= <<ENTRY;
VTABLE_push_string(interp, temp,
CONST_STRING(interp, "$item"));
More information about the parrot-commits
mailing list