This is work-in-progress, however it does usually complete self-build
on Linux (less so on macOS) and can run some of the regression suite.
This commit is mainly for other developers to view the state.
Using the "buildit" script which is for now the suggested way to build,
make-target-2 will show (in lines prefixed with "Stack scan") pause times
as low as 5 microseconds, or up to maybe 100 microseconds on the high end.
Anything having to do with thread start/exit is potentially broken,
and there are some obviously missing pieces which are denoted by purposely-
inserted lose() calls.
This change anticipates an incremental or concurrent GC wherein access to
weak objects has to synchronize with GC. There is an obvious race between
a collector deciding that an object was not strongly reachable (and
smashing it), and a mutator strengthening a weak reference merely by loading
it into a register.
Techniques to deal with the race typically involve a read barrier that may
involve fine-grained locking around weakRef.get(), or worst-case a way to
inhibit any weak object from being accessed while GC is deciding what to clear.
It would be highly suboptimal to put such a read barrier into SVREF.
To find problems, this change introduces a #+weak-vector-readbarrier feature
which is disabled by default. If enabled, SVREF won't work on the result
of MAKE-WEAK-VECTOR. xof notes that few users have taken the liberty of using
SVREF on SBCL's weak vectors. The migration path isn't too bad - it's just
a matter of changing SVREF to WEAK-VECTOR-REF.
* Put the predicate in generic/utils.
* Put avlnode definition back into src/code/avlnode
(where it matches the file patterns in target-compile-stem)
and add :c-headers flag for header autogeneration
* Get #+(and system-tlabs (not immobile-space)) working
By request of Charles Zhang the capabilities of immobile-space are
getting a slight refactor so that you can have a configuration which
demands immobile text but not immobile fdefns.
As for x86-64, there's no convenient way to request nonstandard
choices of build options because --without-compact-instance-header is
overridden by (WHEN (TARGET-FEATUREP :IMMOBILE-SPACE) in src/cold/shared.
If nothing else, this removes the restriction about trying to build
with arenas and no immobile-space, though the unit tests will fail.
A request for an object exceeding the extension block size would allocate a new
extension, fail to fit in that, again and again. Luckily the loop would terminate
(fatally) when the max extension count was reached. So use a discrete malloc
for oversized allocations. Also, even if a large request would fit in an extension
block, it could waste a large percentage of the previously active block.
Fix a few glitches:
* data loss could occur because GETF made arbitrary destructive modifications
to condition-assigned-slots if two threads read different properties.
Change the plist to an alist and do it right.
* a memoized value would never be returned if it was the unbound marker,
but if a keyword/value pair were given as unbound, it was returned.
I'm not sure why that should be.
* a condition instance allocated on the heap could have conses in an arena
if the first call to SLOT-VALUE occurred with an arena in use.
not exactly use-after-free because it does not free the memory,
but it deals with a similar issue. By changing REWIND-ARENA to HIDE-ARENA,
and then working with a different arena, you can trap erroneous references
to the hidden arena without the further damage that would come from
seeing partially overwritten memory if you reused that same arena.
This gets rid of the coalescing step in save-lisp-and-die as well as
several ad-hoc caches such as the cache formerly known as
unknown-type-atoms, and the values-type-cached function.
Also remove a few special cases of "interned" types since basically
everything looks interned now.
Slower constructors are more than made up for by improved hit rates
in type operator caches. In fact, the compiler ran about 3% faster
in several benchmarks, including a timed run of make-host-1.
And at last it should be reasonably ok to execute on an arena without
fear that every TYPEP operation may create a heap->arena reference due
to caches holding on to type specifiers and internal representations.
Use LIST-ELTS-EQ instead of EQUAL.
Also cons the &REST list on the stack, and copy it only if writing
a cache line. Pleasantly, define-hash-cache already allowed for that.
* POSSIBLY-BASE-STRINGIZE-TO-HEAP wasn't inlining COPY-SEQ if #-sb-unicode
* Move thread arena assignment up and out of a #-win32 guard
* Don't know what's going on with SB-VM:DESTROY-ARENA, so skip it
Decode interior pointers to thread structures in the result.
And a drive-by fix of the comment at the definition of *all-threads*
(we don't key it by stack base address)
* The wasted space calculation was completely wrong
* Initialize per-arena mutex in NEW-ARENA
* Use sysV ABI C call convention for win32
* Record enough state for every thread to remember where it
last allocated in every arena
* Improve heap->arena pointer finder