Skip to content

Commit

Permalink
implement a constant cache for ints 0 to 16
Browse files Browse the repository at this point in the history
  • Loading branch information
timo committed Feb 14, 2014
1 parent 4bfc5eb commit 96e7aaf
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 13 deletions.
2 changes: 2 additions & 0 deletions build/Makefile.in
Expand Up @@ -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@ \
Expand Down Expand Up @@ -153,6 +154,7 @@ HEADERS = src/moar.h \
src/core/dll.h \
src/core/ext.h \
src/core/continuation.h \
src/core/intcache.h \
src/io/fileops.h \
src/io/socketops.h \
src/io/dirops.h \
Expand Down
2 changes: 2 additions & 0 deletions src/6model/bootstrap.c
Expand Up @@ -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);
}
8 changes: 6 additions & 2 deletions src/6model/reprconv.c
Expand Up @@ -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;
}

Expand Down
10 changes: 6 additions & 4 deletions src/6model/serialization.c
Expand Up @@ -1501,14 +1501,16 @@ MVMObject * read_ref_func(MVMThreadContext *tc, MVMSerializationReader *reader)
return read_obj_ref(tc, reader);
case REFVAR_VM_NULL:
return NULL;
case REFVAR_VM_INT:
result = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTInt);
case REFVAR_VM_INT: {
MVMint64 value;
if (reader->root.version < VARINT_MIN_VERSION) {
MVM_repr_set_int(tc, result, read_int_func(tc, reader));
value = read_int_func(tc, reader);
} else {
MVM_repr_set_int(tc, result, read_varint_func(tc, reader));
value = read_varint_func(tc, reader);
}
result = MVM_repr_box_int(tc, tc->instance->boot_types.BOOTInt, value);
return result;
}
case REFVAR_VM_NUM:
result = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTNum);
MVM_repr_set_num(tc, result, read_num_func(tc, reader));
Expand Down
2 changes: 2 additions & 0 deletions src/core/hll.c
Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions src/core/instance.h
Expand Up @@ -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 15
* 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;
Expand Down
55 changes: 55 additions & 0 deletions src/core/intcache.c
@@ -0,0 +1,55 @@
#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] == NULL) {
right_slot = type_index;
break;
}
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;
MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->int_const_cache->types[type_index]);
}
}

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 NULL;

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 NULL;
}
7 changes: 7 additions & 0 deletions 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);
20 changes: 13 additions & 7 deletions src/core/interp.c
Expand Up @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/moar.c
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/moar.h
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/types.h
Expand Up @@ -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;
Expand Down

0 comments on commit 96e7aaf

Please sign in to comment.