From 677a2ac22633473fb286d7297a8585c01fe7394b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 7 Nov 2013 04:20:46 +0900 Subject: irep->pool not to be GCed --- src/codegen.c | 61 ++++++++++++++++++++++++++++++++++++++++++----------------- src/dump.c | 22 ++++++++++----------- src/gc.c | 47 +-------------------------------------------- src/load.c | 13 ++++++++----- src/state.c | 6 ++++++ src/string.c | 28 --------------------------- src/vm.c | 11 +++++++---- 7 files changed, 76 insertions(+), 112 deletions(-) (limited to 'src') 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; iirep->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; iirep->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; iirep->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; irlen; 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; iplen; i++) { - mrb_gc_mark_value(mrb, irep->pool[i]); - } - for (i=0; irlen; 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; iirep[i]; - if (!irep) continue; - for (j=0; jplen; 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; iplen; 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 @@ -331,34 +331,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 str. - */ - -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) { -- cgit v1.2.3