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

Reply via email to