Feature #6993


Class#allocate の仕様変更(Cレベル)

Added by ko1 (Koichi Sasada) over 9 years ago. Updated over 9 years ago.

Target version:



 現在,Class#new を呼び出すと,Class#allocate が呼ばれます.Class#allocate は,次のような特徴を持つ,ちょっと特殊なメソッドになっています.

  • 普通に定義しても Class#new からは使われない
  • 実際に動かす処理 func は rb_define_alloc_func(klass, func) として登録する
  • func は ID_ALLOCATOR という特殊なメソッド名で登録される(対応するシンボル名はなし,つまり rb_id2name(ID_ALLOCATOR) は NULL を返す
  • func は rb_funcall(klass, ID_ALLOCATOR, ...) で呼ばれる

これは,変な allocator を定義出来ないようにするための処置だったと思います(多分).


  • backtrace には現れない
  • set_trace_func ではスキップする

という特殊な処理をしており,Ruby からは見えないようになっています.ただし,set_trace_func には現れませんが,C で trace_func を登録すると呼べてしまう,という中途半端な感じになっています.

これについて,中田さんと協議したんですが,そもそも allocator function はメソッド呼び出し(rb_funcall)で呼ばないでもいいんでないか,という結論を得ました.具体的には,rb_classext_t に allocator function を登録するようにして,それを呼び出す,ということになります.

あり得る問題点としては,allocator function から super が出来ない,という話がありました.ただし,そんなことやる奴はいないだろう,ということで allocator function の制限とするのがいいのではないか,という議論になりました.

副次的な効果として,allocator function のためにメソッドフレームを積む必要がなくなり,ユーザ定義クラスの生成が若干速くなる,ということがあります.

なお,もう一方の選択肢としては,allocator function を backtrace や set_trace_func などで特別扱いしない,というものがありましたが,今まで見えなかったものが見えると互換性的にまずいかもしれない,という話がありました.



Updated by ko1 (Koichi Sasada) over 9 years ago

  • Description updated (diff)

Class#allocate の特徴をちょっと追記.

Actions #2

Updated by nobu (Nobuyoshi Nakada) over 9 years ago

  • Tracker changed from Bug to Feature
Actions #3

Updated by nobu (Nobuyoshi Nakada) over 9 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r36925.
Koichi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

internal.h: allocator function in rb_classext_t

  • internal.h (struct rb_classext_struct): move allocator function into
    rb_classext_t from ordinary method table. [ruby-dev:46121]
    [Feature #6993]
  • object.c (rb_obj_alloc): call allocator function directly.
  • vm_method.c (rb_define_alloc_func, rb_undef_alloc_func)
    (rb_get_alloc_func): use allocator function in rb_classext_t.

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Closed to Assigned


[ruby-core:49119] で Roger Pack が「ID_ALLOCATOR がなくなったせいで拡張ライブラリ (ruby-prof) がビルドできなくなった」と報告してます。
#define ID_ALLOCATOR 0 を追加するだけで直ります? それとも他に (拡張ライブラリから見える) 挙動に変更があります?

Yusuke Endoh

Updated by mame (Yusuke Endoh) over 9 years ago

  • Status changed from Assigned to Closed

Class#allocate は C レベルの set_trace_func でもフックできなくなったという非互換があります、
ということで preview2 を出してみて、文句が来たら reopen して考えましょう。

Yusuke Endoh

Updated by agrimm (Andrew Grimm) over 9 years ago

(Preview 2 is also bad)

$ gem install ruby-prof
Building native extensions.  This could take a while...
ERROR:  Error installing ruby-prof:
	ERROR: Failed to build gem native extension.

        /Users/agrimm/.rvm/rubies/ruby-head/bin/ruby extconf.rb
checking for sys/times.h... yes
checking for rb_os_allocated_objects()... no
checking for rb_gc_allocated_size()... no
checking for rb_gc_collections()... no
checking for rb_gc_time()... no
checking for rb_class_superclass()... yes
checking for rb_heap_total_mem()... no
checking for rb_gc_heap_info()... no
creating Makefile

compiling rp_call_info.c
compiling rp_measure.c
compiling rp_measure_allocations.c
compiling rp_measure_cpu_time.c
compiling rp_measure_gc_runs.c
compiling rp_measure_gc_time.c
compiling rp_measure_memory.c
compiling rp_measure_process_time.c
compiling rp_measure_wall_time.c
compiling rp_method.c
rp_method.c: In function ‘method_name’:
rp_method.c:101: error: ‘ID_ALLOCATOR’ undeclared (first use in this function)
rp_method.c:101: error: (Each undeclared identifier is reported only once
rp_method.c:101: error: for each function it appears in.)
make: *** [rp_method.o] Error 1

Gem files will remain installed in /Users/agrimm/.rvm/gems/ruby-head/gems/ruby-prof-0.11.2 for inspection.
Results logged to /Users/agrimm/.rvm/gems/ruby-head/gems/ruby-prof-0.11.2/ext/ruby_prof/gem_make.out
$ ruby --version
ruby 2.0.0dev (2012-12-12) [x86_64-darwin10.8.0]

Mame-san, were you saying "if it doesn't work on preview2, please re-open the issue"? Apologies for re-opening if I misunderstood you.

Updated by nobu (Nobuyoshi Nakada) over 9 years ago

You can just wrap the lines with #ifdef ID_ALLOCATOR, I guess.

Updated by mame (Yusuke Endoh) over 9 years ago

@agrimm (Andrew Grimm): Thank you for the reporting!

My understanding is that this issue will be fixed in the ruby-prof side.
So, currently, we plan to include this incompatibility "as is" in Ruby 2.0.0.
But, if the impact is bigger than we expect (i.e., if this affects other existing code except ruby-prof), we may revert this.

Note that we can NOT fix this incompatibility just by restoring the ID_ALLOCATOR macro definition.
As far as I know, this is a side effect of the improvement of class allocation.
But sorry, I don't understand the improvement itself in depth.

Yusuke Endoh


Also available in: Atom PDF