Skip to content

Instantly share code, notes, and snippets.

@timo
Created February 14, 2014 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timo/64ccbdb18bdf11b705cf to your computer and use it in GitHub Desktop.
Save timo/64ccbdb18bdf11b705cf to your computer and use it in GitHub Desktop.
commit f1d15119ad78e02b0f5050d1331de7bd11827f1a
Author: Timo Paulssen <timonator@perpetuum-immobile.de>
Date: Fri Feb 14 19:50:05 2014 +0100
implement a constant cache for ints 0 to 16
diff --git a/build/Makefile.in b/build/Makefile.in
index 0a8105b..663ae5d 100644
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -71,6 +71,7 @@ OBJECTS = src/core/args@obj@ \
src/core/dll@obj@ \
src/core/ext@obj@ \
src/core/continuation@obj@ \
+ src/core/intcache@obj@ \
src/gen/config@obj@ \
src/gc/orchestrate@obj@ \
src/gc/allocation@obj@ \
diff --git a/moar-gdb.py b/moar-gdb.py
index f24a589..9150ba3 100644
--- a/moar-gdb.py
+++ b/moar-gdb.py
@@ -493,7 +493,6 @@ class Gen2Data(CommonHeapData):
if self.empty:
print "(unallocated)"
return
- print "setting up stuff"
cols_per_block = int(math.sqrt(MVM_GEN2_PAGE_ITEMS))
lines_per_block = cols_per_block / 2
outlines = [[] for i in range(lines_per_block + 1)]
@@ -535,9 +534,10 @@ class Gen2Data(CommonHeapData):
print "(freelist with", self.length_freelist, "entries out of an allocd", self.allocd_freelist,")",
print ""
- print "sizes of objects/stables:"
- show_histogram(self.size_histogram, "key", True)
- print "REPRs:"
+ if len(self.size_histogram) > 1:
+ print "sizes of objects/stables:"
+ show_histogram(self.size_histogram, "key", True)
+ print "REPRs (sampled):"
show_histogram(self.repr_histogram)
class HeapData(object):
diff --git a/src/6model/bootstrap.c b/src/6model/bootstrap.c
index 5c8b08c..f42fb0a 100644
--- a/src/6model/bootstrap.c
+++ b/src/6model/bootstrap.c
@@ -658,4 +658,6 @@ void MVM_6model_bootstrap(MVMThreadContext *tc) {
/* Get initial __6MODEL_CORE__ serialization context set up. */
setup_core_sc(tc);
MVM_6model_containers_setup(tc);
+
+ MVM_intcache_for(tc, tc->instance->boot_types.BOOTInt);
}
diff --git a/src/6model/reprconv.c b/src/6model/reprconv.c
index c746972..9c1547d 100644
--- a/src/6model/reprconv.c
+++ b/src/6model/reprconv.c
@@ -229,8 +229,12 @@ void MVM_repr_set_str(MVMThreadContext *tc, MVMObject *obj, MVMString *val) {
}
MVMObject * MVM_repr_box_int(MVMThreadContext *tc, MVMObject *type, MVMint64 val) {
- MVMObject *res = MVM_repr_alloc_init(tc, type);
- MVM_repr_set_int(tc, res, val);
+ MVMObject *res;
+ res = MVM_intcache_get(tc, type, val);
+ if (res == 0) {
+ res = MVM_repr_alloc_init(tc, type);
+ MVM_repr_set_int(tc, res, val);
+ }
return res;
}
diff --git a/src/core/hll.c b/src/core/hll.c
index 0b02ce2..40e048e 100644
--- a/src/core/hll.c
+++ b/src/core/hll.c
@@ -100,6 +100,8 @@ MVMObject * MVM_hll_set_config(MVMThreadContext *tc, MVMString *name, MVMObject
check_config_key(tc, config_hash, "method_not_found_error", method_not_found_error, config);
});
+ MVM_intcache_for(tc, config->int_box_type);
+
return config_hash;
}
diff --git a/src/core/instance.h b/src/core/instance.h
index 3a9eefc..1421088 100644
--- a/src/core/instance.h
+++ b/src/core/instance.h
@@ -157,6 +157,10 @@ struct MVMInstance {
MVMint64 hll_compilee_depth;
uv_mutex_t mutex_hllconfigs;
+ /* By far the most common integers are between 0 and 8, but we cache up to 16
+ * so that it lines up properly. */
+ MVMIntConstCache *int_const_cache;
+
/* Atomically-incremented counter of newly invoked frames,
* so each can obtain an index into each threadcontext's pool table */
AO_t num_frame_pools;
diff --git a/src/core/intcache.c b/src/core/intcache.c
new file mode 100644
index 0000000..f82ee29
--- /dev/null
+++ b/src/core/intcache.c
@@ -0,0 +1,54 @@
+#include "moar.h"
+
+/* XXX adding new types to the cache should be protected by a mutex */
+
+void MVM_intcache_for(MVMThreadContext *tc, MVMObject *type) {
+ int type_index;
+ int right_slot = -1;
+ for (type_index = 0; type_index < 4; type_index++) {
+ if (tc->instance->int_const_cache->types[type_index] == 0) {
+ }
+ else if (tc->instance->int_const_cache->types[type_index] == type) {
+ return;
+ }
+ }
+ if (right_slot != -1) {
+ int val;
+ for (val = 0; val < 16; val++) {
+ MVMObject *obj;
+ obj = MVM_repr_alloc_init(tc, type);
+ MVM_repr_set_int(tc, obj, val);
+ tc->instance->int_const_cache->cache[type_index][val] = obj;
+ MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->int_const_cache->cache[type_index][val]);
+ }
+ }
+ tc->instance->int_const_cache->types[type_index] = type;
+}
+
+MVMObject *MVM_intcache_get(MVMThreadContext *tc, MVMObject *type, MVMint64 value) {
+ int type_index;
+ int right_slot = -1;
+ MVMObject *result;
+
+ if (value < 0 || value >= 16)
+ return 0;
+
+ for (type_index = 0; type_index < 4; type_index++) {
+ if (tc->instance->int_const_cache->types[type_index] == type) {
+ right_slot = type_index;
+ break;
+ }
+ }
+ if (right_slot != -1) {
+ MVMint64 res_val;
+ result = tc->instance->int_const_cache->cache[right_slot][value];
+ res_val = MVM_repr_get_int(tc, result);
+ if (res_val != value) {
+ printf("the num is %ld, expected %ld\n", res_val, value);
+ }
+ return result;
+ }
+ return 0;
+}
diff --git a/src/core/intcache.h b/src/core/intcache.h
new file mode 100644
index 0000000..100197d
--- /dev/null
+++ b/src/core/intcache.h
@@ -0,0 +1,7 @@
+struct MVMIntConstCache {
+ MVMObject *types[4];
+ MVMObject *cache[4][16];
+};
+
+void MVM_intcache_for(MVMThreadContext *tc, MVMObject *type);
+MVMObject *MVM_intcache_get(MVMThreadContext *tc, MVMObject *type, MVMint64 value);
diff --git a/src/core/interp.c b/src/core/interp.c
index 5745f57..047cf8a 100644
--- a/src/core/interp.c
+++ b/src/core/interp.c
@@ -2296,14 +2296,20 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
}
OP(box_i): {
MVMObject *type = GET_REG(cur_op, 4).o;
- MVMObject *box = REPR(type)->allocate(tc, STABLE(type));
- MVMROOT(tc, box, {
- if (REPR(box)->initialize)
- REPR(box)->initialize(tc, STABLE(box), box, OBJECT_BODY(box));
- REPR(box)->box_funcs.set_int(tc, STABLE(box), box,
- OBJECT_BODY(box), GET_REG(cur_op, 2).i64);
+ MVMObject *box;
+ box = MVM_intcache_get(tc, type, GET_REG(cur_op, 2).i64);
+ if (box == 0) {
+ box = REPR(type)->allocate(tc, STABLE(type));
+ MVMROOT(tc, box, {
+ if (REPR(box)->initialize)
+ REPR(box)->initialize(tc, STABLE(box), box, OBJECT_BODY(box));
+ REPR(box)->box_funcs.set_int(tc, STABLE(box), box,
+ OBJECT_BODY(box), GET_REG(cur_op, 2).i64);
+ GET_REG(cur_op, 0).o = box;
+ });
+ } else {
GET_REG(cur_op, 0).o = box;
- });
+ }
cur_op += 6;
goto NEXT;
}
diff --git a/src/moar.c b/src/moar.c
index c3fda3c..5d296df 100644
--- a/src/moar.c
+++ b/src/moar.c
@@ -60,6 +60,8 @@ MVMInstance * MVM_vm_create_instance(void) {
* they will have program lifetime. */
MVM_gc_allocate_gen2_default_set(instance->main_thread);
+ instance->int_const_cache = calloc(1, sizeof(MVMIntConstCache));
+
/* Bootstrap 6model. It is assumed the GC will not be called during this. */
MVM_6model_bootstrap(instance->main_thread);
diff --git a/src/moar.h b/src/moar.h
index 5e9d0c1..57eb18d 100644
--- a/src/moar.h
+++ b/src/moar.h
@@ -97,6 +97,7 @@ typedef double MVMnum64;
#include "io/procops.h"
#include "math/bigintops.h"
#include "mast/driver.h"
+#include "core/intcache.h"
MVMObject *MVM_backend_config(MVMThreadContext *tc);
diff --git a/src/types.h b/src/types.h
index 238c99c..9389da7 100644
--- a/src/types.h
+++ b/src/types.h
@@ -47,6 +47,7 @@ typedef struct MVMHashAttrStoreBody MVMHashAttrStoreBody;
typedef struct MVMHashBody MVMHashBody;
typedef struct MVMHashEntry MVMHashEntry;
typedef struct MVMHLLConfig MVMHLLConfig;
+typedef struct MVMIntConstCache MVMIntConstCache;
typedef struct MVMInstance MVMInstance;
typedef struct MVMInvocationSpec MVMInvocationSpec;
typedef struct MVMIter MVMIter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment