Fix MAKE-LOAD-FORM data-flow ordering in the file compiler#741
Closed
blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
Closed
Fix MAKE-LOAD-FORM data-flow ordering in the file compiler#741blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
Conversation
Author
|
Duplicated in pull request 743 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix MAKE-LOAD-FORM data-flow ordering in the file compiler
Summary
MAKE-LOAD-FORM.ORDER.*tests (ORDER.3–14) inthe ANSI test suite: compiled-test failures drop from 64 to 52
with no regressions.
MAKE-LOAD-FORMcreation andinitialization forms to the fasl in data-flow dependency order,
with init forms run ASAP per CLHS.
*FASL-VERSION*from 43 to 44 (fasl layout changed).Motivation
CLHS requires, for every literal instance handled by
MAKE-LOAD-FORM:references (transitive closure);
and as soon as its data-flow dependencies are satisfied.
Previously, ABCL emitted the creation + init forms inline at the
point where the instance was referenced, expanded via
get-instance-formas(let ((inst <creation>)) <init> inst). Thiscould not express cross-object dependencies and failed every
MAKE-LOAD-FORM.ORDER.*test that involved more than one instancewith dependencies between them.
Approach
Each fasl now carries a per-file instance vector
sys::*fasl-instances*indexed by integer. For every literalinstance referenced in the compile unit, the compiler emits (in
dependency order, before the top-level form that references it):
and the original inline reference to the instance is rewritten to
#.(svref sys::*fasl-instances* N). The vector is allocated once inthe fasl prologue from the final instance count.
A two-phase dependency walker drives the emission:
%fasl-ensure-created(X)— recursively ensures creation of everyinstance embedded in
X's creation form, then emitsX'screation form. A re-entry while
Xis mid-creation is a realcircular creation dependency and signals an error (CLHS: undefined
behavior).
%fasl-ensure-initialized(X)— ensuresXis created, thenrecursively ensures initialization of every instance embedded in
X's init form, then emitsX's init form. An in-progress initcycle is tolerated (CLHS leaves ordering within an init cycle
unspecified).
To honor the ASAP rule (tests
.6,.10–.12),%fasl-ensure-createdeagerly initializesXimmediately afteremitting its creation form iff
%fasl-init-deps-ready-preportsthat every object referenced by
X's init form (ignoringXitself,since MAKE-LOAD-FORM methods commonly embed
',xin their initform) is already initialized. Otherwise init-
Xis emitted later,either from the top-level walk that directly references
Xor fromanother object's init-form walk.
Circularity detection
dump-instancenow writes#.(svref sys::*fasl-instances* N)instead of the legacy inline form. The existing
*circularity*walker (
df-check-object) had to be taught to walk the same consthat
dump-instanceultimately writes, so a single reference consper instance is cached in
*fasl-instance-refs*and reused by bothsites.
A new dynamic variable
*fasl-emitting-to-fasl-stream*gates the newbehavior: when unbound (e.g. dumping constants into a class file via
SERIALIZE-OBJECT),dump-instance/df-check-instancefall backto the legacy
get-instance-formexpansion.Files changed
src/org/armedbear/lisp/Load.java*FASL-VERSION*from 43 to 44.*FASL-INSTANCES*special;bindSpecialit per fasl ininit_fasl.execute.src/org/armedbear/lisp/dump-form.lisp(
%fasl-ensure-created,%fasl-ensure-initialized,%fasl-walk-for-deps,%fasl-init-deps-ready-p,%fasl-write-raw-form,%fasl-emit-toplevel-form).dump-instanceanddf-check-instanceto use the cachedref cons when emitting to a fasl stream; retain the legacy
get-instance-formpath for non-fasl contexts.src/org/armedbear/lisp/compile-file.lispcompile-from-stream.(setq sys::*fasl-instances* (make-array N))in the faslprologue when any instance was registered.
%fasl-emit-toplevel-form.Test plan
MAKE-LOAD-FORM.ORDER.4runs in theexpected order:
*ORDER* = (:CREATING B :CREATING A :INITIALIZING A :INITIALIZING B) (eql (ob-init-dep *b*) *a*) = Tant test.ansi.compiled: 64 → 52 failures / 21930 tests.MAKE-LOAD-FORM.ORDER.3through.14now pass.Compatibility
Fasl layout has changed (new prologue
setqofsys::*fasl-instances*, new per-reference(svref ...)form), hencethe
*FASL-VERSION*bump. Older.abclfasls are rejected by theversion check in
Load.javaand must be recompiled.