[svn:parrot] r48393 - in trunk: compilers/opsc/src/Ops/Trans src/ops

chromatic at svn.parrot.org chromatic at svn.parrot.org
Tue Aug 10 23:50:17 UTC 2010


Author: chromatic
Date: Tue Aug 10 23:50:15 2010
New Revision: 48393
URL: https://trac.parrot.org/parrot/changeset/48393

Log:
[opsc] Coalesced expensive allocation for op info.

By allocating lots of little buckets in one big chunk, we can avoid repeated
calls to calloc().  This improves Parrot startup by 4.3%.

Modified:
   trunk/compilers/opsc/src/Ops/Trans/C.pm
   trunk/src/ops/core_ops.c

Modified: trunk/compilers/opsc/src/Ops/Trans/C.pm
==============================================================================
--- trunk/compilers/opsc/src/Ops/Trans/C.pm	Tue Aug 10 23:50:07 2010	(r48392)
+++ trunk/compilers/opsc/src/Ops/Trans/C.pm	Tue Aug 10 23:50:15 2010	(r48393)
@@ -282,7 +282,7 @@
 
 static void hop_init(PARROT_INTERP);
 static size_t hash_str(const char *str);
-static void store_op(PARROT_INTERP, op_info_t *info, int full);
+static void store_op(PARROT_INTERP, op_info_t *info, HOP *p, int full);
 
 /* XXX on changing interpreters, this should be called,
    through a hook */
@@ -314,9 +314,8 @@
     return key;
 }
 
-static void store_op(PARROT_INTERP, op_info_t *info, int full)
+static void store_op(PARROT_INTERP, op_info_t *info, HOP *p, int full)
 {
-    HOP * const p     = mem_gc_allocate_zeroed_typed(interp, HOP);
     const size_t hidx =
         hash_str(full ? info->full_name : info->name) % OP_HASH_SIZE;
 
@@ -342,29 +341,30 @@
 
 static void hop_init(PARROT_INTERP)
 {
-    size_t i;
     op_info_t * const info = [[BS]]op_lib.op_info_table;
+
+    /* allocate the storage all in one chunk
+     * yes, this is profligate, but we can tighten it later */
+    HOP *hops =
+        mem_gc_allocate_n_zeroed_typed(interp, [[BS]]op_lib.op_count * 2, HOP );
+
+    size_t i;
+
     /* store full names */
     for (i = 0; i < [[BS]]op_lib.op_count; i++)
-        store_op(interp, info + i, 1);
+        store_op(interp, info + i, hops++, 1);
+
     /* plus one short name */
     for (i = 0; i < [[BS]]op_lib.op_count; i++)
         if (get_op(interp, info[i].name, 0) == -1)
-            store_op(interp, info + i, 0);
+            store_op(interp, info + i, hops++, 0);
 }
 
 static void hop_deinit(PARROT_INTERP)
 {
     if (hop) {
-        size_t i;
-        for (i = 0; i < OP_HASH_SIZE; i++) {
-            HOP *p = hop[i];
-            while (p) {
-                HOP * const next = p->next;
-                mem_gc_free(interp, p);
-                p = next;
-            }
-        }
+        HOP *p = hop[0];
+        mem_gc_free(interp, p);
         mem_sys_free(hop);
         hop = NULL;
     }

Modified: trunk/src/ops/core_ops.c
==============================================================================
--- trunk/src/ops/core_ops.c	Tue Aug 10 23:50:07 2010	(r48392)
+++ trunk/src/ops/core_ops.c	Tue Aug 10 23:50:15 2010	(r48393)
@@ -25049,7 +25049,7 @@
 
 static void hop_init(PARROT_INTERP);
 static size_t hash_str(const char *str);
-static void store_op(PARROT_INTERP, op_info_t *info, int full);
+static void store_op(PARROT_INTERP, op_info_t *info, int full, HOP *p);
 
 /* XXX on changing interpreters, this should be called,
    through a hook */
@@ -25081,9 +25081,8 @@
     return key;
 }
 
-static void store_op(PARROT_INTERP, op_info_t *info, int full)
+static void store_op(PARROT_INTERP, op_info_t *info, int full, HOP *p)
 {
-    HOP * const p     = mem_gc_allocate_zeroed_typed(interp, HOP);
     const size_t hidx =
         hash_str(full ? info->full_name : info->name) % OP_HASH_SIZE;
 
@@ -25097,7 +25096,7 @@
     const HOP * p;
     const size_t hidx = hash_str(name) % OP_HASH_SIZE;
     if (!hop) {
-        hop = mem_gc_allocate_n_zeroed_typed(interp, OP_HASH_SIZE,HOP *);
+        hop = mem_gc_allocate_n_zeroed_typed(interp, OP_HASH_SIZE, HOP *);
         hop_init(interp);
     }
     for (p = hop[hidx]; p; p = p->next) {
@@ -25111,27 +25110,24 @@
 {
     size_t i;
     op_info_t * const info = core_op_lib.op_info_table;
+    HOP *hops =
+         mem_gc_allocate_n_zeroed_typed(interp, core_op_lib.op_count * 2, HOP );
+
     /* store full names */
     for (i = 0; i < core_op_lib.op_count; i++)
-        store_op(interp, info + i, 1);
+        store_op(interp, info + i, 1, hops++);
+
     /* plus one short name */
     for (i = 0; i < core_op_lib.op_count; i++)
         if (get_op(interp, info[i].name, 0) == -1)
-            store_op(interp, info + i, 0);
+            store_op(interp, info + i, 0, hops++);
 }
 
 static void hop_deinit(PARROT_INTERP)
 {
     if (hop) {
-        size_t i;
-        for (i = 0; i < OP_HASH_SIZE; i++) {
-            HOP *p = hop[i];
-            while (p) {
-                HOP * const next = p->next;
-                mem_gc_free(interp, p);
-                p = next;
-            }
-        }
+        HOP   *p = hop[0];
+        mem_gc_free(interp, p);
         mem_sys_free(hop);
         hop = NULL;
     }


More information about the parrot-commits mailing list