summaryrefslogtreecommitdiff
path: root/marshal.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-01 20:29:46 (GMT)
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-01 20:29:46 (GMT)
commita17ffebfa0bff3c8843ef15b18020d8bd0662f4c (patch)
treec360c103af4a8cbef82db1a0a6fcbc6a38c5f370 /marshal.c
parent3b841719c9c4f31f9f36f65750f3bf714b978fe9 (diff)
marshal.c: lazy compat_tbl allocation
In some common cases, compat_tbl is unused in dump_arg/load_arg, so avoid malloc/free costs for the unused table. ruby -e 'h = {a: :b}; 600000.times { Marshal.load(Marshal.dump(h)) }' before: real 0m2.458s user 0m2.450s sys 0m0.006s after: real 0m2.122s user 0m2.110s sys 0m0.011s * marshal.c (w_class): check dump_arg->compat_tbl before lookup (w_object): lazy init ->compat_tbl before insert (obj_alloc_by_class): ditto (clear_dump_arg): free only non-NULL ->compat_tbl (clear_load_arg): ditto for ->compat_tbl (marshal_dump): ->compat_tbl defaults to zero (marshal_load): ditto for ->compat_tbl (r_entry0): check l->compat_tbl before lookup (r_fixup_compat): ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'marshal.c')
-rw-r--r--marshal.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/marshal.c b/marshal.c
index 8e197c7..acd962e 100644
--- a/marshal.c
+++ b/marshal.c
@@ -495,7 +495,8 @@ w_class(char type, VALUE obj, struct dump_arg *arg, int check)
st_data_t real_obj;
VALUE klass;
- if (st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
+ if (arg->compat_tbl &&
+ st_lookup(arg->compat_tbl, (st_data_t)obj, &real_obj)) {
obj = (VALUE)real_obj;
}
klass = CLASS_OF(obj);
@@ -738,6 +739,9 @@ w_object(VALUE obj, struct dump_arg *arg, int limit)
marshal_compat_t *compat = (marshal_compat_t*)compat_data;
VALUE real_obj = obj;
obj = compat->dumper(real_obj);
+ if (!arg->compat_tbl) {
+ arg->compat_tbl = st_init_numtable();
+ }
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
if (obj != real_obj && !ivtbl) hasiv = 0;
}
@@ -911,8 +915,10 @@ clear_dump_arg(struct dump_arg *arg)
arg->symbols = 0;
st_free_table(arg->data);
arg->data = 0;
- st_free_table(arg->compat_tbl);
- arg->compat_tbl = 0;
+ if (arg->compat_tbl) {
+ st_free_table(arg->compat_tbl);
+ arg->compat_tbl = 0;
+ }
if (arg->encodings) {
st_free_table(arg->encodings);
arg->encodings = 0;
@@ -985,7 +991,7 @@ marshal_dump(int argc, VALUE *argv)
arg->symbols = st_init_numtable();
arg->data = st_init_numtable();
arg->infection = 0;
- arg->compat_tbl = st_init_numtable();
+ arg->compat_tbl = 0;
arg->encodings = 0;
arg->str = rb_str_buf_new(0);
if (!NIL_P(port)) {
@@ -1365,7 +1371,7 @@ static VALUE
r_entry0(VALUE v, st_index_t num, struct load_arg *arg)
{
st_data_t real_obj = (VALUE)Qundef;
- if (st_lookup(arg->compat_tbl, v, &real_obj)) {
+ if (arg->compat_tbl && st_lookup(arg->compat_tbl, v, &real_obj)) {
st_insert(arg->data, num, (st_data_t)real_obj);
}
else {
@@ -1384,7 +1390,7 @@ static VALUE
r_fixup_compat(VALUE v, struct load_arg *arg)
{
st_data_t data;
- if (st_lookup(arg->compat_tbl, v, &data)) {
+ if (arg->compat_tbl && st_lookup(arg->compat_tbl, v, &data)) {
VALUE real_obj = (VALUE)data;
rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj));
st_data_t key = v;
@@ -1490,6 +1496,10 @@ obj_alloc_by_klass(VALUE klass, struct load_arg *arg, VALUE *oldclass)
VALUE real_obj = rb_obj_alloc(klass);
VALUE obj = rb_obj_alloc(compat->oldclass);
if (oldclass) *oldclass = compat->oldclass;
+
+ if (!arg->compat_tbl) {
+ arg->compat_tbl = st_init_numtable();
+ }
st_insert(arg->compat_tbl, (st_data_t)obj, (st_data_t)real_obj);
return obj;
}
@@ -1950,8 +1960,10 @@ clear_load_arg(struct load_arg *arg)
arg->symbols = 0;
st_free_table(arg->data);
arg->data = 0;
- st_free_table(arg->compat_tbl);
- arg->compat_tbl = 0;
+ if (arg->compat_tbl) {
+ st_free_table(arg->compat_tbl);
+ arg->compat_tbl = 0;
+ }
}
/*
@@ -1996,7 +2008,7 @@ marshal_load(int argc, VALUE *argv)
arg->offset = 0;
arg->symbols = st_init_numtable();
arg->data = st_init_numtable();
- arg->compat_tbl = st_init_numtable();
+ arg->compat_tbl = 0;
arg->proc = 0;
arg->readable = 0;