Collect info about ruby-api

Dnia czw 26. czerwca 2003 22:18, Simon Strandgaard napisa³:

I just don’t understand the purpose+goal with Init_stack.

Init_stack tells the Ruby interpreter where the portion of the stack which may
contain pointers to Ruby objects begins.

···


__("< Marcin Kowalczyk
__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/

If I understand you correct, then its a sort of watermark mecanism, where
you can take a snapshot of the current state and restore it later ?

Is it usable for rubyists whom is doing extensions/embedding ?

I think I need to see more examples of its usage before I understand.

···

On Thu, 26 Jun 2003 01:26:41 +0900, Mauricio Fernández wrote:

On Wed, Jun 25, 2003 at 11:43:34PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 23:48:00 +0900, Mauricio Fernández wrote:

On Wed, Jun 25, 2003 at 10:21:37PM +0900, Simon Strandgaard wrote:

On Wed, 25 Jun 2003 22:57:53 +0900, nobu.nokad wrote:

#3 Init_stack(address)
tell GC the machine stack limit.

I never heard about this before, what does it do ?
Can you give me a more lengthy description of it :slight_smile:

The GC of Ruby is conservative: it will scan the stack to find VALUEs.
This means at any moment it can take the stack pointer and scan from
there to the beginning of the stack. Init_stack takes the address of one
local variable (in the stack) and records it as the bottom of the stack
(highest address in x86).

Sorry I don’t understand Nobu’s reason to added Init_stack as number 3rd
item in the list of possible ways to register an instance.

Is Init_stack really a 3rd possiblitity to do registring ?

It doesn’t register one specific instance, but sets the top of the stack
(which will be scanned afterwards) so that the value can be found later.

You have to call this (directly or via another function) at the
beginning of your program.

Some references:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66013
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66025


Simon Strandgaard

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

Can you post the whole program, then I will see what I can do ?

Try commenting out the line marked by <===== below.

Ok… I also commented out Init_stack() because I don’t know what it does.
This code works… I have no segfaults ?

expand -t2 main.c
#include <ruby.h>

int main(int Argc, char **Argv) {
int argc;
VALUE argv[2];
VALUE klass;
VALUE instance;

ruby_init();
//Init_stack(&argc); // tell GC the machine stack limit.

argv[0] = INT2FIX(5);
argc = 2;
klass = rb_path2class(“Array”);
argv[1] = rb_str_new2(“hello”);
instance = rb_class_new_instance(argc, argv, klass);
rb_p(instance);

// Uncommenting the next line will cause the program to crash
klass = rb_const_get(rb_cObject, rb_intern(“Array”)); //<=====
argv[1] = rb_str_new2(“world”);
instance= rb_funcall2(klass, rb_intern(“new”), argc, argv);

//No need, see [ruby-talk 74400]
//rb_gc_register_address(&instance);

rb_p(instance);
ruby_finalize();
return 0;
}

./a.out
[“hello”, “hello”, “hello”, “hello”, “hello”]
[“world”, “world”, “world”, “world”, “world”]

···

On Wed, 25 Jun 2003 20:15:25 +0000, Shashank Date wrote:


Simon Strandgaard

OK, I have been told this many times… What I don’t realize is when to use
it? Why to use it?

Maybe we should try the opposite game: What happens if Init_stack is not
invoked ?

···

On Fri, 27 Jun 2003 09:21:36 +0900, Marcin ‘Qrczak’ Kowalczyk wrote:

Dnia czw 26. czerwca 2003 22:18, Simon Strandgaard napisał:

I just don’t understand the purpose+goal with Init_stack.

Init_stack tells the Ruby interpreter where the portion of the stack which may
contain pointers to Ruby objects begins.


Simon Strandgaard

Is it usable for rubyists whom is doing extensions/embedding ?

embedding

I think I need to see more examples of its usage before I understand.

Look at plruby (but don't expect comment in the source :-)))

Guy Decoux

Some references:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66013
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66025

If I understand you correct, then its a sort of watermark mecanism, where
you can take a snapshot of the current state and restore it later ?

???
It only makes Ruby remember where the stack starts so that it can scan
it later safely (ie. doesn’t try to walk off the memory and die w/ a
segfault or alike).

Is it usable for rubyists whom is doing extensions/embedding ?

You do normally not need it (it’s called by ruby_init). You only have to
be aware of how it works for cases such as the one exposed in
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66022.

If Init_stack is called in a deeper stack frame than the one where some
VALUE resides, Ruby won’t see the later when it scans the stack and the
object will be GCed.

I think I need to see more examples of its usage before I understand.

Check out the links I gave you.

···

On Thu, Jun 26, 2003 at 01:05:10AM +0900, Simon Strandgaard wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

ECRC hat keine lynx komp. seiten, sowas MUSS ja pleite gehen ;-)=
– Getty on #LinuxGER

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

This code works… I have no segfaults ?

Hmm … it only means one thing: the Visual Studio IDE that I am using
is doing something which I do not quite understand. I will have to dig
deeper. Thank you for being so patient.

– shanko

Dnia pi± 27. czerwca 2003 07:42, Simon Strandgaard napisa³:

OK, I have been told this many times… What I don’t realize is when to use
it?

When ruby_init() is called from a function whose local variables point to Ruby
objects.

Maybe we should try the opposite game: What happens if Init_stack is not
invoked ?

The garbage collector may free these objects even though they are needed.

But it’s easier to move the code which accesses Ruby objects to a separate
function.

···


__("< Marcin Kowalczyk
__/ qrczak@knm.org.pl
^^ Blog człowieka poczciwego.

Some references:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66013
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66025

If I understand you correct, then its a sort of watermark mecanism, where
you can take a snapshot of the current state and restore it later ?

???

I don’t understand, so im guessing… as you can see im terrible at it :slight_smile:

It only makes Ruby remember where the stack starts so that it can scan
it later safely (ie. doesn’t try to walk off the memory and die w/ a
segfault or alike).

Maybe I will understand another day… but right now im lost.

Is it usable for rubyists whom is doing extensions/embedding ?

You do normally not need it (it’s called by ruby_init). You only have to
be aware of how it works for cases such as the one exposed in
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/66022.

If Init_stack is called in a deeper stack frame than the one where some
VALUE resides, Ruby won’t see the later when it scans the stack and the
object will be GCed.

Again… I don’t understand… It will perhaps help if I knew in which
situations Init_stack is useful. If you can explain it more verbose, I
would be very happy :slight_smile:

I think I need to see more examples of its usage before I understand.

Check out the links I gave you.

I did… but I don’t know its purpose :slight_smile:

···

On Thu, 26 Jun 2003 02:12:53 +0900, Mauricio Fernández wrote:

On Thu, Jun 26, 2003 at 01:05:10AM +0900, Simon Strandgaard wrote:


Simon Strandgaard

Is it usable for rubyists whom is doing extensions/embedding ?

embedding

I use embedding myself… I am very curios how/if I can use it?

I think I need to see more examples of its usage before I understand.

Look at plruby (but don’t expect comment in the source :-)))

I don’t know what plruby_call_handler() does… but it definitly uses
Init_stack()

int pl_call_level; hmmm, don’t know what this is either.

Any hints ? :slight_smile:

···

On Thu, 26 Jun 2003 02:10:19 +0900, ts wrote:


Simon Strandgaard

If you having trouble with it I suggest you spawn a new thread at this
newsgroup, only about that subject. I find it strange that it works with
G++ and crashes with visual studio.

Just a thought :slight_smile:

···

On Thu, 26 Jun 2003 23:11:14 +0000, Shashank Date wrote:

“Simon Strandgaard” 0bz63fz3m1qt3001@sneakemail.com

This code works… I have no segfaults ?

Hmm … it only means one thing: the Visual Studio IDE that I am using
is doing something which I do not quite understand. I will have to dig
deeper. Thank you for being so patient.


Simon Strandgaard

I don't know what plruby_call_handler() does.. but it definitly uses
Init_stack()

plruby_call_handler() is the entry point for plruby : each time that
postgres need to call a procedural function written in ruby it will call
plruby_call_handler()

int pl_call_level; hmmm, don't know what this is either.

a procedural function written in ruby can call another procedural function
written in ruby : pl_call_level will say if it's the first call or if it's
a "recursive" call.

Any hints ? :slight_smile:

Normally ruby_init() (which call Init_stack()) must be called at the
beginning of the program (postgres in this case) to make sure that ruby
has the right value for the beginning of the stack.

It's not possible (and I don't want) to modify postgres to be sure that
ruby_init() will be called at the right place (in main()). The
consequence is that plruby will call ruby_init() (to initialize ruby) the
first time that a procedural function written in ruby is called.

Now where is the problem : imagine this case (the values for the stack are
just examples)

* The first time that postgres call plruby_call_handler() the value of the
stack is 0xe0000000

  - ruby_init() is called, and ruby will remember that the beginning of
    the stack is 0xe0000000

  - ruby will store VALUE from 0xe0000000 to 0xc0000000 (this is just an
    example)

* Another procedural function is called latter (and this is not a
   "recursive" call) but this time the value for the stack is 0xf0000000
   (i.e. postgres use less stack when it call plruby_call_handler())

  - ruby will store VALUE from 0xf0000000 to 0xd0000000

  - if ruby call the GC, the GC will mark the objects from 0xe0000000
    (beginning of the stack when ruby_init() was called) to 0xd0000000.
    When ruby run the sweep phase, it will remove all objects which are
    stored in 0xf0000000-0xe0000000

  - now after the GC, if plruby try to access objects stored in
    0xf0000000-0xe0000000, it just crash.

* To correct this : each time that plruby_call_handler() is called (and
   this is not a "recursive" call) it call Init_stack() to be sure that
   ruby has the right value for the beginning of the stack when it run the
   GC

Guy Decoux

I don’t know what plruby_call_handler() does… but it definitly uses
Init_stack()

plruby_call_handler() is the entry point for plruby : each time that
postgres need to call a procedural function written in ruby it will call
plruby_call_handler()

int pl_call_level; hmmm, don’t know what this is either.

a procedural function written in ruby can call another procedural function
written in ruby : pl_call_level will say if it’s the first call or if it’s
a “recursive” call.

If its a nested request, then Init_stack will only be invoked once (first
request). If its not a nested request, then Init_stack is executed. OK?

Browsing mod_ruby, I see that Init_stack is invoked within their
library-bootstrap function (ruby_startup). It is not invoked per request.

Why this difference ?

BTW: In VIM/if_ruby.c Init_stack is not used at all!

Any hints ? :slight_smile:

Normally ruby_init() (which call Init_stack()) must be called at the
beginning of the program (postgres in this case) to make sure that ruby
has the right value for the beginning of the stack.

It’s not possible (and I don’t want) to modify postgres to be sure that
ruby_init() will be called at the right place (in main()). The
consequence is that plruby will call ruby_init() (to initialize ruby) the
first time that a procedural function written in ruby is called.

Now where is the problem : imagine this case (the values for the stack are
just examples)

  • The first time that postgres call plruby_call_handler() the value of the
    stack is 0xe0000000
  • ruby_init() is called, and ruby will remember that the beginning of
    the stack is 0xe0000000

  • ruby will store VALUE from 0xe0000000 to 0xc0000000 (this is just an
    example)

  • Another procedural function is called latter (and this is not a
    “recursive” call) but this time the value for the stack is 0xf0000000
    (i.e. postgres use less stack when it call plruby_call_handler())
  • ruby will store VALUE from 0xf0000000 to 0xd0000000

  • if ruby call the GC, the GC will mark the objects from 0xe0000000
    (beginning of the stack when ruby_init() was called) to 0xd0000000.
    When ruby run the sweep phase, it will remove all objects which are
    stored in 0xf0000000-0xe0000000

  • now after the GC, if plruby try to access objects stored in
    0xf0000000-0xe0000000, it just crash.

Yes I see, the objects withing the range 0xf000-0xe000 is un-marked and
will thus be sweept. I agree that trying to access destroyed instances can
cause segfaults.

  • To correct this : each time that plruby_call_handler() is called (and
    this is not a “recursive” call) it call Init_stack() to be sure that
    ruby has the right value for the beginning of the stack when it run the
    GC

Solution to the second request, am I right ???
Init_stack(0xf0000000);

···

On Fri, 27 Jun 2003 18:21:28 +0900, ts wrote:


Simon Strandgaard

If its a nested request, then Init_stack will only be invoked once (first
request). If its not a nested request, then Init_stack is executed. OK?

Yes,

Solution to the second request, am I right ???
Init_stack(0xf0000000);

Yes, it call Init_Stack() with the current value of the beginning of the
stack

Guy Decoux

Wow… Now I know what Init_stack() does, I feel relieved :slight_smile:

Thanks everyone. I agree with you that Init_stack is very important when
one is embedding Ruby into C/C++. This may explain my random segfaults.

I better add a Init_stack() section to my tutorial about embedding Ruby into C++.
http://metaeditor.sf.net/embed/

Thanks again :slight_smile:

···

On Fri, 27 Jun 2003 19:09:41 +0900, ts wrote:

If its a nested request, then Init_stack will only be invoked once (first
request). If its not a nested request, then Init_stack is executed. OK?

Yes,

Solution to the second request, am I right ???
Init_stack(0xf0000000);

Yes, it call Init_Stack() with the current value of the beginning of the
stack


Simon Strandgaard