Re: More Garbage Collection Issues

2005-03-30 Thread Leopold Toetsch
Nick Glencross [EMAIL PROTECTED] wrote:

 Ok, now I understand. This is inspecting the C runtime stack (I think).
 The Interpreter remembers the bottom address, and then when the time
 comes, a routine runs the depth of the stack.

Yes. Exactly.

 The values on the stack are then checked whether they are in the pmc or
 buffer memory ranges.

Yes.

 I guess that there must be automatic variables which haven't been
 explicitly set on the stack(?).

No. The C runtime stack isn't explicitely written to or initialized by
running Parrot, which triggers the bogus valgrind warnings.

See Ftools/dev/parrot.supp and:

$ cat vgp
valgrind --suppressions=tools/dev/parrot.supp --alignment=8 \
   --num-callers=8 ./parrot $@

$ vgp some.imc

 Nick

leo


Re: More Garbage Collection Issues

2005-03-29 Thread Leopold Toetsch
Cory Spencer [EMAIL PROTECTED] wrote:

 I've come across another garbage collection/DOD issue that I'm trying to
 solve (without much success) and would appreciate some tips/advice on how
 to locate the source of the problem.

When I'm investigating GC bugs, the usual procedure is like this:
- run the program with -t with or w/o --gc-debug
  (GC bug sometimes happens earlier, which usually simplifies things)
- check the backtraces
- run it with -t -G
- compare trace outputs (possibly after reducing trace dumps with the
  help of a perl script that deletes DOD/GC messages and maybe
  addresses)
- try to locate which POBj (or parent(s) of it) are involved
- turn on GC_VERBOSE and set the PObj_report_FLAG in involved PMCs
- or put a printf message into destroy vtable functions
- check if parent of too early collected objects are alive and if they
  mark their contents (or refs) properly

Overall: it's a nasty and time consuming job.

 ...  It appears to affectthe String class (in
 my case, a subclass of String).

Does it happen with the plain String PMC too?

 ... Oddly, it appears to only affect strings
 with a length of 1 (ie. a single character - changing the string to a
 longer length does not cause it be be marked as a dead object).

Strange. How are these strings created? Some special cased code?

 I've also noticed similar behaviour when I use a native string type (ie.
 something declared with an IMC .local string str declaration) as a key
 in a Hash table (again, it only appears to happen when the string is a
 single character in length).  Later, when I go back to retrieve the value
 stored in the hash, it can't find it.  (Running an iterator over the keys
 of the Hash shows keys that appears as garbage characters (presumably
 string types that have since been collected).)

Are the strings created dynamically during an eval sequence
(compreg/compile)? String constants or outcome of a string expression?

 I've as of yet been unable to produce a concise, working example.  Any
 tips as to how I can find the source of this bug?

If you can't reduce it, just send a tarball of needed stuff in PM to me.

leo


Re: More Garbage Collection Issues

2005-03-29 Thread Nick Glencross
Leopold Toetsch wrote:
Cory Spencer [EMAIL PROTECTED] wrote:
 

I've come across another garbage collection/DOD issue that I'm trying to
solve (without much success) and would appreciate some tips/advice on how
to locate the source of the problem.
Running valgrind (on supported platforms, obviously) may sometimes work.
The DOD certainly has a few things flagged up, which I'm going to 
quickly investigate to see if they are serious or not...

Nick
e.g.
==914== Conditional jump or move depends on uninitialised value(s)
==914==at 0x80C9700: trace_mem_block (dod.c:1004)
==914==by 0x80CB9D3: trace_system_stack (cpu_dep.c:117)
==914==by 0x80CB9A1: trace_system_areas (cpu_dep.c:98)
==914==by 0x80C8F5A: Parrot_dod_trace_root (dod.c:362)
==914==by 0x80C8FB3: trace_active_PMCs (dod.c:374)
==914==by 0x80C99B9: Parrot_dod_ms_run (dod.c:1198)
==914==by 0x80C9A79: Parrot_do_dod_run (dod.c:1237)
==914==by 0x80C7920: more_traceable_objects (smallobject.c:114)
==914== Conditional jump or move depends on uninitialised value(s)
==914==at 0x80C7846: contained_in_pool (smallobject.c:55)
==914==by 0x80C85CD: is_buffer_ptr (headers.c:517)
==914==by 0x80C970F: trace_mem_block (dod.c:1004)
==914==by 0x80CB9D3: trace_system_stack (cpu_dep.c:117)
==914==by 0x80CB9A1: trace_system_areas (cpu_dep.c:98)
==914==by 0x80C8F5A: Parrot_dod_trace_root (dod.c:362)
==914==by 0x80C8FB3: trace_active_PMCs (dod.c:374)
==914==by 0x80C99B9: Parrot_dod_ms_run (dod.c:1198)
==914==


Re: More Garbage Collection Issues

2005-03-29 Thread Nick Glencross
Nick Glencross wrote:
The DOD certainly has a few things flagged up, which I'm going to 
quickly investigate to see if they are serious or not...
I've learned alot about DOD since earlier (and watched telly). Not as 
straightforward as I thought it would be to find if these traces should 
be considered serious or not (I would say any logic based on unitialised 
values will bite one day!).

I now know a bit more about the system stack/area, but can't quite 
picture what's going on. Sorry I couldn't help more.

Probably unrelated to Cory's gremlin...
Nick


Re: More Garbage Collection Issues

2005-03-29 Thread Nick Glencross
Nick Glencross wrote:
I've learned alot about DOD since earlier (and watched telly). Not as 
straightforward as I thought it would be to find if these traces should 
be considered serious or not (I would say any logic based on unitialised 
values will bite one day!).
Ok, now I understand. This is inspecting the C runtime stack (I think). 
The Interpreter remembers the bottom address, and then when the time 
comes, a routine runs the depth of the stack.

The values on the stack are then checked whether they are in the pmc or 
buffer memory ranges.

I guess that there must be automatic variables which haven't been 
explicitly set on the stack(?).

Last email from me on the subject,
Nick


Re: Garbage Collection Issues?

2005-03-28 Thread Leopold Toetsch
Cory Spencer [EMAIL PROTECTED] wrote:
 ---354891615-125901741-966306=:18075
 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed


 I've been writing a Lisp implementation on top of Parrot for the last
 several months (and I'm just about at the point where I'm ready to unleash
 it upon the world).

Wow.

 ... I seem to have run up against some issues which
 *appear* to be related to the garbage collector collecting objects that
 aren't ready to be collected yet.

Yep. Good catch. The Hash creation sequence was slightly wrong, i.e.
PMC_struct_val(SELF), which gets the Hash* structure after creation,
wasn't cleared and did contain some garbage. Marking this bogus pointer
did cause the segfault.

Thanks for the test program - fixed.
leo


Garbage Collection Issues?

2005-03-27 Thread Cory Spencer
I've been writing a Lisp implementation on top of Parrot for the last 
several months (and I'm just about at the point where I'm ready to unleash 
it upon the world).  I seem to have run up against some issues which 
*appear* to be related to the garbage collector collecting objects that 
aren't ready to be collected yet.  (I say appear because I'm unsure as 
to how to check when an object is being collected and the memory returned 
to the system - for all I know this could be entirely my fault.)

I've included a much pared down example IMC file which on an x86 Linux 
machine will produce a segmentation fault and on a Mac OS X 10.3 machine 
produces a bus error.  Running with the garbage collection disabled (ie. 
with the -G flag) does not produce these errors.

If anyone could point me towards what is going wrong, I would MOST 
appreciate it - it's been driving me nuts.  (I've been following Parrot 
internals only superficially for the past little while so I'm entirely 
unfamiliar with the garbage collection system.)  I have only a vague
inclination that it has to do somehow with the Hash class (based on how 
various bugs manifest themselves in my program).

The Parrot version is the latest CVS checkout as of 10 minutes ago.
Regards,
Cory

.macro PACKAGE (P,N)
  .P = new LispPackage
  .P._set_name_as_string(.N)  
.endm

.macro STRING (R,S)
  .R = new LispString
  .R = .S
.endm

.macro SYMBOL (R,N)
  .R = new LispSymbol
  .R._set_name_as_string(.N)
.endm

.sub _main @MAIN
  .local pmc package1
  .local pmc package2
  .local pmc package3
  .local pmc symbol
  .local int count

  _init_types()

  .PACKAGE(package1, COMMON-LISP)

  symbol = package1._intern_symbol(T)

  count = 0
LOOP:
  print count
  print : 
  print looking up symbol: T\n
  symbol = package1._lookup_symbol(T)

  .PACKAGE(package3, SYSTEM)

  package3._import_symbol(symbol)

  symbol = package1._lookup_symbol(T)
  package2 = symbol._get_package()

  inc count
  goto LOOP
  
  end
.end

.sub _init_types
  .local pmc class

  # Create the LispPackage class
  newclass class, LispPackage

  addattribute class, internal
  addattribute class, name

  # Create the LispString class
  subclass class, String, LispString

  # Create the LispSymbol class
  newclass class, LispSymbol

  addattribute class, function
  addattribute class, name
  addattribute class, package
.end

.namespace [LispPackage]

.sub __init method
  .local pmc value

  value = new Hash
  setattribute self, LispPackage\0internal, value
.end

.sub _lookup_symbol method
  .param string name
  .local string type
  .local pmc symbol
  .local pmc hash

  getattribute hash, self,  LispPackage\0internal
  symbol = hash[name]

  typeof type, symbol

  if type == None goto SYMBOL_NOT_FOUND
  goto DONE

SYMBOL_NOT_FOUND:
  null symbol
  goto DONE

DONE:
  .return(symbol)
.end

.sub _import_symbol method
  .param pmc symbol
  .local string symname
  .local pmc hash

  symname = symbol._get_name_as_string()

  getattribute hash, self,  LispPackage\0internal
  hash[symname] = symbol

  .return(symbol)
.end

.sub _intern_symbol method
  .param string name
  .local string type
  .local pmc symbol
  .local pmc status
  .local pmc hash

  getattribute hash, self,  LispPackage\0internal
  symbol = hash[name]

  typeof type, symbol
  if type != None goto DONE

  .SYMBOL(symbol, name)
  hash[name] = symbol

  symbol._set_package(self)

  goto DONE

DONE:
  .return(symbol)
.end

.sub _get_name_as_string method
  .local pmc name
  .local string retv

  getattribute name, self, LispPackage\0name
  retv = name

  .return(retv)
.end

.sub _set_name_as_string method
  .param string name
  .local pmc retv

  .STRING(retv, name)

  setattribute self, LispPackage\0name, retv

  .return(retv)
.end

.sub __get_string method
  .local pmc name
  .local pmc tmps
  .local pmc retv

  getattribute name, self, LispPackage\0name

  retv = new String
  tmps = new String

  tmps = #PACKAGE 

  concat retv, tmps, name

  tmps = 
  concat retv, retv, tmps

  .pcc_begin_return
  .return retv
  .pcc_end_return
.end

.namespace [LispSymbol]

.sub _get_name_as_string method
  .local pmc name
  .local string retv

  getattribute name, self, LispSymbol\0name
  retv = name

  .return(retv)
.end

.sub _set_name_as_string method
  .param string name
  .local pmc retv

  .STRING(retv, name)

  setattribute self, LispSymbol\0name, retv

  .return(retv)
.end

.sub _get_package method
  .local pmc retv

  getattribute retv, self, LispSymbol\0package

  .return(retv)
.end

.sub _set_package method
  .param pmc package

  setattribute self, LispSymbol\0package, package

  .return(package)
.end

.sub __get_string method
  .local pmc name

  getattribute name, self, LispSymbol\0name

  .pcc_begin_return
  .return name
  .pcc_end_return
.end

.namespace []