Skip to content

Warn unless T_DATA object classes redefine or undefine the alloc function#4604

Merged
nobu merged 2 commits intoruby:masterfrom
flavorjones:flavorjones-extension-checks
Aug 19, 2021
Merged

Warn unless T_DATA object classes redefine or undefine the alloc function#4604
nobu merged 2 commits intoruby:masterfrom
flavorjones:flavorjones-extension-checks

Conversation

@flavorjones
Copy link
Copy Markdown
Contributor

@flavorjones flavorjones commented Jun 25, 2021

Backlink to https://bugs.ruby-lang.org/issues/18007

Problem being solved

This option is intended to help developers of C extensions to check if their code meets the requirements explained in "doc/extension.rdoc". Specifically, I want to ensure that T_DATA object classes undefine or redefine the alloc function.

There is currently no easy way for an author of a C extension to easily see where they have made the mistake of letting the class's default alloc function remain.

Description of the solution

Ruby will undefine the alloc func when a T_DATA object is created whose class has not undefined or redefined the alloc function.

A new function is defined, rb_data_object_check. That function is called from rb_data_object_wrap() and rb_data_typed_object_wrap() (which implement the Data_Wrap_Struct family of macros).

An optional warning can be enabled which, when emitted, looks like this:

warning: undefining the allocator of T_DATA class Nokogiri::XML::RelaxNG

Examples of this problem in the wild

Using this code, I found that many of Nokogiri's classes needed to undefine their alloc funcs.

This PR also updates these core Ruby classes by undefining their alloc func:

  • ObjectSpace::InternalObjectWrapper
  • Socket::Ifaddr

Questions for reviewers

Should this warning be emitted with the deprecated category?

Benchmarking

I benchmarked this code by allocating Nokogiri::XML::NodeSets in a loop. This is a class with a relatively simple alloc function.

The runs cover the four combinations of enabled/disabled, and warnings/no-warnings.

ruby 3.1.0dev (2021-06-25T04:02:18Z flavorjones-extens.. de943189aa) [x86_64-linux]
Warming up --------------------------------------
disabled, warn=false   490.143k i/100ms
Calculating -------------------------------------
disabled, warn=false      4.863M (± 1.5%) i/s -     49.014M in  10.081177s

ruby 3.1.0dev (2021-06-25T04:02:18Z flavorjones-extens.. de943189aa) [x86_64-linux]
Warming up --------------------------------------
 disabled, warn=true   483.070k i/100ms
Calculating -------------------------------------
 disabled, warn=true      4.839M (± 1.4%) i/s -     48.790M in  10.083899s

Comparison:
disabled, warn=false:  4863064.0 i/s
 disabled, warn=true:  4839310.1 i/s - same-ish: difference falls within error


ruby 3.1.0dev (2021-06-25T04:02:18Z flavorjones-extens.. de943189aa) [x86_64-linux]
Warming up --------------------------------------
 enabled, warn=false   484.398k i/100ms
Calculating -------------------------------------
 enabled, warn=false      4.840M (± 1.9%) i/s -     48.440M in  10.011854s

Comparison:
disabled, warn=false:  4863064.0 i/s
 enabled, warn=false:  4840123.2 i/s - same-ish: difference falls within error
 disabled, warn=true:  4839310.1 i/s - same-ish: difference falls within error


ruby 3.1.0dev (2021-06-25T04:02:18Z flavorjones-extens.. de943189aa) [x86_64-linux]
Warming up --------------------------------------
  enabled, warn=true   492.200k i/100ms
Calculating -------------------------------------
  enabled, warn=true      4.866M (± 2.1%) i/s -     48.728M in  10.017455s

Comparison:
  enabled, warn=true:  4866434.8 i/s
disabled, warn=false:  4863064.0 i/s - same-ish: difference falls within error
 enabled, warn=false:  4840123.2 i/s - same-ish: difference falls within error
 disabled, warn=true:  4839310.1 i/s - same-ish: difference falls within error

@flavorjones
Copy link
Copy Markdown
Contributor Author

Backlink to https://bugs.ruby-lang.org/issues/18007

@flavorjones flavorjones force-pushed the flavorjones-extension-checks branch from 43475f2 to 5728e5f Compare June 25, 2021 13:44
@flavorjones flavorjones changed the title Added --enable-extension-checks configuration option Warn unless T_DATA object classes redefine or undefine allocate Jun 25, 2021
@flavorjones
Copy link
Copy Markdown
Contributor Author

Updated in response to Nobu's feedback at https://bugs.ruby-lang.org/issues/18007#note-1

@flavorjones flavorjones force-pushed the flavorjones-extension-checks branch from 5728e5f to f9e6e92 Compare July 11, 2021 17:30
@flavorjones
Copy link
Copy Markdown
Contributor Author

@nobu I've made the requested change, squashed and rebased. Thank you again for your time.

@ioquatix
Copy link
Copy Markdown
Member

Great!

@flavorjones flavorjones force-pushed the flavorjones-extension-checks branch from f9e6e92 to 22de9b0 Compare August 17, 2021 14:58
@flavorjones
Copy link
Copy Markdown
Contributor Author

I've rebased onto master.

@flavorjones flavorjones force-pushed the flavorjones-extension-checks branch 2 times, most recently from e2853e9 to 15338e7 Compare August 19, 2021 13:53
which have not undefined or redefined it.

When a `T_DATA` object is created whose class has not undefined or
redefined the alloc function, the alloc function now gets undefined by
Data_Wrap_Struct et al. Optionally, a future release may also warn
that this being done.

This should help developers of C extensions to meet the requirements
explained in "doc/extension.rdoc". Without a check like this, there is
no easy way for an author of a C extension to see where they have made
a mistake.
@flavorjones flavorjones force-pushed the flavorjones-extension-checks branch from 15338e7 to e50d558 Compare August 19, 2021 17:31
@flavorjones flavorjones changed the title Warn unless T_DATA object classes redefine or undefine allocate Warn unless T_DATA object classes redefine or undefine the alloc function Aug 19, 2021
per guidance in doc/extension.rdoc, these classes now undefine their
alloc functions:

- ObjectSpace::InternalObjectWrapper
- Socket::Ifaddr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants