Oh yeah, the goal of this exercise was to cache the hash, not build it
every time. Here's a version which does that and passes the tests with
GC_DEBUG. It still complains about passing constant C-strings to
hash_put(), but that's a different story.
-- c
Index: include/parrot/interpreter.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v
retrieving revision 1.149
diff -u -u -r1.149 interpreter.h
--- include/parrot/interpreter.h 26 Jul 2004 07:34:33 -0000 1.149
+++ include/parrot/interpreter.h 13 Aug 2004 22:13:36 -0000
@@ -267,6 +267,7 @@
IGLOBALS_INTERPRETER,
IGLOBALS_DYN_LIBS,
IGLOBALS_RUNTIME_LIBRARY,
+ IGLOBALS_NCI_FUNCS,
IGLOBALS_SIZE
} iglobals_enum;
Index: build_tools/build_nativecall.pl
===================================================================
RCS file: /cvs/public/parrot/build_tools/build_nativecall.pl,v
retrieving revision 1.49
diff -u -u -r1.49 build_nativecall.pl
--- build_tools/build_nativecall.pl 9 Aug 2004 21:20:12 -0000 1.49
+++ build_tools/build_nativecall.pl 14 Aug 2004 01:59:44 -0000
@@ -175,6 +175,7 @@
* References:
*/
#include "parrot/parrot.h"
+#include "parrot/hash.h"
/*
* if the architecture can build some or all of these signatures
@@ -245,10 +246,15 @@
build_call_func(Interp *interpreter, PMC *pmc_nci,
STRING *signature)
{
- STRING *ns;
- STRING *message;
- char *c;
- void *result = NULL;
+ char *c;
+ STRING *ns, *message;
+ HashBucket *b;
+ PMC *iglobals;
+
+ void *result = NULL;
+ Hash *known_frames = NULL;
+ PMC *HashPointer = NULL;
+
#if defined(CAN_BUILD_CALL_FRAMES)
/* Try if JIT code can build that signature,
@@ -260,12 +266,41 @@
#endif
if (result)
return result;
+
/* And in here is the platform-independent way. Which is to say
"here there be hacks" */
UNUSED(pmc_nci);
if (0 == string_length(interpreter, signature)) return F2DPTR(pcf_v_v);
- $icky_global_bit
+ iglobals = interpreter->iglobals;
+
+ if (iglobals)
+ HashPointer = VTABLE_get_pmc_keyed_int(interpreter, iglobals,
+ IGLOBALS_NCI_FUNCS);
+
+ if (HashPointer)
+ known_frames = PMC_struct_val(HashPointer);
+
+ if (known_frames == NULL)
+ {
+ new_cstring_hash( interpreter, &known_frames );
+
+$icky_global_bit
+
+ if (iglobals)
+ {
+ HashPointer = pmc_new(interpreter, enum_class_Pointer);
+ VTABLE_set_pmc_keyed_int(interpreter, iglobals, IGLOBALS_NCI_FUNCS,
+ HashPointer);
+ PMC_struct_val(HashPointer) = known_frames;
+ }
+ }
+
+ b = hash_get_bucket(interpreter, known_frames,
+ string_to_cstring(interpreter, signature));
+
+ if (b)
+ return F2DPTR( b->value );
/*
These three lines have been added to aid debugging. I want to be able to
@@ -437,21 +472,12 @@
HEADER
}
- if (defined $params) {
- push @icky_global_variable, <<CALL;
- if (!string_compare(interpreter, signature,
- string_from_cstring(interpreter, "$return$params", 0)))
- return F2DPTR(pcf_${return}_$params);
-CALL
- }
- else {
- push @icky_global_variable, <<CALL;
- if (!string_compare(interpreter, signature,
- string_from_cstring(interpreter, "$return", 0)))
- return F2DPTR(pcf_${return});
-CALL
- }
+ my ($key, $value) = (defined $params ?
+ ( "$return$params", "pcf_${return}_$params" ) :
+ ( "$return", "pcf_${return}" ));
+ push @icky_global_variable,
+ qq| hash_put( interpreter, known_frames, "$key", $value );|;
}