Project

General

Profile

Actions

Feature #21966

closed

Remove rb_obj_class runtime check on rb_define_alloc_func returned objects

Feature #21966: Remove rb_obj_class runtime check on rb_define_alloc_func returned objects
2

Added by jhawthorn (John Hawthorn) 2 days ago. Updated 1 day ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:125140]

Description

I want to remove the following runtime check in class_call_alloc_func, replacing it with a RUBY_ASSERT (so we would still have the check, but only on a debug build).

if (rb_obj_class(obj) != rb_class_real(klass)) {
    rb_raise(rb_eTypeError, "wrong instance allocation");
}

This checks that the value returned from the function registered with rb_define_alloc_func is of the correct class. When this was first introduced in 1fe40b7cc5 (by Matz on 2001-10-03), allocation was done via user-defined Object#allocate, so it made sense to have a runtime check in release builds. Now that it's defined via rb_define_alloc_func in the C extension API, I don't think it's necessary.

The check is surprisingly expensive. Removing it makes Object.new about 10% faster. It allows the C compiler to optimize the call to the function pointer as a tail-call. Removing this also allows ZJIT/YJIT to call the function directly (ZJIT already does this by having a list of known safe allocation functions). The diff in the assembly from skipping this is substantial https://gist.github.com/jhawthorn/20834b654bec4ba0bafee729592d5156 (though much of that is rb_class_real which I also have plans to improve).

There's no way for users to ever have seen this check, other than by writing a misbehaving C extension, which returns objects with the wrong class.

https://github.com/ruby/ruby/pull/16571

I don't think this should be controversial, but I'm filing a feature to make sure it has visibility. If anyone has concerns I'll revert the change and discuss here.

Actions

Also available in: PDF Atom