diff options
| author | take-cheeze <[email protected]> | 2018-10-29 19:17:05 +0900 |
|---|---|---|
| committer | take-cheeze <[email protected]> | 2018-10-29 19:17:05 +0900 |
| commit | 3248de83b6754eecc99d9ab6fdef8bb3575fcd04 (patch) | |
| tree | 56f57e3526c89ff9581b0d7b71a0be742e09800d | |
| parent | eebb56713e27cde27a7b899da8636a0634704863 (diff) | |
| download | mruby-3248de83b6754eecc99d9ab6fdef8bb3575fcd04.tar.gz mruby-3248de83b6754eecc99d9ab6fdef8bb3575fcd04.zip | |
Reduce instruction size
| -rw-r--r-- | include/mruby/ops.h | 22 | ||||
| -rw-r--r-- | include/mruby/symbol.h | 32 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 43 | ||||
| -rw-r--r-- | src/symbol.c | 26 | ||||
| -rw-r--r-- | src/vm.c | 62 |
5 files changed, 130 insertions, 55 deletions
diff --git a/include/mruby/ops.h b/include/mruby/ops.h index f23bb1b0b..7531a5ee2 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -70,17 +70,17 @@ OPCODE(RETURN, B) /* return R(a) (normal) */ OPCODE(RETURN_BLK, B) /* return R(a) (in-block return) */ OPCODE(BREAK, B) /* break R(a) */ OPCODE(BLKPUSH, BS) /* R(a) = block (16=m5:r1:m5:d1:lv4) */ -OPCODE(ADD, BB) /* R(a) = R(a)+R(a+1) (Syms[b]=:+) */ -OPCODE(ADDI, BBB) /* R(a) = R(a)+mrb_int(c) (Syms[b]=:+) */ -OPCODE(SUB, BB) /* R(a) = R(a)-R(a+1) (Syms[b]=:-) */ -OPCODE(SUBI, BBB) /* R(a) = R(a)-C (Syms[b]=:-) */ -OPCODE(MUL, BB) /* R(a) = R(a)*R(a+1) (Syms[b]=:*) */ -OPCODE(DIV, BB) /* R(a) = R(a)/R(a+1) (Syms[b]=:/) */ -OPCODE(EQ, BB) /* R(a) = R(a)==R(a+1) (Syms[b]=:==) */ -OPCODE(LT, BB) /* R(a) = R(a)<R(a+1) (Syms[b]=:<) */ -OPCODE(LE, BB) /* R(a) = R(a)<=R(a+1) (Syms[b]=:<=) */ -OPCODE(GT, BB) /* R(a) = R(a)>R(a+1) (Syms[b]=:>) */ -OPCODE(GE, BB) /* R(a) = R(a)>=R(a+1) (Syms[b]=:>=) */ +OPCODE(ADD, B) /* R(a) = R(a)+R(a+1) */ +OPCODE(ADDI, BB) /* R(a) = R(a)+mrb_int(c) */ +OPCODE(SUB, B) /* R(a) = R(a)-R(a+1) */ +OPCODE(SUBI, BB) /* R(a) = R(a)-C */ +OPCODE(MUL, B) /* R(a) = R(a)*R(a+1) */ +OPCODE(DIV, B) /* R(a) = R(a)/R(a+1) */ +OPCODE(EQ, B) /* R(a) = R(a)==R(a+1) */ +OPCODE(LT, B) /* R(a) = R(a)<R(a+1) */ +OPCODE(LE, B) /* R(a) = R(a)<=R(a+1) */ +OPCODE(GT, B) /* R(a) = R(a)>R(a+1) */ +OPCODE(GE, B) /* R(a) = R(a)>=R(a+1) */ OPCODE(ARRAY, BB) /* R(a) = ary_new(R(a),R(a+1)..R(a+b)) */ OPCODE(ARRAY2, BBB) /* R(a) = ary_new(R(b),R(b+1)..R(b+c)) */ OPCODE(ARYCAT, B) /* ary_cat(R(a),R(a+1)) */ diff --git a/include/mruby/symbol.h b/include/mruby/symbol.h new file mode 100644 index 000000000..595caeefd --- /dev/null +++ b/include/mruby/symbol.h @@ -0,0 +1,32 @@ +/* +** mruby/symbol.h - symbol utilities +** +** See Copyright Notice in mruby.h +*/ + +#ifndef MRUBY_SYMBOL_H +#define MRUBY_SYMBOL_H + +#include "common.h" + +/** + * Symbol utilities + */ +MRB_BEGIN_DECL + +typedef enum mrb_reserved_symbol { + mrb_sym_add = 1, // + + mrb_sym_sub = 2, // - + mrb_sym_mul = 3, // * + mrb_sym_div = 4, // / + mrb_sym_eq = 5, // == + mrb_sym_lt = 6, // < + mrb_sym_le = 7, // <= + mrb_sym_gt = 8, // > + mrb_sym_ge = 9, // >= + mrb_sym_method_missing = 10, // method_missing +} mrb_reserved_symbol; + +MRB_END_DECL + +#endif /* MRUBY_SYMBOL_H */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8ab1b9bc3..759e7267e 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -468,11 +468,11 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) } static void -gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst, uint16_t idx) +gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) { if (no_peephole(s)) { normal: - genop_2(s, op, dst, idx); + genop_1(s, op, dst); return; } else { @@ -493,10 +493,10 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst, uint16_t idx) if (data.b >= 128) goto normal; s->pc = s->lastpc; if (op == OP_ADD) { - genop_3(s, OP_ADDI, dst, idx, (uint8_t)data.b); + genop_2(s, OP_ADDI, dst, (uint8_t)data.b); } else { - genop_3(s, OP_SUBI, dst, idx, (uint8_t)data.b); + genop_2(s, OP_SUBI, dst, (uint8_t)data.b); } break; default: @@ -982,6 +982,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) gen_move(s, cursp(), recv, 1); skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val); } + // TODO: don't new when unused idx = new_sym(s, sym); tree = tree->cdr->cdr->car; if (tree) { @@ -1017,31 +1018,31 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen); if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { - gen_addsub(s, OP_ADD, cursp(), idx); + gen_addsub(s, OP_ADD, cursp()); } else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { - gen_addsub(s, OP_SUB, cursp(), idx); + gen_addsub(s, OP_SUB, cursp()); } else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { - genop_2(s, OP_MUL, cursp(), idx); + genop_1(s, OP_MUL, cursp()); } else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { - genop_2(s, OP_DIV, cursp(), idx); + genop_1(s, OP_DIV, cursp()); } else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { - genop_2(s, OP_LT, cursp(), idx); + genop_1(s, OP_LT, cursp()); } else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { - genop_2(s, OP_LE, cursp(), idx); + genop_1(s, OP_LE, cursp()); } else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { - genop_2(s, OP_GT, cursp(), idx); + genop_1(s, OP_GT, cursp()); } else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { - genop_2(s, OP_GE, cursp(), idx); + genop_1(s, OP_GE, cursp()); } else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { - genop_2(s, OP_EQ, cursp(), idx); + genop_1(s, OP_EQ, cursp()); } else { if (sendv) { @@ -2025,28 +2026,28 @@ codegen(codegen_scope *s, node *tree, int val) idx = new_sym(s, sym); if (len == 1 && name[0] == '+') { - gen_addsub(s, OP_ADD, cursp(), idx); + gen_addsub(s, OP_ADD, cursp()); } else if (len == 1 && name[0] == '-') { - gen_addsub(s, OP_SUB, cursp(), idx); + gen_addsub(s, OP_SUB, cursp()); } else if (len == 1 && name[0] == '*') { - genop_2(s, OP_MUL, cursp(), idx); + genop_1(s, OP_MUL, cursp()); } else if (len == 1 && name[0] == '/') { - genop_2(s, OP_DIV, cursp(), idx); + genop_1(s, OP_DIV, cursp()); } else if (len == 1 && name[0] == '<') { - genop_2(s, OP_LT, cursp(), idx); + genop_1(s, OP_LT, cursp()); } else if (len == 2 && name[0] == '<' && name[1] == '=') { - genop_2(s, OP_LE, cursp(), idx); + genop_1(s, OP_LE, cursp()); } else if (len == 1 && name[0] == '>') { - genop_2(s, OP_GT, cursp(), idx); + genop_1(s, OP_GT, cursp()); } else if (len == 2 && name[0] == '>' && name[1] == '=') { - genop_2(s, OP_GE, cursp(), idx); + genop_1(s, OP_GE, cursp()); } else { genop_3(s, OP_SEND, cursp(), idx, 1); diff --git a/src/symbol.c b/src/symbol.c index 6b4c7200c..f7dbc1be1 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -11,6 +11,7 @@ #include <mruby/string.h> #include <mruby/dump.h> #include <mruby/class.h> +#include <mruby/symbol.h> /* ------------------------------------------------------ */ typedef struct symbol_name { @@ -170,10 +171,35 @@ mrb_free_symtbl(mrb_state *mrb) kh_destroy(n2s, mrb, mrb->name2sym); } +struct reserved_symbol_t { + mrb_reserved_symbol sym; + char const *str; +}; + +static struct reserved_symbol_t reserved_symbols[] = { + { mrb_sym_add, "+" }, + { mrb_sym_sub, "-" }, + { mrb_sym_mul, "*" }, + { mrb_sym_div, "/" }, + { mrb_sym_eq, "==" }, + { mrb_sym_lt, "<" }, + { mrb_sym_le, "<=" }, + { mrb_sym_gt, ">" }, + { mrb_sym_ge, ">=" }, + { mrb_sym_method_missing, "method_missing" }, + { 0, NULL }, +}; + void mrb_init_symtbl(mrb_state *mrb) { + int i; mrb->name2sym = kh_init(n2s, mrb); + + for (i = 0; reserved_symbols[i].sym != 0; ++i) { + mrb_sym s = mrb_intern_static(mrb, reserved_symbols[i].str, strlen(reserved_symbols[i].str)); + mrb_assert(s == reserved_symbols[i].sym); + } } /********************************************************************** @@ -21,6 +21,7 @@ #include <mruby/opcode.h> #include "value_array.h" #include <mruby/throw.h> +#include <mruby/symbol.h> #ifdef MRB_DISABLE_STDIO #if defined(__cplusplus) @@ -1009,6 +1010,7 @@ mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) uint32_t a; uint16_t b; uint8_t c; + mrb_sym mid; #ifdef DIRECT_THREADED static void *optable[] = { @@ -1386,9 +1388,18 @@ RETRY_TRY_BLOCK: SET_NIL_VALUE(regs[bidx]); goto L_SENDB; }; + L_SEND_CONSTSYM: + { + /* push nil after arguments */ + int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; + SET_NIL_VALUE(regs[bidx]); + goto L_SENDB_CONSTSYM; + }; CASE(OP_SENDB, BBB) L_SENDB: + mid = syms[b]; + L_SENDB_CONSTSYM: { int argc = (c == CALL_MAXARGS) ? -1 : c; int bidx = (argc < 0) ? a+2 : a+c+1; @@ -1396,7 +1407,6 @@ RETRY_TRY_BLOCK: struct RClass *cls; mrb_callinfo *ci = mrb->c->ci; mrb_value recv, blk; - mrb_sym mid = syms[b]; mrb_assert(bidx < irep->nregs); @@ -2204,7 +2214,7 @@ RETRY_TRY_BLOCK: v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ } while(0) - CASE(OP_ADD, BB) { + CASE(OP_ADD, B) { /* need to check if op is overridden */ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): @@ -2259,13 +2269,14 @@ RETRY_TRY_BLOCK: break; default: c = 1; - goto L_SEND; + mid = mrb_sym_add; + goto L_SEND_CONSTSYM; } mrb_gc_arena_restore(mrb, ai); NEXT; } - CASE(OP_SUB, BB) { + CASE(OP_SUB, B) { /* need to check if op is overridden */ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): @@ -2316,12 +2327,13 @@ RETRY_TRY_BLOCK: #endif default: c = 1; - goto L_SEND; + mid = mrb_sym_sub; + goto L_SEND_CONSTSYM; } NEXT; } - CASE(OP_MUL, BB) { + CASE(OP_MUL, B) { /* need to check if op is overridden */ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): @@ -2372,12 +2384,13 @@ RETRY_TRY_BLOCK: #endif default: c = 1; - goto L_SEND; + mid = mrb_sym_mul; + goto L_SEND_CONSTSYM; } NEXT; } - CASE(OP_DIV, BB) { + CASE(OP_DIV, B) { #ifndef MRB_WITHOUT_FLOAT double x, y, f; #endif @@ -2411,7 +2424,8 @@ RETRY_TRY_BLOCK: #endif default: c = 1; - goto L_SEND; + mid = mrb_sym_div; + goto L_SEND_CONSTSYM; } #ifndef MRB_WITHOUT_FLOAT @@ -2509,7 +2523,7 @@ RETRY_TRY_BLOCK: #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) #ifdef MRB_WITHOUT_FLOAT -#define OP_CMP(op) do {\ +#define OP_CMP(op, sym) do {\ int result;\ /* need to check if - is overridden */\ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ @@ -2518,7 +2532,8 @@ RETRY_TRY_BLOCK: break;\ default:\ c = 1;\ - goto L_SEND;\ + mid = mrb_sym_ ## sym;\ + goto L_SEND_CONSTSYM;\ }\ if (result) {\ SET_TRUE_VALUE(regs[a]);\ @@ -2528,7 +2543,7 @@ RETRY_TRY_BLOCK: }\ } while(0) #else -#define OP_CMP(op) do {\ +#define OP_CMP(op, sym) do {\ int result;\ /* need to check if - is overridden */\ switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ @@ -2546,7 +2561,8 @@ RETRY_TRY_BLOCK: break;\ default:\ c = 1;\ - goto L_SEND;\ + mid = mrb_sym_ ## sym;\ + goto L_SEND_CONSTSYM;\ }\ if (result) {\ SET_TRUE_VALUE(regs[a]);\ @@ -2557,33 +2573,33 @@ RETRY_TRY_BLOCK: } while(0) #endif - CASE(OP_EQ, BB) { + CASE(OP_EQ, B) { if (mrb_obj_eq(mrb, regs[a], regs[a+1])) { SET_TRUE_VALUE(regs[a]); } else { - OP_CMP(==); + OP_CMP(==, eq); } NEXT; } - CASE(OP_LT, BB) { - OP_CMP(<); + CASE(OP_LT, B) { + OP_CMP(<, gt); NEXT; } - CASE(OP_LE, BB) { - OP_CMP(<=); + CASE(OP_LE, B) { + OP_CMP(<=, ge); NEXT; } - CASE(OP_GT, BB) { - OP_CMP(>); + CASE(OP_GT, B) { + OP_CMP(>, lt); NEXT; } - CASE(OP_GE, BB) { - OP_CMP(>=); + CASE(OP_GE, B) { + OP_CMP(>=, le); NEXT; } |
