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 );|; }