summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-24 17:06:15 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-24 17:06:15 +0000
commitd3f73f45d8342e37a814eeb8c98e1d04f451a3b4 (patch)
treed871b6a106c9320604d208b3c3d49616496dffbb /compile.c
parentee43611393834f0e10aa982831698a11c3c9ced4 (diff)
* insns.def: Change the operand type of setinlinecache
(OFFSET to IC). This IC must be same as corresponding getinlinecache instruction's IC operand. This change is for a little performance improvement (getting IC directly) and is for the AOT compilation development. * compile.c, iseq.c, insns.def: Change the approach to handling inline cahce (IC) type operand to enable the above change. This change also affects ISeq#to_a method. The inline cache operand will be dumped by fixnum, the index of inline cache, in other words, inline cache identity. * template/insns_info.inc.tmpl, tool/instruction.rb: No need to count inline cache size (insn_iclen()). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26759 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c136
1 files changed, 71 insertions, 65 deletions
diff --git a/compile.c b/compile.c
index 975167c3ec..ad57ca251f 100644
--- a/compile.c
+++ b/compile.c
@@ -12,7 +12,6 @@
#include "ruby/ruby.h"
#define USE_INSN_STACK_INCREASE 1
-#define USE_INSN_ICLEN 1
#include "vm_core.h"
#include "iseq.h"
#include "insns.inc"
@@ -865,6 +864,7 @@ new_insn_core(rb_iseq_t *iseq, int line_no,
int insn_id, int argc, VALUE *argv)
{
INSN *iobj = compile_data_alloc_insn(iseq);
+ /* printf("insn_id: %d, line: %d\n", insn_id, line_no); */
iobj->link.type = ISEQ_ELEMENT_INSN;
iobj->link.next = 0;
@@ -900,12 +900,13 @@ new_insn_send(rb_iseq_t *iseq, int line_no,
{
INSN *iobj = 0;
VALUE *operands =
- (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 4);
+ (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 5);
operands[0] = id;
operands[1] = argc;
operands[2] = block;
operands[3] = flag;
- iobj = new_insn_core(iseq, line_no, BIN(send), 4, operands);
+ operands[4] = INT2FIX(iseq->ic_size++);
+ iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
return iobj;
}
@@ -1261,8 +1262,6 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
struct iseq_insn_info_entry *insn_info_table;
LINK_ELEMENT *list;
VALUE *generated_iseq;
- int ic_size = 0;
- int ic_index = 0;
int k, pos, sp, stack_max = 0, line = 0;
@@ -1276,7 +1275,6 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
iobj = (INSN *)list;
line = iobj->line_no;
pos += insn_data_length(iobj);
- ic_size += insn_iclen(iobj->insn_id);
k++;
break;
}
@@ -1314,9 +1312,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
/* make instruction sequence */
generated_iseq = ALLOC_N(VALUE, pos);
insn_info_table = ALLOC_N(struct iseq_insn_info_entry, k);
- iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, ic_size);
- MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, ic_size);
- iseq->ic_size = ic_size;
+ iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
+ MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
list = FIRST_ELEMENT(anchor);
k = pos = sp = 0;
@@ -1325,7 +1322,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
switch (list->type) {
case ISEQ_ELEMENT_INSN:
{
- int j, len, insn, iclen = 0;
+ int j, len, insn;
const char *types;
VALUE *operands;
@@ -1338,21 +1335,19 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
}
/* fprintf(stderr, "insn: %-16s, sp: %d\n", insn_name(iobj->insn_id), sp); */
-
operands = iobj->operands;
insn = iobj->insn_id;
generated_iseq[pos] = insn;
types = insn_op_types(insn);
len = insn_len(insn);
- iclen = insn_iclen(insn);
/* operand check */
- if (iobj->operand_size + iclen != len - 1) {
- printf("%d, %d, %d\n", iobj->operand_size, iclen, len);
+ if (iobj->operand_size != len - 1) {
+ /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */
dump_disasm_list(list);
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"operand size miss! (%d for %d)",
- iobj->operand_size + iclen, len - 1);
+ iobj->operand_size, len - 1);
xfree(generated_iseq);
xfree(insn_info_table);
return 0;
@@ -1434,10 +1429,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
}
case TS_IC: /* inline cache */
{
- IC ic = &iseq->ic_entries[ic_index++];
- if (UNLIKELY(ic_index > ic_size)) {
+ int ic_index = FIX2INT(operands[j]);
+ IC ic = &iseq->ic_entries[ic_index];
+ if (UNLIKELY(ic_index > iseq->ic_size)) {
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d",
- ic_index, ic_size);
+ ic_index, iseq->ic_size);
}
generated_iseq[pos + 1 + j] = (VALUE)ic;
break;
@@ -1782,10 +1778,22 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
static int
-insn_set_specialized_instruction(INSN *iobj, int insn_id)
+insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
{
+ int i, old_opsize = iobj->operand_size;
+
iobj->insn_id = insn_id;
- iobj->operand_size = 0;
+ iobj->operand_size = insn_len(insn_id) - 1;
+ /* printf("iobj->operand_size: %d\n", iobj->operand_size); */
+
+ if (iobj->operand_size > old_opsize) {
+ iobj->operands = (VALUE *)compile_data_alloc(iseq, iobj->operand_size);
+ }
+
+ for (i=0; i<iobj->operand_size; i++) {
+ iobj->operands[i] = INT2FIX(iseq->ic_size++);
+ }
+
return COMPILE_OK;
}
@@ -1802,59 +1810,59 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
if (block == 0 && flag == INT2FIX(0)) {
if (argc == 0) {
if (mid == idLength) {
- insn_set_specialized_instruction(iobj, BIN(opt_length));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_length));
}
else if (mid == idSize) {
- insn_set_specialized_instruction(iobj, BIN(opt_size));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_size));
}
else if (mid == idSucc) {
- insn_set_specialized_instruction(iobj, BIN(opt_succ));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_succ));
}
else if (mid == idNot) {
- insn_set_specialized_instruction(iobj, BIN(opt_not));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_not));
}
}
else if (argc == 1) {
if (0) {
}
else if (mid == idPLUS) {
- insn_set_specialized_instruction(iobj, BIN(opt_plus));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_plus));
}
else if (mid == idMINUS) {
- insn_set_specialized_instruction(iobj, BIN(opt_minus));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_minus));
}
else if (mid == idMULT) {
- insn_set_specialized_instruction(iobj, BIN(opt_mult));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_mult));
}
else if (mid == idDIV) {
- insn_set_specialized_instruction(iobj, BIN(opt_div));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_div));
}
else if (mid == idMOD) {
- insn_set_specialized_instruction(iobj, BIN(opt_mod));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_mod));
}
else if (mid == idEq) {
- insn_set_specialized_instruction(iobj, BIN(opt_eq));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_eq));
}
else if (mid == idNeq) {
- insn_set_specialized_instruction(iobj, BIN(opt_neq));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_neq));
}
else if (mid == idLT) {
- insn_set_specialized_instruction(iobj, BIN(opt_lt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_lt));
}
else if (mid == idLE) {
- insn_set_specialized_instruction(iobj, BIN(opt_le));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_le));
}
else if (mid == idGT) {
- insn_set_specialized_instruction(iobj, BIN(opt_gt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_gt));
}
else if (mid == idGE) {
- insn_set_specialized_instruction(iobj, BIN(opt_ge));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_ge));
}
else if (mid == idLTLT) {
- insn_set_specialized_instruction(iobj, BIN(opt_ltlt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_ltlt));
}
else if (mid == idAREF) {
- insn_set_specialized_instruction(iobj, BIN(opt_aref));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_aref));
}
}
}
@@ -3700,8 +3708,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (!poped) {
ADD_INSN(ret, nd_line(node), dup);
}
- ADD_INSN1(ret, nd_line(node), setinstancevariable,
- ID2SYM(node->nd_vid));
+ ADD_INSN2(ret, nd_line(node), setinstancevariable,
+ ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++));
break;
}
case NODE_CDECL:{
@@ -4310,8 +4318,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_IVAR:{
debugi("nd_vid", node->nd_vid);
if (!poped) {
- ADD_INSN1(ret, nd_line(node), getinstancevariable,
- ID2SYM(node->nd_vid));
+ ADD_INSN2(ret, nd_line(node), getinstancevariable,
+ ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++));
}
break;
}
@@ -4319,13 +4327,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
debugi("nd_vid", node->nd_vid);
if (iseq->compile_data->option->inline_const_cache) {
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN1(ret, nd_line(node), getinlinecache, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
else {
@@ -4474,16 +4481,15 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_DREGX_ONCE:{
/* TODO: once? */
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN1(ret, nd_line(node), onceinlinecache, lend);
+ ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
compile_dregx(iseq, ret, node);
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
if (poped) {
@@ -4636,8 +4642,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_COLON2:{
if (rb_is_const_id(node->nd_mid)) {
/* constant */
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
+
DECL_ANCHOR(pref);
DECL_ANCHOR(body);
@@ -4646,8 +4653,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
compile_colon2(iseq, node, pref, body);
if (LIST_SIZE_ZERO(pref)) {
if (iseq->compile_data->option->inline_const_cache) {
- ADD_LABEL(ret, lstart);
- ADD_INSN1(ret, nd_line(node), getinlinecache, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
}
else {
ADD_INSN(ret, nd_line(node), putnil);
@@ -4656,7 +4662,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_SEQ(ret, body);
if (iseq->compile_data->option->inline_const_cache) {
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
}
@@ -4678,14 +4684,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_COLON3:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
- debugi("colon3#nd_mid", node->nd_mid);
+ int ic_index = iseq->ic_size++;
+
+ debugi("colon3#nd_mid", node->nd_mid);
/* add cache insn */
if (iseq->compile_data->option->inline_const_cache) {
- ADD_LABEL(ret, lstart);
- ADD_INSN1(ret, nd_line(node), getinlinecache, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
}
@@ -4693,7 +4699,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
if (iseq->compile_data->option->inline_const_cache) {
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
@@ -4821,19 +4827,18 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_POSTEXE:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN1(ret, nd_line(node), onceinlinecache, lend);
+ ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, nd_line(node), putiseq, block);
ADD_SEND (ret, nd_line(node), ID2SYM(id_core_set_postexe), INT2FIX(1));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
if (poped) {
@@ -4960,15 +4965,15 @@ insn_data_line_no(INSN *iobj)
static VALUE
insn_data_to_s_detail(INSN *iobj)
{
- VALUE str = rb_str_new(0, 0);
+ VALUE str = rb_sprintf("%-16s", insn_name(iobj->insn_id));
- str = rb_sprintf("%-16s", insn_name(iobj->insn_id));
if (iobj->operands) {
const char *types = insn_op_types(iobj->insn_id);
int j;
for (j = 0; types[j]; j++) {
char type = types[j];
+ printf("str: %p, type: %c\n", str, type);
switch (type) {
case TS_OFFSET: /* label(destination position) */
@@ -5004,7 +5009,7 @@ insn_data_to_s_detail(INSN *iobj)
rb_str_cat2(str, rb_id2name(entry->id));
}
case TS_IC: /* method cache */
- rb_str_cat2(str, "<ic>");
+ rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
break;
case TS_CDHASH: /* case/when condition cache */
rb_str_cat2(str, "<ch>");
@@ -5264,6 +5269,7 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
break;
case TS_IC:
+ argv[j] = op;
break;
case TS_ID:
argv[j] = rb_convert_type(op, T_SYMBOL,