Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

inline method caching

  • Loading branch information...
commit c5c6da31add62d581cd43a74087338b025773d8b 1 parent 68b0bf0
@charliesome charliesome authored
View
7 inc/slash/vm.h
@@ -12,6 +12,8 @@ struct sl_vm_ids {
SLID op_eq;
SLID op_lt;
SLID op_lte;
+ SLID op_add;
+ SLID op_sub;
/* methods */
SLID call;
SLID current;
@@ -90,6 +92,7 @@ typedef struct sl_vm {
sl_gc_arena_t* arena;
st_table_t* required;
uint32_t state_constant;
+ uint32_t state_method;
struct {
st_table_t* name_to_id;
SLVAL* id_to_name;
@@ -138,12 +141,14 @@ typedef enum sl_vm_opcode {
SL_OP_END_TRY,
SL_OP_CATCH,
SL_OP_YADA_YADA,
- SL_OP_BIND_METHOD
+ SL_OP_BIND_METHOD,
+ SL_OP_ADD
}
sl_vm_opcode_t;
typedef struct sl_vm_inline_cache {
uint32_t state;
+ SLVAL klass;
SLVAL value;
}
sl_vm_inline_cache_t;
View
1  src/class.c
@@ -219,6 +219,7 @@ sl_define_method3(sl_vm_t* vm, SLVAL klass, SLID name, SLVAL method)
{
sl_expect(vm, method, vm->lib.Method);
st_insert(get_class(vm, klass)->instance_methods, (st_data_t)name.id, (st_data_t)sl_get_ptr(method));
+ vm->state_method++;
}
int
View
2  src/compile.c
@@ -155,6 +155,8 @@ emit_send(sl_compile_state_t* cs, size_t recv, SLID id, size_t arg_base, size_t
emit(cs, insn);
insn.uint = arg_size;
emit(cs, insn);
+ insn.ic = sl_alloc(cs->vm->arena, sizeof(sl_vm_inline_cache_t));
+ emit(cs, insn);
insn.uint = return_reg;
emit(cs, insn);
}
View
3  src/vm.c
@@ -148,6 +148,7 @@ sl_init()
vm->lib.StackOverflowError_instance = sl_make_error2(vm, vm->lib.StackOverflowError, sl_make_cstring(vm, "Stack Overflow"));
vm->state_constant = 1;
+ vm->state_method = 1;
return vm;
}
@@ -176,6 +177,8 @@ sl_init_id(sl_vm_t* vm)
OP(eq, "==");
OP(lt, "<");
OP(lte, "<=");
+ OP(add, "+");
+ OP(sub, "-");
ID(call);
ID(current);
View
16 src/vm_defn.inc
@@ -167,14 +167,24 @@ INSTRUCTION(SL_OP_IMMEDIATE, {
2: <id:name>
3: <reg:first_arg> // arguments must be in a contiguous register region
4: <uint:arg_count>
- 5: <reg:dest> */
+ 5: <ic:inline_cache>
+ 6: <reg:dest> */
INSTRUCTION(SL_OP_SEND, {
SLVAL receiver = NEXT_REG();
SLID id = NEXT_ID();
SLVAL* argv = &NEXT_REG();
size_t argc = NEXT_UINT();
- /* @TODO: backtrace stuff */
- NEXT_REG() = sl_send2(vm, receiver, id, argc, argv);
+ sl_vm_inline_cache_t* ic = NEXT_IC();
+ if(sl_get_primitive_type(receiver) != SL_T_INT && sl_get_ptr(receiver)->singleton_methods) {
+ NEXT_REG() = sl_send2(vm, receiver, id, argc, argv);
+ } else {
+ SLVAL recv_klass = sl_class_of(vm, receiver);
+ if(ic->state < vm->state_method || ic->klass.i != recv_klass.i) {
+ ic->klass = recv_klass;
+ ic->value.i = (intptr_t)sl_lookup_method(vm, receiver, id);
+ }
+ NEXT_REG() = sl_apply_method(vm, receiver, (sl_method_t*)ic->value.i, argc, argv);
+ }
})
/* 0: JUMP
Please sign in to comment.
Something went wrong with that request. Please try again.