1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
ko1 2010-02-24 17:06:15 +00:00
parent ee43611393
commit d3f73f45d8
6 changed files with 94 additions and 90 deletions

View file

@ -1,3 +1,20 @@
Thu Feb 25 00:43:57 2010 Koichi Sasada <ko1@atdot.net>
* 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()).
Thu Feb 25 00:57:59 2010 Tanaka Akira <akr@fsij.org>
* pack.c (swap64): don't redefine.

134
compile.c
View file

@ -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));
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,

View file

@ -1217,12 +1217,10 @@ onceinlinecache
*/
DEFINE_INSN
setinlinecache
(OFFSET dst)
(IC ic)
(VALUE val)
(VALUE val)
{
IC ic = GET_CONST_INLINE_CACHE(dst);
if (ic->ic_value.value == Qundef) {
rb_ary_push(GET_ISEQ()->mark_ary, val);
}

8
iseq.c
View file

@ -797,7 +797,7 @@ insn_operand_intern(rb_iseq_t *iseq,
break;
case TS_IC:
ret = rb_str_new2("<ic>");
ret = rb_sprintf("<ic:%d>", (struct iseq_inline_cache_entry *)op - iseq->ic_entries);
break;
case TS_CDHASH:
@ -1228,8 +1228,10 @@ iseq_data_to_ary(rb_iseq_t *iseq)
rb_ary_push(ary, ID2SYM(entry->id));
}
break;
case TS_IC:
rb_ary_push(ary, Qnil);
case TS_IC: {
struct iseq_inline_cache_entry *ic = (struct iseq_inline_cache_entry *)*seq;
rb_ary_push(ary, INT2FIX(ic - iseq->ic_entries));
}
break;
case TS_ID:
rb_ary_push(ary, ID2SYM(*seq));

View file

@ -23,10 +23,6 @@ static const int insn_len_info[] = {
<%= operands_num_info %>
};
static const int insn_iclen_info[] = {
<%= icoperands_num_info %>
};
#ifdef USE_INSN_RET_NUM
static const int insn_stack_push_num_info[] = {
<%= stack_num_info %>
@ -85,11 +81,3 @@ insn_ret_num(VALUE insn)
return insn_stack_push_num_info[(int)insn];
}
#endif
#ifdef USE_INSN_ICLEN
static int
insn_iclen(int insn)
{
return insn_iclen_info[insn];
}
#endif

View file

@ -984,7 +984,6 @@ class RubyVM
# operands info
operands_info = ''
operands_num_info = ''
icoperands_num_info = ''
@insns.each{|insn|
opes = insn.opes
@ -996,12 +995,6 @@ class RubyVM
num = opes.size + 1
operands_num_info << " #{num},\n"
icnum = 0
opes.each{|e|
icnum += 1 if e[0] == 'IC'
}
icoperands_num_info << " #{icnum},\n"
}
# stack num