Skip to content

clojure.walk and 11 analyzer namespaces are compiled without intrinsics #119

Description

@skydread1

Problem

The intrinsic registry is a plain def, so compiling its own namespace empties it:

;; magic-compiler/src/magic/analyzer/intrinsics.clj:11
(def intrinsic-forms (atom {}))

build.clj compiles that namespace at position 25 and magic.intrinsics, which fills it, at 38. The 12 entries in between are emitted with an empty registry, clojure.walk among them.

walk.clj:45 is (instance? clojure.lang.IMapEntry form). The committed DLL:

ldsfld    Var ...clojure_core$instance_QMARK_
call      Var::getRawRoot()
castclass IFn
ldtoken   clojure.lang.IMapEntry
callvirt  IFn::invoke(object, object)
unbox.any Boolean

With the registry intact it is one isinst clojure.lang.IMapEntry. walk__0 is 745 bytes instead of 607.

Valid IL either way, so nothing fails and no drift check fires. The cost is a Var deref and a boxed Type per call, in walk / prewalk / postwalk and in 11 analyzer passes.

Not new: the 2022-03-26 build of clojure.walk.clj.dll has the intrinsic, the 2022-11-19 build does not.

Suggestion

- (def intrinsic-forms (atom {}))
+ (defonce intrinsic-forms (atom {}))

magic.util already does this for the gensym map (util.clj:10). Reordering build.clj will not work: magic.analyzer requires clojure.walk and magic.intrinsics requires magic.analyzer, so walk has to come first.

Takes effect on bootstrap pass 2, and should regenerate all 12 DLLs.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions