[gambit-list] (##resolve-referencing-objects obj) => list of the objects that reference obj implementation, feedback welcome.

Mikael mikael.rcv at gmail.com
Sat Jun 22 18:11:18 EDT 2013


Update:

2013/6/20 Mikael <mikael.rcv at gmail.com>

>
>
> 2013/6/20 Marc Feeley <feeley at iro.umontreal.ca>
>
>> I will study your implementation soon.  I do have a few comments at this
>> point:
>>
>> 1) It would be nice if there was more information in the resulting list
>> when the reference is not in an object.  For example a string which names
>> the global variable which references the object, a fixnum giving the number
>> of the register which references the object, etc).
>>
>
> Yeah!
>

Following your suggestion above I made so that instead of non-object
references leading to #!unbound , they lead to one of the following symbols:

'register:current-thread
'register:run-queue
'register:gvm-registers
'register:symbol-table
'register:keyword-table
'will-list:nonexecutable
'will-list:executable
'continuation
'rc


..and global variables lead to their name, as a symbol.

And added a variable so that the search is done only
during |##resolve-referencing-objects| and the code path is disabled
otherwise.

And last, made |##resolve-referencing-objects| return a plain list again as
I found a way to do reference graph probing without using weak references.

Example use:

$ gsc
Gambit v4.6.9

> (define a "Hi")
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers a)
> (##resolve-referencing-objects (current-thread))
(register:current-thread
 register:gvm-registers
 register:gvm-registers
 #<thread #1 primordial>
 #<thread #1 primordial>
 #<run-queue #2>
 #<run-queue #2>
 #<run-queue #2>
 #<repl-channel-ports #3>
 #<thread-group #4 primordial>
 #<thread-group #4 primordial>)
> (load "dig-out-gc-roots-graph.scm")
> (define a "Hi")
> (define b (list a a))
> (define c (vector b b))
> (dig-out-gc-roots-graph a)
Digging out the GC roots for object #2...

References to object #2:
#2
  #3 (In work queue)
  #4 (In work queue)
  continuation
  ~#a

References to object #2:
#2
  #3 (In work queue)
  #4
    #5 (In work queue)
    #5 (In work queue)
    ~#b
  continuation
  ~#a

References to object #2:
#2
  #3
    #4 (In work queue)
  #4
    #5 (In work queue)
    #5 (In work queue)
    ~#b
  continuation
  ~#a

References to object #2:
#2
  #3
    #4 (In work queue)
  #4
    #5 (In work queue)
    #5
      ~#c
    ~#b
  continuation
  ~#a

References to object #2:
#2
  #3
    #4 (In work queue)
  #4
    #5 (This object was already found at a lower depth in the graph.)
    #5
      ~#c
    ~#b
  continuation
  ~#a

References to object #2:
#2
  #3
    #4 (This object was already found at a lower depth in the graph.)
  #4
    #5 (This object was already found at a lower depth in the graph.)
    #5
      ~#c
    ~#b
  continuation
  ~#a

Done!
All the objects that refer to this object in total (+ the object itself)
are: #2 #4 #5 #3
All the objects that refer to this object closest to the root in total are:
#5
>


An interesting oddity, that I don't see any reason for but that doesn't
hurt is that references from wills generally is returned as
'will-list:nonexecutable but sometimes as the will object itself - this is
only for wills that don't have an active reference from anywhere, such as
from a global:

> (import lib/track_leaks)
> (define a "Hi")
> (make-will a (lambda (v) (void)))
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a #<will #3>)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a #<will #3>)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a #<will #3>)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a #<will #3>)
> 1
1
> 2
2
> 3
3
> 4
4
> (##gc)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a #<will #3>)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)
> (##resolve-referencing-objects a)
(register:gvm-registers register:gvm-registers ~#a will-list:nonexecutable)



Compilation is per the previous email.

I did not include any limiting mechanism on number of max references
resolved by ##resolve-referencing-objects , as such usecases are extremely
rare anyhow - I mean, how many objects did you ever have so many references
to that ##resolve-referencing-objects 's response would occupy tens of
megabytes?


Spontaneously this appears stable to me, and thus could be something to
commit to the Gambit repo now.

Marc would probably have some suggestions for making the code better and
more conformant to Gambit's general code style.



Best regards,
Mikael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130623/2945de63/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mem.c
Type: text/x-csrc
Size: 129689 bytes
Desc: not available
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130623/2945de63/attachment.c>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mem.h
Type: text/x-chdr
Size: 3903 bytes
Desc: not available
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130623/2945de63/attachment.h>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: _kernel.scm
Type: application/octet-stream
Size: 123448 bytes
Desc: not available
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130623/2945de63/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dig-out-gc-roots-graph.scm
Type: application/octet-stream
Size: 10156 bytes
Desc: not available
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130623/2945de63/attachment-0001.obj>


More information about the Gambit-list mailing list