[svn:parrot] r44281 - trunk/src/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sun Feb 21 20:24:02 UTC 2010


Author: whiteknight
Date: Sun Feb 21 20:24:02 2010
New Revision: 44281
URL: https://trac.parrot.org/parrot/changeset/44281

Log:
add caching to OpLib PMC. One Opcode PMC for each opcode. Since these are read-only, no reason to have more than one for the same op

Modified:
   trunk/src/pmc/oplib.pmc

Modified: trunk/src/pmc/oplib.pmc
==============================================================================
--- trunk/src/pmc/oplib.pmc	Sun Feb 21 19:41:37 2010	(r44280)
+++ trunk/src/pmc/oplib.pmc	Sun Feb 21 20:24:02 2010	(r44281)
@@ -18,12 +18,14 @@
 
 /* TODO: Since Opcode PMCs are essentially read-only after initialization
          here, we should cache them. A FixedPMCArray would be okay, an
-         INTVAL->PMC HASH might be better, since it's unlike that we will
+         INTVAL->PMC HASH might be better, since it's unlikely that we will
          need to cache even a majority of the ~1300 ops. */
 static PMC *OPLIB_PMC_INSTANCE;
+static PMC *OPLIB_OPCODE_CACHE;
 pmclass OpLib {
     void class_init() {
         OPLIB_PMC_INSTANCE = NULL;
+        OPLIB_OPCODE_CACHE = NULL;
     }
 
     VTABLE void *get_pointer() {
@@ -34,6 +36,16 @@
         OPLIB_PMC_INSTANCE = (PMC *)ptr;
     }
 
+    VTABLE void init() {
+        if (OPLIB_OPCODE_CACHE == NULL)
+            OPLIB_OPCODE_CACHE = Parrot_pmc_new(INTERP, enum_class_Hash);
+    }
+
+    VTABLE void mark() {
+        if (OPLIB_OPCODE_CACHE != NULL)
+            Parrot_gc_mark_PMC_alive(INTERP, OPLIB_OPCODE_CACHE);
+    }
+
     /* Look up an opnumber given the name of the op. First we look for the
        specific name, then the more general short name. */
     VTABLE INTVAL get_integer_keyed_str(STRING *name) {
@@ -51,10 +63,16 @@
     }
 
     VTABLE PMC* get_pmc_keyed_str(STRING *name) {
-        PMC * const op = Parrot_pmc_new_noinit(INTERP, enum_class_Opcode);
-        VTABLE_set_string_native(INTERP, op, name);
-        PObj_custom_mark_SET(op);
-        return op;
+        if (VTABLE_defined_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name)) {
+            PMC * const op = VTABLE_get_pmc_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name);
+            return op;
+        } else {
+            PMC * const op = Parrot_pmc_new_noinit(INTERP, enum_class_Opcode);
+            VTABLE_set_string_native(INTERP, op, name);
+            PObj_custom_mark_SET(op);
+            VTABLE_set_pmc_keyed_str(INTERP, OPLIB_OPCODE_CACHE, name, op);
+            return op;
+        }
     }
 
     VTABLE PMC* get_pmc_keyed(PMC *key) {
@@ -63,10 +81,15 @@
     }
 
     VTABLE PMC* get_pmc_keyed_int(INTVAL value) {
-        PMC * const op = Parrot_pmc_new_noinit(INTERP, enum_class_Opcode);
-        VTABLE_set_integer_native(INTERP, op, value);
-        PObj_custom_mark_SET(op);
-        return op;
+        if (value > interp->op_lib->op_count)
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
+                "OpLib: Opcode index %d out of bounds", value);
+        else {
+            const char * const name = interp->op_info_table[value].full_name;
+            const INTVAL len = strlen(name);
+            STRING * const newstr = Parrot_str_new(INTERP, name, len);
+            return VTABLE_get_pmc_keyed_str(INTERP, SELF, newstr);
+        }
     }
 
     VTABLE INTVAL get_integer() {


More information about the parrot-commits mailing list