Porting Boehm-gc to embedded m68k environment

John Neil jneil@atrove.com
Wed Nov 12 13:47:00 GMT 2003

>> 1.  The GC_alloc function(s) calls a clear stack function just prior to
>> returning.  I assume that this function is used to clear old addresses
>It isn't necessary but is sometimes beneficial.  Even if you know the
>exact top of stack for each thread, portions of the stack within that
>range are frequently uninitialized, so the GC takes the opportunity to
>clear some of the stack when it can.

The clearing only happens off the end of the stack, it does not affect the
un-initialized values within the stack.  In my case the stack is cleared
when the thread is initialised so I can safely remove this stack clearing. 

>> 2.  Are the memory pages returned via the GET_MEM function automatically
>> added to the list of ranges to be ...
>No.  Those memory pages are only traced when referenced from a live
>pointer.  (If you did register all of your heap as roots, nothing could
>ever be collected.)
OK I found my problem, gcj is incorrectly calculating the boehm descriptor
when the alignment is not the same as sizeof(void*). 
>> 3.  Why do the Jv_realloc and Jv_malloc functions in prims.cc us
>> realloc/malloc directly rather than the corresponding GC function's
>> GC_malloc 

>I think these are for uncollectable memory.  There may be no good reason
>for not using the GC equivalents.  (At one time the libgcj designers were
>careful to avoid locking in to a single GC implementation, however, no
>real alternative to Boehm's collector has ever been widely used.)
Would it not be nicer to add the appropriate functions to the GC interface
and map these to appropriate functions within the GC implementation, rather
than call malloc, etc directly.  In my case it is better to use the GC
calls, as that way I only need to support one memory management system not
>> 4.  As garbage collection takes considerable time (1.5 seconds for 6M) I
>> was looking at limiting the amount of memory scanned ...
>> Is there any reason why initialized static primitive fields are
>> not stored in the .data section.
>None that I can think of, except that moving fields from .bss to .data
>will increase the binary size slightly.

I would have through smaller, as the code to initialize these variables
would become redundant and could be removed. 

>> As no class pointers are stored in the .data section, is it true that
>> only the section .bss needs be scanned by the garbage collector.

>Definitely not.  The .data section also contains GC-allocated pointers.

>To a large extent .data is pointer-free, but the collector needs help to
>discern this.  If a large continugous region is known to be pointer-free
>it can be excluded from roots by an API call.  However the way libgcj is
>currently organized, most pointer-free regions are small and littered

>Class metadata is the large contributor to libgcj's root size.  The
>best plan may be avoiding scanning any classes that are not yet

>From a pure java point of view, my observation is that the only data in the
.data section which needs to be scanned is in the class meta data.  A list
of these is already available in the JCR_SECTION, so does this mean that I
should be able to iterate over the __JCR_LIST__ and push/mark each class
which has been initialized?  Could the class processing be performed by
something similar to the Jv_MarkObj function, only processing pointers?

As an additional modification, would it be possible to add an additional
section, and get the compiler to place all static java object and array
fields into this section.  Then the GC would only need to scan these for
pointers, rather than the entire .bss and .data sections.  Furthermore, as
only pointers are scanned the chances of false pointers is reduced. 

Would it be possible to sort the class fields so that object and array
fields appear at the start of the object so they can be more easily scanned
by the GC using a length boehm descriptor.  Is there any requirement that
the field order is maintained within the java class?

The problem I had could have was that the alignment was not the same as the
sizeof(void*).  One possible solution to this would be to force stronger
alignment, always align to sizeof(void*) (or an integral number of
sizeof(void*)).  This would also considerably improve the speed of the GC
scanning.  Is it possible to enforce this stronger alignment or would it
cause side affects that I am unaware of.



More information about the Java mailing list