summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2013-11-07 04:20:46 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2013-11-07 04:20:46 +0900
commit677a2ac22633473fb286d7297a8585c01fe7394b (patch)
treeb0052f5b50bfb490c9780c6dd0645a2742aaf655
parente92d4e2680716d3e16a264e46394cb6e458699f9 (diff)
downloadmruby-677a2ac22633473fb286d7297a8585c01fe7394b.tar.gz
mruby-677a2ac22633473fb286d7297a8585c01fe7394b.zip
irep->pool not to be GCed
-rw-r--r--include/mruby/irep.h12
-rw-r--r--src/codegen.c61
-rw-r--r--src/dump.c22
-rw-r--r--src/gc.c47
-rw-r--r--src/load.c13
-rw-r--r--src/state.c6
-rw-r--r--src/string.c28
-rw-r--r--src/vm.c11
8 files changed, 87 insertions, 113 deletions
diff --git a/include/mruby/irep.h b/include/mruby/irep.h
index 83cd4b9e8..a31fef39c 100644
--- a/include/mruby/irep.h
+++ b/include/mruby/irep.h
@@ -18,7 +18,17 @@ typedef struct mrb_irep {
uint8_t flags;
mrb_code *iseq;
- mrb_value *pool;
+ struct irep_pool {
+ union {
+ mrb_float f;
+ struct irep_pool_string {
+ mrb_int len;
+ char buf[1];
+ } *s;
+ mrb_int i;
+ } value;
+ enum mrb_vtype type;
+ } *pool;
mrb_sym *syms;
struct mrb_irep **reps;
diff --git a/src/codegen.c b/src/codegen.c
index 2afcb340e..21714d131 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -316,8 +316,8 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
if (c0 == OP_STRING) {
int i = GETARG_Bx(i0);
- if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING &&
- RSTRING_LEN(s->irep->pool[i]) == 0) {
+ if (s->irep->pool[i].type == MRB_TT_STRING &&
+ s->irep->pool[i].value.s->len == 0) {
s->pc--;
return;
}
@@ -397,34 +397,62 @@ static inline int
new_lit(codegen_scope *s, mrb_value val)
{
size_t i;
+ struct irep_pool *pv;
switch (mrb_type(val)) {
case MRB_TT_STRING:
for (i=0; i<s->irep->plen; i++) {
- mrb_value pv = s->irep->pool[i];
+ pv = &s->irep->pool[i];
mrb_int len;
- if (mrb_type(pv) != MRB_TT_STRING) continue;
- if ((len = RSTRING_LEN(pv)) != RSTRING_LEN(val)) continue;
- if (memcmp(RSTRING_PTR(pv), RSTRING_PTR(val), len) == 0)
+ if (pv->type != MRB_TT_STRING) continue;
+ if ((len = pv->value.s->len) != RSTRING_LEN(val)) continue;
+ if (memcmp(pv->value.s->buf, RSTRING_PTR(val), len) == 0)
return i;
}
break;
case MRB_TT_FLOAT:
- default:
for (i=0; i<s->irep->plen; i++) {
- if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i;
+ pv = &s->irep->pool[i];
+ if (pv->value.f == mrb_float(val)) return i;
}
break;
+ case MRB_TT_FIXNUM:
+ for (i=0; i<s->irep->plen; i++) {
+ pv = &s->irep->pool[i];
+ if (pv->value.i == mrb_fixnum(val)) return i;
+ }
+ break;
+ default:
+ /* should not happen */
+ return 0;
}
if (s->irep->plen == s->pcapa) {
s->pcapa *= 2;
- s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
+ s->irep->pool = (struct irep_pool*)codegen_realloc(s, s->irep->pool, sizeof(struct irep_pool)*s->pcapa);
}
- s->irep->pool[s->irep->plen] = val;
+
+ pv = &s->irep->pool[s->irep->plen];
i = s->irep->plen++;
+ pv->type = mrb_type(val);
+ switch (pv->type) {
+ case MRB_TT_STRING:
+ pv->value.s = (struct irep_pool_string*)codegen_malloc(s, sizeof(struct irep_pool_string) + RSTRING_LEN(val));
+ pv->value.s->len = RSTRING_LEN(val);
+ memcpy(pv->value.s->buf, RSTRING_PTR(val), RSTRING_LEN(val));
+ break;
+ case MRB_TT_FLOAT:
+ pv->value.f = mrb_float(val);
+ break;
+ case MRB_TT_FIXNUM:
+ pv->value.i = mrb_fixnum(val);
+ break;
+ default:
+ /* should not happen */
+ break;
+ }
return i;
}
@@ -2382,7 +2410,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
p->pcapa = 32;
- p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
+ p->irep->pool = (struct irep_pool*)mrb_malloc(mrb, sizeof(struct irep_pool)*p->pcapa);
p->irep->plen = 0;
p->scapa = 256;
@@ -2435,9 +2463,9 @@ scope_finish(codegen_scope *s)
irep->lines = 0;
}
}
- irep->pool = (mrb_value *)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
- irep->syms = (mrb_sym *)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
- irep->reps = (mrb_irep **)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
+ irep->pool = (struct irep_pool*)codegen_realloc(s, irep->pool, sizeof(struct irep_pool)*irep->plen);
+ irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
+ irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
if (s->filename) {
s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
mrb_debug_info_append_file(mrb, s->irep, s->debug_start_pos, s->pc);
@@ -2777,9 +2805,8 @@ codedump(mrb_state *mrb, mrb_irep *irep)
break;
case OP_STRING:
{
- mrb_value s = irep->pool[GETARG_Bx(c)];
-
- s = mrb_str_dump(mrb, s);
+ struct irep_pool *pv = &irep->pool[GETARG_Bx(c)];
+ mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, pv->value.s->buf, pv->value.s->len));
printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s));
}
break;
diff --git a/src/dump.c b/src/dump.c
index 65b60b17c..2c9e85302 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -79,20 +79,19 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
int ai = mrb_gc_arena_save(mrb);
- switch (mrb_type(irep->pool[pool_no])) {
+ switch (irep->pool[pool_no].type) {
case MRB_TT_FIXNUM:
- str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+ str = mrb_fixnum_to_str(mrb, mrb_fixnum_value(irep->pool[pool_no].value.i), 10);
size += RSTRING_LEN(str);
break;
case MRB_TT_FLOAT:
- len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
+ len = mrb_float_to_str(buf, irep->pool[pool_no].value.f);
size += len;
break;
case MRB_TT_STRING:
- str = mrb_str_to_str(mrb, irep->pool[pool_no]);
- size += RSTRING_LEN(str);
+ size += irep->pool[pool_no].value.s->len;
break;
default:
@@ -120,24 +119,23 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
for (pool_no = 0; pool_no < irep->plen; pool_no++) {
int ai = mrb_gc_arena_save(mrb);
- cur += uint8_to_bin(mrb_type(irep->pool[pool_no]), cur); /* data type */
+ cur += uint8_to_bin(irep->pool[pool_no].type, cur); /* data type */
- switch (mrb_type(irep->pool[pool_no])) {
+ switch (irep->pool[pool_no].type) {
case MRB_TT_FIXNUM:
- str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+ str = mrb_fixnum_to_str(mrb, mrb_fixnum_value(irep->pool[pool_no].value.i), 10);
char_ptr = RSTRING_PTR(str);
len = RSTRING_LEN(str);
break;
case MRB_TT_FLOAT:
- len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no]));
+ len = mrb_float_to_str(char_buf, irep->pool[pool_no].value.f);
char_ptr = &char_buf[0];
break;
case MRB_TT_STRING:
- str = irep->pool[pool_no];
- char_ptr = RSTRING_PTR(str);
- len = RSTRING_LEN(str);
+ char_ptr = irep->pool[pool_no].value.s->buf;
+ len = irep->pool[pool_no].value.s->len;
break;
default:
diff --git a/src/gc.c b/src/gc.c
index e8dce1fdf..866d5bdc8 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -470,31 +470,6 @@ mark_context(mrb_state *mrb, struct mrb_context *c)
}
}
-static size_t
-mark_irep_pool_size(mrb_state *mrb, mrb_irep *irep)
-{
- size_t size = irep->plen;
- size_t i;
-
- for (i=0; i<irep->rlen; i++) {
- size += mark_irep_pool_size(mrb, irep->reps[i]);
- }
- return size;
-}
-
-static void
-mark_irep_pool(mrb_state *mrb, mrb_irep *irep)
-{
- size_t i;
-
- for (i=0; i<irep->plen; i++) {
- mrb_gc_mark_value(mrb, irep->pool[i]);
- }
- for (i=0; i<irep->rlen; i++) {
- mark_irep_pool(mrb, irep->reps[i]);
- }
-}
-
static void
gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
@@ -529,9 +504,6 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
mrb_gc_mark(mrb, (struct RBasic*)p->env);
mrb_gc_mark(mrb, (struct RBasic*)p->target_class);
- if (!MRB_PROC_CFUNC_P(p)) {
- mark_irep_pool(mrb, p->body.irep);
- }
}
break;
@@ -691,7 +663,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
static void
root_scan_phase(mrb_state *mrb)
{
- size_t i, e, j;
+ size_t i, e;
if (!is_minor_gc(mrb)) {
mrb->gray_list = NULL;
@@ -714,19 +686,6 @@ root_scan_phase(mrb_state *mrb)
if (mrb->root_c != mrb->c) {
mark_context(mrb, mrb->c);
}
-
- /* mark irep pool */
- if (mrb->irep) {
- size_t len = mrb->irep_len;
- if (len > mrb->irep_capa) len = mrb->irep_capa;
- for (i=0; i<len; i++) {
- mrb_irep *irep = mrb->irep[i];
- if (!irep) continue;
- for (j=0; j<irep->plen; j++) {
- mrb_gc_mark_value(mrb, irep->pool[j]);
- }
- }
- }
}
static size_t
@@ -799,10 +758,6 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
break;
case MRB_TT_PROC:
- if (!MRB_PROC_CFUNC_P((struct RProc*)obj)) {
- children += mark_irep_pool_size(mrb, ((struct RProc*)obj)->body.irep);
- }
- /* fall through */
case MRB_TT_RANGE:
children+=2;
break;
diff --git a/src/load.c b/src/load.c
index 9a229b8ee..cb698dfe6 100644
--- a/src/load.c
+++ b/src/load.c
@@ -87,7 +87,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) {
return NULL;
}
- irep->pool = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value) * plen);
+ irep->pool = (struct irep_pool*)mrb_malloc(mrb, sizeof(struct irep_pool) * plen);
if (irep->pool == NULL) {
return NULL;
}
@@ -99,21 +99,24 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, uint32_t *len)
src += sizeof(uint16_t);
s = mrb_str_new(mrb, (char *)src, pool_data_len);
src += pool_data_len;
+ irep->pool[i].type = tt;
switch (tt) { //pool data
case MRB_TT_FIXNUM:
- irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
+ irep->pool[i].value.i = mrb_fixnum(mrb_str_to_inum(mrb, s, 10, FALSE));
break;
case MRB_TT_FLOAT:
- irep->pool[i] = mrb_float_value(mrb, mrb_str_to_dbl(mrb, s, FALSE));
+ irep->pool[i].value.f = mrb_str_to_dbl(mrb, s, FALSE);
break;
case MRB_TT_STRING:
- irep->pool[i] = s;
+ irep->pool[i].value.s = (struct irep_pool_string*)mrb_malloc(mrb, sizeof(struct irep_pool_string) + pool_data_len);
+ irep->pool[i].value.s->len = pool_data_len;
+ memcpy(irep->pool[i].value.s->buf, src-pool_data_len, pool_data_len);
break;
default:
- irep->pool[i] = mrb_nil_value();
+ /* should not happen */
break;
}
irep->plen++;
diff --git a/src/state.c b/src/state.c
index 1ea76a107..77e45ba8f 100644
--- a/src/state.c
+++ b/src/state.c
@@ -109,8 +109,14 @@ void mrb_free_heap(mrb_state *mrb);
void
mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
{
+ size_t i;
+
if (!(irep->flags & MRB_ISEQ_NO_FREE))
mrb_free(mrb, irep->iseq);
+ for (i=0; i<irep->plen; i++) {
+ if (irep->pool[i].type == MRB_TT_STRING)
+ mrb_free(mrb, irep->pool[i].value.s);
+ }
mrb_free(mrb, irep->pool);
mrb_free(mrb, irep->syms);
mrb_free(mrb, (void *)irep->filename);
diff --git a/src/string.c b/src/string.c
index 90852943e..af70e8e45 100644
--- a/src/string.c
+++ b/src/string.c
@@ -332,34 +332,6 @@ str_make_shared(mrb_state *mrb, struct RString *s)
}
/*
- * call-seq: (Caution! string literal)
- * String.new(str="") => new_str
- *
- * Returns a new string object containing a copy of <i>str</i>.
- */
-
-mrb_value
-mrb_str_literal(mrb_state *mrb, mrb_value str)
-{
- struct RString *s, *orig;
- mrb_shared_string *shared;
-
- s = mrb_obj_alloc_string(mrb);
- orig = mrb_str_ptr(str);
- if (!(orig->flags & MRB_STR_SHARED)) {
- str_make_shared(mrb, orig);
- }
- shared = orig->aux.shared;
- shared->refcnt++;
- s->ptr = shared->ptr;
- s->len = shared->len;
- s->aux.shared = shared;
- s->flags |= MRB_STR_SHARED;
-
- return mrb_obj_value(s);
-}
-
-/*
* call-seq:
* char* str = String("abcd"), len=strlen("abcd")
*
diff --git a/src/vm.c b/src/vm.c
index be3518e8d..92836bf7a 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -552,7 +552,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
/* mrb_assert(mrb_proc_cfunc_p(proc)) */
mrb_irep *irep = proc->body.irep;
mrb_code *pc = irep->iseq;
- mrb_value *pool = irep->pool;
+ struct irep_pool *pool = irep->pool;
mrb_sym *syms = irep->syms;
mrb_value *regs = NULL;
mrb_code i;
@@ -616,7 +616,10 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
CASE(OP_LOADL) {
/* A Bx R(A) := Pool(Bx) */
- regs[GETARG_A(i)] = pool[GETARG_Bx(i)];
+ if (pool[GETARG_Bx(i)].type == MRB_TT_FLOAT)
+ SET_FLT_VALUE(mrb, regs[GETARG_A(i)], pool[GETARG_Bx(i)].value.f);
+ else
+ SET_INT_VALUE(regs[GETARG_A(i)], pool[GETARG_Bx(i)].value.i);
NEXT;
}
@@ -1934,7 +1937,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
CASE(OP_STRING) {
/* A Bx R(A) := str_new(Lit(Bx)) */
- regs[GETARG_A(i)] = mrb_str_literal(mrb, pool[GETARG_Bx(i)]);
+ regs[GETARG_A(i)] = mrb_str_new(mrb, pool[GETARG_Bx(i)].value.s->buf, pool[GETARG_Bx(i)].value.s->len);
mrb_gc_arena_restore(mrb, ai);
NEXT;
}
@@ -2129,7 +2132,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
CASE(OP_ERR) {
/* Bx raise RuntimeError with message Lit(Bx) */
- mrb_value msg = pool[GETARG_Bx(i)];
+ mrb_value msg = mrb_str_new(mrb, pool[GETARG_Bx(i)].value.s->buf, pool[GETARG_Bx(i)].value.s->len);
mrb_value exc;
if (GETARG_A(i) == 0) {