[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gcl-devel] fast-linking and conservative gc

From: Camm Maguire
Subject: [Gcl-devel] fast-linking and conservative gc
Date: Wed, 16 Jul 2014 13:40:52 -0400

Greetings!  This note is just to memorialize an issue I've run into and
partially fixed in git.  This fix stabilizes the axiom build against
2.6.11pre (git tag cygwin).

GCL has a variety of traditional syntaxes for 'fast-link' function calls
via a single pointer indirection.  The fastest, of course, is the case
where there is no closure environment, the number and types of arguments
are all known, as is the (singe-word) return type.  This mimics all
calls in C, with the added overhead of merely one instruction -- to
fetch the function address from the pointer.

In lisp, however, multiple complexities arise.  It is possible, for
instance, that some function at the end of a chain of such calls,
rebinds the function binding of the symbol referencing an earlier call
higher up in the stack.  This is actually common in the old 'autoloader'
paradigm in which a symbol is bound to a generic function which loads
the appropriate module containing the real definition and then passing
control to that function.  In particular, it is possible that a gc is
triggered in such a process, and with the function now orphaned, its
environment, data, and even code might be reclaimed by the gc, causing
havoc when control returns to the old calling function.

2.6.11pre makes uniform the optimized 'turbo closure' syntax
traditionally used mostly by pcl.  An object array containing the
environment is passed on the stack, which is alas invisible to
conservative gc.  Now we pass the function instead, finding the
environment by an additional indirection, so that data referenced by the
function is safe at least until the function returns.

Note that setting a global to pass the current
function-with-environment, as is done in git master, will not suffice,
as the whole stack needs to be walked to protect each function in the
call chain.  Note also that this does nothing to address the most common
and fastest call with no environment, in which the code and data still
need protection in principle even though there is no environment to
protect.   It is, however, much less likely to be an issue, as almost
all functions share code and data with other functions in a file, all of
which would have to be redefined prior to a gc to cause trouble.

The proper solution is to place the function as an extra argument on the
stack for all calls, but this will necessarily slow things down a bit.
We will have to decide in the future whether this is advisable.
Suggestions as always are most welcome.
Camm Maguire                                        address@hidden
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah

reply via email to

[Prev in Thread] Current Thread [Next in Thread]