aboutsummaryrefslogtreecommitdiffstats
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-30 09:33:08 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-30 09:33:08 +0000
commitb872ad5861ffc6585063bb9f045b825278fbc842 (patch)
tree73d72b65614de7f731123bf8b1cff27010a46f68 /gc.c
parent0445b5f6c69e92497e8bab12474699ef545434f1 (diff)
downloadruby-b872ad5861ffc6585063bb9f045b825278fbc842.tar.gz
* gc.c (newobj_slowpath): reduce 1 parameter to use only registers
for performance. On my laptop, 'N.times{x = []}' (where N = 29_000_000) is 1.86 sec -> 1.74 sec. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52389 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/gc.c b/gc.c
index 9ef65192f4..f9ac21573e 100644
--- a/gc.c
+++ b/gc.c
@@ -1787,10 +1787,8 @@ newobj_init(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_prote
return obj;
}
-NOINLINE(static VALUE newobj_slowpath(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, rb_objspace_t *objspace));
-
-static VALUE
-newobj_slowpath(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected, rb_objspace_t *objspace)
+static inline VALUE
+newobj_slowpath(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace, int wb_protected)
{
VALUE obj;
@@ -1809,11 +1807,26 @@ newobj_slowpath(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_p
}
obj = heap_get_freeobj(objspace, heap_eden);
- newobj_init(klass, flags, v1, v2, v3, wb_protected, objspace, obj);
+ newobj_init(klass, (flags & ~FL_WB_PROTECTED), v1, v2, v3, (flags & FL_WB_PROTECTED) ? TRUE : FALSE, objspace, obj);
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_NEWOBJ, obj);
return obj;
}
+NOINLINE(static VALUE newobj_slowpath_wb_protected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace));
+NOINLINE(static VALUE newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace));
+
+static VALUE
+newobj_slowpath_wb_protected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace)
+{
+ return newobj_slowpath(klass, flags, v1, v2, v3, objspace, TRUE);
+}
+
+static VALUE
+newobj_slowpath_wb_unprotected(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, rb_objspace_t *objspace)
+{
+ return newobj_slowpath(klass, flags, v1, v2, v3, objspace, FALSE);
+}
+
static inline VALUE
newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protected)
{
@@ -1829,24 +1842,20 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3, int wb_protect
}
}
#endif
- if (LIKELY(!(during_gc ||
- ruby_gc_stressful ||
- gc_event_hook_available_p(objspace)) &&
- (obj = heap_get_freeobj_head(objspace, heap_eden)) != Qfalse)) {
+ if (!(during_gc ||
+ ruby_gc_stressful ||
+ gc_event_hook_available_p(objspace)) &&
+ (obj = heap_get_freeobj_head(objspace, heap_eden)) != Qfalse) {
return newobj_init(klass, flags, v1, v2, v3, wb_protected, objspace, obj);
}
else {
- return newobj_slowpath(klass, flags, v1, v2, v3, wb_protected, objspace);
+ return wb_protected ?
+ newobj_slowpath_wb_protected(klass, flags, v1, v2, v3, objspace) :
+ newobj_slowpath_wb_unprotected(klass, flags, v1, v2, v3, objspace);
}
}
VALUE
-rb_newobj(void)
-{
- return newobj_of(0, T_NONE, 0, 0, 0, FALSE);
-}
-
-VALUE
rb_wb_unprotected_newobj_of(VALUE klass, VALUE flags)
{
if (RGENGC_CHECK_MODE > 0) assert((flags & FL_WB_PROTECTED) == 0);
@@ -1860,6 +1869,14 @@ rb_wb_protected_newobj_of(VALUE klass, VALUE flags)
return newobj_of(klass, flags, 0, 0, 0, TRUE);
}
+/* for compatibility */
+
+VALUE
+rb_newobj(void)
+{
+ return newobj_of(0, T_NONE, 0, 0, 0, FALSE);
+}
+
VALUE
rb_newobj_of(VALUE klass, VALUE flags)
{