C code review

Posted on 2015 July 02

Vicare’s expander review is still on hold. Ha! Ha! Sue me. Instead I did a C language code review fixing some errors related to memory management, normalising the name of some data types, performing some clean–up and documentation. There is still some documentation review I have to do. All the changes discussed here are in the master branch.

The uses of C language types long and unsigned long have been removed when the intended data type was “signed machine word” and “unsigned machine word”. New data types are now in the code: iksword_t for signed machine words and ikuword_t for unsigned machine words. This should make it feasible (at least: more feasible) to compile and run the code base on platforms adopting the data model LP64 and platforms adopting the data model LLP642.

I found that many places where the dirty vector is to be used were doing it wrong: shame on me. This is really my fault for not understanding correctly how the dirty vector is to be used. I think I fixed the errors.

Customisation of memory handling and garbage collection

I was inspired by a tale of Common Lisp optimisation (found through Reddit and commented on Hacker News) to check what I can do to make Vicare’s memory handling and garbage collection configurable.

First, I realised one of my previous changes was degrading performance a bit, by limiting the size of the Scheme heap’s nursery in some cases; fixed. I reported previously (see Random stuff (2015 May 19)), that start–up time for a simple “Hello world!” compiled program typically gave this execution times:

$ /usr/bin/time -p ./demo
Hello World!
real 0.13
user 0.08
sys 0.05

after the heap size fix, I get:

$ /usr/bin/time -p ./demo
Hello World!
real 0.09
user 0.06
sys 0.03

I am not opening Spumante bottles…

Second, I have made configurable the size of the Scheme heap’s nursery and of the Scheme stack. There are now command line options:

--option scheme-heap-nursery-size=num-of-bytes
--option scheme-stack-size=num-of-bytes

to select the size of memory segments. In addition: the functions scheme-heap-nursery-size and scheme-stack-size allow querying and setting the values at run–time.

Disabling garbage collection

Some time ago, a Github user asked for the ability to (temporarily) disable garbage collection. I quickly dismissed it as too time–consuming to implement, but I changed my mind: it is feasible and I have implemented it.

There is a new command line option; when running with:

$ vicare --option disable-automatic-gc ...

automatic garbage collection is disabled: memory allocation for Scheme objects is performed by enlarging, when needed, the Scheme heap’s nursery.

When automatic garbage collection is disabled: the function collect will still perform a garbage collection, because it is considered an explicit request. The new function automatic-collect mimics the behaviour of automatic collection and can be used to test what happens. The new function automatic-garbage-collection enables or disables automatic garbage collection at run–time.

With this api we should be able to disable automatic garbage collection, then (periodically) run a collection by explicitly calling collect, when it is appropriate to do so. We must do this with care.

Tracking run–time events

There is a new command line option; when running with:

$ vicare --option enable-runtime-messages ...

the C language code in the vicare program prints messages on stderr describing events in the run–time system. At present memory handling events are tracked.

As example:

$ vicare --option enable-runtime-messages
vicare: runtime: initialising Scheme heap's nursery hot block, size: 8388608 bytes, 2048 pages
vicare: runtime: initialising Scheme stack, size: 4194304 bytes, 1024 pages
vicare: runtime: ik_make_room_in_heap_nursery: stored full heap nursery hot block, size: 8388608 bytes, 2048 pages
vicare: runtime: ik_make_room_in_heap_nursery: allocated new heap nursery hot block, size: 8388608 bytes, 2048 pages
Vicare Scheme version 0.4d0, 64-bit
Build 2015-06-30

Copyright (c) 2006-2010 Abdulaziz Ghuloum and contributors
Copyright (c) 2011-2015 Marco Maggi and contributors

vicare> (collect)
vicare: runtime: ik_explicit_collect_from_scheme_with_hooks: explicit GC, requested size 32768 bytes
vicare: runtime: perform_garbage_collection: enter collection for generation 0, requested size 32768 bytes, crossed redline=no
vicare: runtime: perform_garbage_collection: releasing old full heap's nursery segments
vicare: runtime: perform_garbage_collection: reusing current heap's nursery hot block, size: 8388608 bytes, 2048 pages
vicare: runtime: perform_garbage_collection: leave collection for generation 0
vicare: runtime: ikrt_explicit_collect_from_scheme_check_after_gc_hooks: requested 32768 bytes, available before redline 8378656 bytes
vicare: runtime: ikrt_explicit_collect_from_scheme_check_after_gc_hooks: enough room on the nursery, skipping further GC
vicare>

In future more events will be logged, making it a real mess to understand what is going on.


Footnotes

(2)

For details see:

https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models