diff --git a/pkgs/racket-doc/scribblings/reference/eval.scrbl b/pkgs/racket-doc/scribblings/reference/eval.scrbl index 04aeeecc99..930125ad6c 100644 --- a/pkgs/racket-doc/scribblings/reference/eval.scrbl +++ b/pkgs/racket-doc/scribblings/reference/eval.scrbl @@ -528,12 +528,12 @@ handler} in tail position with @racket[stx].} @defproc[(compiled-expression-recompile [ce compiled-expression?]) compiled-expression?]{ -Recompiles @racket[ce], effectively re-running optimization passes to -produce an equivalent compiled form with potentially different -performance characteristics. - -If @racket[ce] includes module forms, then only phase-0 code in the -immediate module (not in submodules) is recompiled. +Recompiles @racket[ce]. If @racket[ce] was compiled as +machine-independent and @racket[compile-machine-independent] is +@racket[#f], then recompiling effectively converts to the current +machine format. Otherwise, recompiling effectively re-runs +optimization passes to produce an equivalent compiled form with +potentially different performance characteristics. @history[#:added "6.3"]} diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index 03acaac065..feb7dc2ffe 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -2838,6 +2838,54 @@ case of module-leve bindings; it doesn't cover local bindings. (dynamic-require ''assigns-to-self-variable-through-namespace #f) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Check machine-independent compilation and +;; machine-dependent recompilation + +(let () + (define m (parameterize ([compile-machine-independent #t]) + (compile + ;; The intent of this module is to exercise cross-module + ;; inlining when moving from machine-independent to + ;; machine-dependent. The `x` should be inlined from a submodule + ;; and `map` should be inlined --- but we don't actually + ;; check, currently. + `(module should-inline-when-fully-compiled racket/base + (module sub racket/base + (define x 1) + (provide x)) + (require 'sub) + (define (f g) + (map (lambda (y) x) g)))))) + + (define (check-vm bstr vm) + (define vm-bstr (string->bytes/utf-8 (symbol->string vm))) + (define expect (bytes-append #"#~" + (bytes (string-length (version))) + (string->bytes/utf-8 (version)) + (bytes (bytes-length vm-bstr)) + vm-bstr)) + (test #t equal? expect (subbytes bstr 0 (min (bytes-length bstr) (bytes-length expect))))) + + (define o (open-output-bytes)) + (write m o) + (check-vm (get-output-bytes o) 'linklet) + + (define m2 + (parameterize ([read-accept-compiled #t]) + (read (open-input-bytes (get-output-bytes o))))) + + (define re-m (compiled-expression-recompile m)) + (define re-m2 (compiled-expression-recompile m2)) + + (define re-o (open-output-bytes)) + (write re-m re-o) + (check-vm (get-output-bytes re-o) (system-type 'vm)) + + (define re-o2 (open-output-bytes)) + (write re-m2 re-o2) + (check-vm (get-output-bytes re-o2) (system-type 'vm))) + ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (report-errs) diff --git a/racket/src/expander/compile/form.rkt b/racket/src/expander/compile/form.rkt index 611a90b0e4..7c6e5b96f8 100644 --- a/racket/src/expander/compile/form.rkt +++ b/racket/src/expander/compile/form.rkt @@ -27,7 +27,7 @@ "correlated-linklet.rkt") (provide compile-forms - + compile-module-linklet compile-namespace-scopes) (struct link-info (link-module-uses imports extra-inspectorsss def-decls)) @@ -386,6 +386,7 @@ ;; means that the set of imports can change: return a compiled linklet ;; and a list of `module-use*` (define (compile-module-linklet body-linklet + #:compile-linklet [compile-linklet compile-linklet] #:body-imports body-imports #:body-import-instances body-import-instances #:get-module-linklet-info get-module-linklet-info diff --git a/racket/src/expander/compile/module.rkt b/racket/src/expander/compile/module.rkt index 83c9ce3e60..a60da92b9f 100644 --- a/racket/src/expander/compile/module.rkt +++ b/racket/src/expander/compile/module.rkt @@ -200,20 +200,8 @@ (performance-region ['compile 'module 'linklet] (compile-linklet s 'decl)))) - `(linklet - ;; imports - (,deserialize-imports - [,mpi-vector-id]) - ;; exports - (self-mpi - requires - provides - phase-to-link-modules) - ;; body - (define-values (self-mpi) ,(add-module-path-index! mpis self)) - (define-values (requires) ,(generate-deserialize requires mpis #:syntax-support? #f)) - (define-values (provides) ,(generate-deserialize provides mpis #:syntax-support? #f)) - (define-values (phase-to-link-modules) ,phase-to-link-module-uses-expr))))) + (generate-module-declaration-linklet mpis self requires provides + phase-to-link-module-uses-expr)))) ;; Assemble a linklet that shifts syntax objects on demand. ;; Include an encoding of the root expand context, if any, so that @@ -301,15 +289,7 @@ (performance-region ['compile 'module 'linklet] (compile-linklet s 'data)))) - `(linklet - ;; imports - (,deserialize-imports) - ;; exports - (,mpi-vector-id) - ;; body - (define-values (,inspector-id) (current-code-inspector)) - (define-values (,mpi-vector-id) - ,(generate-module-path-index-deserialize mpis)))))) + (generate-module-data-linklet mpis)))) ;; Combine linklets with other metadata as the bundle: (define bundle diff --git a/racket/src/expander/compile/recompile.rkt b/racket/src/expander/compile/recompile.rkt index d140b7eba0..c6fcd90392 100644 --- a/racket/src/expander/compile/recompile.rkt +++ b/racket/src/expander/compile/recompile.rkt @@ -1,26 +1,206 @@ #lang racket/base (require "../host/linklet.rkt" "../eval/reflect.rkt" - "linklet.rkt") + "../compile/form.rkt" + "../compile/module.rkt" + "../namespace/namespace.rkt" + "../namespace/module.rkt" + "../common/module-path.rkt" + "linklet.rkt" + "correlated-linklet.rkt" + "form.rkt" + "serialize.rkt" + "reserved-symbol.rkt" + "instance.rkt" + "extra-inspector.rkt" + "compiled-in-memory.rkt") (provide compiled-expression-recompile) (define (compiled-expression-recompile c) (unless (compiled-expression? c) (raise-argument-error 'compiled-expression-recompile "compiled-expression?" c)) + (cond + [(compile-machine-independent) + ;; There's no use for machine-independent mode, and + ;; `recompile-bundle` assumes that it should actually compile + c] + [(or (linklet-bundle? c) + (linklet-directory? c)) + (define ns (current-namespace)) + ;; First, extract all bundles, so we can implement cross-module + ;; optimizations involving submodules + (define bundles (extract-linklet-bundles c '() #hash())) + ;; Recompile each bundle + (define recompileds (make-hash)) + (define (force-recompile-bundle k) + (unless (hash-ref recompileds k #f) + (hash-set! recompileds k 'in-process) + (define b (hash-ref bundles k #f)) + (unless b + (raise-arguments-error 'compiled-expression-recompile + "cannot find submodule" + "submodule path" k)) + (hash-set! recompileds k (recompile-bundle b + force-recompile-bundle + ns))) + (hash-ref recompileds k)) + (for ([k (in-hash-keys bundles)]) + (force-recompile-bundle k)) + (replace-linklet-bundles c '() recompileds)] + [else + ;; For now, we just give up on compiled-in-memory information, + ;; because the intended use cases are with serialization --- but + ;; beware that we may lose detailed inspector-based access: + (compiled-expression-recompile (compiled-in-memory-linklet-directory c))])) + +;; ---------------------------------------- + +(define (extract-linklet-bundles c rev-path accum) (cond [(linklet-bundle? c) - (hash->linklet-bundle - (for/hasheq ([(k v) (in-hash (linklet-bundle->hash c))]) - (cond - [(linklet? v) (values k (recompile-linklet v))] - [else (values k v)])))] + (hash-set accum (reverse rev-path) c)] + [(linklet-directory? c) + (for/fold ([accum accum]) ([(k v) (in-hash (linklet-directory->hash c))]) + (cond + [(symbol? k) + (extract-linklet-bundles v (cons k rev-path) accum)] + [(not k) + (extract-linklet-bundles v rev-path accum)] + [else accum]))] + [else accum])) + +(define (replace-linklet-bundles c rev-path recompileds) + (cond + [(linklet-bundle? c) + (recompiled-bundle (hash-ref recompileds (reverse rev-path)))] [(linklet-directory? c) (hash->linklet-directory (for/hasheq ([(k v) (in-hash (linklet-directory->hash c))]) - (cond - [(compiled-expression? v) - (values k (compiled-expression-recompile v))] - [else - (values k v)])))] + (values k + (cond + [(symbol? k) + (replace-linklet-bundles v (cons k rev-path) recompileds)] + [(not k) + (replace-linklet-bundles v rev-path recompileds)]))))] [else c])) + +;; ---------------------------------------- + +(struct recompiled (bundle + ;; The remaining information is used for cross-linklet + ;; inlnining among submodules within a linklet directory + phase-to-link-module-uses + self) + #:authentic) + +;; Takes a bundle and returns a recompiled +(define (recompile-bundle b get-submodule-recompiled ns) + ;; We have to execute the parts of the bundle that supply data, such + ;; as the mpis and link modules, then use that data for cross-module + ;; optimization while recompiling the per-phase body units, and then + ;; regenerate the data linklets because optimization can add new + ;; linklet import.s + (define h (linklet-bundle->hash b)) + + (define (eval-linklet* l) + (eval-linklet (force-compile-linklet l))) + (define data-instance + (instantiate-linklet (eval-linklet* (hash-ref h 'data)) + (list deserialize-instance))) + (define declaration-instance + (instantiate-linklet (eval-linklet* (hash-ref h 'decl)) + (list deserialize-instance + data-instance))) + (define (decl key) + (instance-variable-value declaration-instance key)) + + (define mpis (make-module-path-index-table)) + ;; Add current mpis in order, so existing references will stay correct + (for ([mpi (in-vector (instance-variable-value data-instance mpi-vector-id))]) + (add-module-path-index! mpis mpi)) + + (define self (decl 'self-mpi)) + (define phase-to-link-modules (decl 'phase-to-link-modules)) + + (define (find-submodule mod-name phase) + ;; If `mod-name` refers to a submodule in the same linklet directory, + ;; then we need to force that one to be recompiled and then return it. + (define find-l (resolved-module-path-name mod-name)) + (define self-l (resolved-module-path-name (module-path-index-resolve self))) + (define (root-of l) (if (pair? l) (car l) l)) + (cond + [(equal? (root-of find-l) (root-of self-l)) + (define r (get-submodule-recompiled (if (pair? find-l) (cdr find-l) '()))) + (when (eq? r 'in-process) + (raise-arguments-error 'compiled-expression-recompile + "cycle in linklet imports")) + (define b (recompiled-bundle r)) + (define linklet + (or (hash-ref (linklet-bundle->hash b) phase #f) + (raise-arguments-error 'compiled-expression-recompile + "cannot find submodule at phase" + "submodule" mod-name + "phase" phase))) + (module-linklet-info linklet + (hash-ref (recompiled-phase-to-link-module-uses r) phase #f) + (recompiled-self r) + #f ; inspector is the same as the module being compiled + (current-code-inspector) ; compile-time inspector is now + #f)] + [else #f])) + + (define body-linklets+module-use*s + (for/hash ([(phase body-linklet) (in-hash h)] + #:when (exact-integer? phase)) + (define module-use*s + (module-uses-add-extra-inspectorsss (hash-ref phase-to-link-modules phase) + #f)) + (define-values (linklet new-module-use*s) + (compile-module-linklet (if (correlated-linklet? body-linklet) + (correlated-linklet-expr body-linklet) + body-linklet) + #:compile-linklet (if (correlated-linklet? body-linklet) + compile-linklet + recompile-linklet) + #:body-imports `([,get-syntax-literal!-id] + [,set-transformer!-id]) + #:body-import-instances (list empty-syntax-literals-instance + empty-module-body-instance) + #:get-module-linklet-info find-submodule + #:serializable? #t + #:module-use*s module-use*s + #:cross-linklet-inlining? #t + #:namespace ns)) + (values phase (cons linklet new-module-use*s)))) + + (define h/new-body-linklets + (for/fold ([h h]) ([(phase l+mu*s) (in-hash body-linklets+module-use*s)]) + (hash-set h phase (car l+mu*s)))) + + (define phase-to-link-module-uses + (for/hasheq ([(phase l+mu*s) (in-hash body-linklets+module-use*s)]) + (values phase (module-uses-strip-extra-inspectorsss (cdr l+mu*s))))) + + (define phase-to-link-module-uses-expr + (serialize-phase-to-link-module-uses phase-to-link-module-uses mpis)) + + (define data-linklet + (compile-linklet (generate-module-data-linklet mpis) 'data)) + + (define declaration-linklet + (compile-linklet (generate-module-declaration-linklet mpis self + (decl 'requires) + (decl 'provides) + phase-to-link-module-uses-expr) + 'decl)) + + (define new-bundle + (hash->linklet-bundle (let* ([h h/new-body-linklets] + [h (hash-set h 'data data-linklet)] + [h (hash-set h 'decl declaration-linklet)]) + h))) + + (recompiled new-bundle + phase-to-link-module-uses + self)) diff --git a/racket/src/expander/compile/serialize.rkt b/racket/src/expander/compile/serialize.rkt index 2faaad7968..0380a3f935 100644 --- a/racket/src/expander/compile/serialize.rkt +++ b/racket/src/expander/compile/serialize.rkt @@ -73,7 +73,10 @@ add-module-path-index!/pos generate-module-path-index-deserialize mpis-as-vector - + + generate-module-data-linklet + generate-module-declaration-linklet + generate-deserialize deserialize-instance @@ -196,6 +199,36 @@ (or (has-symbol? (car d) vars) (has-symbol? (cdr d) vars))))) +;; ---------------------------------------- + +(define (generate-module-data-linklet mpis) + `(linklet + ;; imports + (,deserialize-imports) + ;; exports + (,mpi-vector-id) + ;; body + (define-values (,inspector-id) (current-code-inspector)) + (define-values (,mpi-vector-id) + ,(generate-module-path-index-deserialize mpis)))) + +(define (generate-module-declaration-linklet mpis self requires provides + phase-to-link-module-uses-expr) + `(linklet + ;; imports + (,deserialize-imports + [,mpi-vector-id]) + ;; exports + (self-mpi + requires + provides + phase-to-link-modules) + ;; body + (define-values (self-mpi) ,(add-module-path-index! mpis self)) + (define-values (requires) ,(generate-deserialize requires mpis #:syntax-support? #f)) + (define-values (provides) ,(generate-deserialize provides mpis #:syntax-support? #f)) + (define-values (phase-to-link-modules) ,phase-to-link-module-uses-expr))) + ;; ---------------------------------------- ;; Module-use serialization --- as an expression, like module path ;; indexes, and unlike everything else diff --git a/racket/src/expander/demo.rkt b/racket/src/expander/demo.rkt index d49bf375de..62c35d17d3 100644 --- a/racket/src/expander/demo.rkt +++ b/racket/src/expander/demo.rkt @@ -17,15 +17,30 @@ (expand (namespace-syntax-introduce (datum->syntax #f e) ns) ns)) -(define (compile+eval-expression e #:namespace [ns demo-ns]) +(define (expand+compile-expression e + #:namespace [ns demo-ns] + #:serializable? [serializable? #f]) (define exp-e (expand-expression e #:namespace ns)) - (define c (compile (if check-reexpand? exp-e e) ns check-serialize?)) + (define c (compile (if check-reexpand? exp-e e) ns (or serializable? + check-serialize?))) (define ready-c (if check-serialize? (let ([o (open-output-bytes)]) (display c o) (parameterize ([read-accept-compiled #t]) (read (open-input-bytes (get-output-bytes o))))) c)) + (values exp-e ready-c)) + +(define (compile-expression e + #:namespace [ns demo-ns] + #:serializable? [serializable? #f]) + (define-values (exp-e ready-c) + (expand+compile-expression e #:namespace ns #:serializable? serializable?)) + ready-c) + +(define (compile+eval-expression e #:namespace [ns demo-ns]) + (define-values (exp-e ready-c) + (expand+compile-expression e #:namespace ns)) (values exp-e (eval ready-c ns))) @@ -1421,3 +1436,19 @@ (quote-syntax car)) (free-identifier=? (syntax-binding-set->syntax bs 'cdr) (quote-syntax cdr))))) + +;; ---------------------------------------- +;; Machine-independent compilation format and recompilation + +(let ([mi-c (parameterize ([compile-machine-independent #t]) + (compile-expression `(module to-recompile '#%kernel + (define-values (x) 0) + (print x) + (newline)) + #:serializable? #t))]) + (parameterize ([current-namespace demo-ns]) + (define c2 (compiled-expression-recompile mi-c)) + (eval c2 demo-ns) + (check-print + (namespace-require ''to-recompile demo-ns) + 0))) diff --git a/racket/src/expander/main.rkt b/racket/src/expander/main.rkt index 8fa998646e..8ea41dbb5c 100644 --- a/racket/src/expander/main.rkt +++ b/racket/src/expander/main.rkt @@ -30,6 +30,8 @@ "boot/runtime-primitive.rkt" "boot/handler.rkt" "syntax/api.rkt" + (only-in "compile/recompile.rkt" + compiled-expression-recompile) (only-in racket/private/config find-main-config) (only-in "syntax/cache.rkt" cache-place-init!) (only-in "syntax/scope.rkt" scope-place-init!) @@ -126,7 +128,9 @@ read-accept-compiled syntax-shift-phase-level - bound-identifier=?) + bound-identifier=? + + compiled-expression-recompile) ;; ---------------------------------------- diff --git a/racket/src/racket/src/startup.inc b/racket/src/racket/src/startup.inc index 927912bbfc..71d71b857a 100644 --- a/racket/src/racket/src/startup.inc +++ b/racket/src/racket/src/startup.inc @@ -6,6 +6,7 @@ static const char *startup_source = "(1/bound-identifier=? bound-identifier=?)" "(1/compile compile)" "(compile-keep-source-locations! compile-keep-source-locations!)" +"(1/compiled-expression-recompile compiled-expression-recompile)" "(1/current-compile current-compile)" "(1/current-compiled-file-roots current-compiled-file-roots)" "(1/current-eval current-eval)" @@ -18450,6 +18451,36 @@ static const char *startup_source = "(void)" " vec_0))))))" "(define-values" +"(generate-module-data-linklet)" +"(lambda(mpis_0)" +"(begin" +"(list" +" 'linklet" +"(list deserialize-imports)" +"(list mpi-vector-id)" +"(list* 'define-values(list inspector-id) '((current-code-inspector)))" +"(list 'define-values(list mpi-vector-id)(generate-module-path-index-deserialize mpis_0))))))" +"(define-values" +"(generate-module-declaration-linklet)" +"(lambda(mpis_0 self_0 requires_0 provides_0 phase-to-link-module-uses-expr_0)" +"(begin" +"(list" +" 'linklet" +"(list deserialize-imports(list mpi-vector-id))" +" '(self-mpi requires provides phase-to-link-modules)" +"(list 'define-values '(self-mpi)(add-module-path-index! mpis_0 self_0))" +"(list" +" 'define-values" +" '(requires)" +"(let-values(((requires10_0) requires_0)((mpis11_0) mpis_0)((temp12_0) #f))" +"(generate-deserialize6.1 temp12_0 requires10_0 mpis11_0)))" +"(list" +" 'define-values" +" '(provides)" +"(let-values(((provides13_0) provides_0)((mpis14_0) mpis_0)((temp15_0) #f))" +"(generate-deserialize6.1 temp15_0 provides13_0 mpis14_0)))" +"(list 'define-values '(phase-to-link-modules) phase-to-link-module-uses-expr_0)))))" +"(define-values" "(serialize-module-uses)" "(lambda(mus_0 mpis_0)" "(begin" @@ -18505,8 +18536,8 @@ static const char *startup_source = "(lambda(phase-to-link-module-uses_0 mpis_0)" "(begin" "(let-values(((phases-in-order_0)" -"(let-values(((temp10_0)(hash-keys phase-to-link-module-uses_0))((<11_0) <))" -"(sort7.1 #f #f temp10_0 <11_0))))" +"(let-values(((temp16_0)(hash-keys phase-to-link-module-uses_0))((<17_0) <))" +"(sort7.1 #f #f temp16_0 <17_0))))" "(list*" " 'hasheqv" "(apply" @@ -19086,9 +19117,9 @@ static const char *startup_source = " null" "(hash-iterate-first ht_0)))))))" "(let-values(((lst_0)" -"(let-values(((share-steps12_0) share-steps_0)" -"((<13_0) <))" -"(sort7.1 #f #f share-steps12_0 <13_0)))" +"(let-values(((share-steps18_0) share-steps_0)" +"((<19_0) <))" +"(sort7.1 #f #f share-steps18_0 <19_0)))" "((start_0) num-mutables_0))" "(begin" "(if(variable-reference-from-unsafe?(#%variable-reference))" @@ -20169,16 +20200,16 @@ static const char *startup_source = "(let-values() ks_0)" "(if(andmap2 symbol? ks_0)" "(let-values()" -"(let-values(((ks14_0) ks_0)((symbollist new-module-use*s_0)(length body-imports_0))))))))))))))))" +"(list-tail(vector->list new-module-use*s_0)(length body-imports_0)))))))))))))))))" "(define-values" "(make-module-use-to-linklet)" "(lambda(cross-linklet-inlining?_0 ns_0 get-module-linklet-info_0 init-mu*s_0)" @@ -39378,47 +39413,12 @@ static const char *startup_source = "(let-values()" "(end-performance-region))" "(void))))))" -"(list" -" 'linklet" -"(list" -" deserialize-imports" -"(list mpi-vector-id))" -" '(self-mpi" -" requires" -" provides" -" phase-to-link-modules)" -"(list" -" 'define-values" -" '(self-mpi)" -"(add-module-path-index!" +"(generate-module-declaration-linklet" " mpis_0" -" self_0))" -"(list" -" 'define-values" -" '(requires)" -"(let-values(((requires73_0)" -" requires_0)" -"((mpis74_0) mpis_0)" -"((temp75_0) #f))" -"(generate-deserialize6.1" -" temp75_0" -" requires73_0" -" mpis74_0)))" -"(list" -" 'define-values" -" '(provides)" -"(let-values(((provides76_0)" -" provides_0)" -"((mpis77_0) mpis_0)" -"((temp78_0) #f))" -"(generate-deserialize6.1" -" temp78_0" -" provides76_0" -" mpis77_0)))" -"(list" -" 'define-values" -" '(phase-to-link-modules)" -" phase-to-link-module-uses-expr_0)))" +" self_0" +" requires_0" +" provides_0" +" phase-to-link-module-uses-expr_0))" " #f)))" "(let-values(((syntax-literals-linklet_0)" "(if(not" @@ -39476,20 +39476,20 @@ static const char *startup_source = " get-syntax-literal!-id" " '(get-encoded-root-expand-ctx))" "(qq-append" -"(let-values(((syntax-literals79_0)" +"(let-values(((syntax-literals73_0)" " syntax-literals_0)" -"((mpis80_0)" +"((mpis74_0)" " mpis_0)" -"((self81_0)" +"((self75_0)" " self_0)" -"((temp82_0)" +"((temp76_0)" "(not" " serializable?_0)))" "(generate-lazy-syntax-literals!9.1" -" temp82_0" -" syntax-literals79_0" -" mpis80_0" -" self81_0))" +" temp76_0" +" syntax-literals73_0" +" mpis74_0" +" self75_0))" "(list" "(list" " 'define-values" @@ -39593,19 +39593,8 @@ static const char *startup_source = "(let-values()" "(end-performance-region))" "(void))))))" -"(list" -" 'linklet" -"(list deserialize-imports)" -"(list mpi-vector-id)" -"(list*" -" 'define-values" -"(list inspector-id)" -" '((current-code-inspector)))" -"(list" -" 'define-values" -"(list mpi-vector-id)" -"(generate-module-path-index-deserialize" -" mpis_0))))" +"(generate-module-data-linklet" +" mpis_0))" " #f)))" "(let-values(((bundle_0)" "(let-values(((bundle_0)" @@ -39699,16 +39688,16 @@ static const char *startup_source = "(hash-set" " bundle_10" " 'side-effects" -"(let-values(((temp83_0)" +"(let-values(((temp77_0)" "(hash-keys" " side-effects_0))" -"((<84_0)" +"((<78_0)" " <))" "(sort7.1" " #f" " #f" -" temp83_0" -" <84_0)))" +" temp77_0" +" <78_0)))" " bundle_10)))" "(let-values(((bundle_12)" "(if empty-result-for-module->namespace?_0" @@ -39951,41 +39940,120 @@ static const char *startup_source = "(if(1/compiled-expression? c_0)" "(void)" " (let-values () (raise-argument-error 'compiled-expression-recompile \"compiled-expression?\" c_0)))" -"(if(linklet-bundle? c_0)" +"(if(compile-machine-independent)" +"(let-values() c_0)" +"(if(let-values(((or-part_0)(linklet-bundle? c_0)))(if or-part_0 or-part_0(linklet-directory? c_0)))" "(let-values()" -"(hash->linklet-bundle" -"(let-values(((ht_0)(linklet-bundle->hash c_0)))" +"(let-values(((ns_0)(1/current-namespace)))" +"(let-values(((bundles_0)(extract-linklet-bundles c_0 '() '#hash())))" +"(let-values(((recompileds_0)(make-hash)))" +"(letrec-values(((force-recompile-bundle_0)" +"(lambda(k_0)" +"(begin" +" 'force-recompile-bundle" +"(begin" +"(if(hash-ref recompileds_0 k_0 #f)" +"(void)" +"(let-values()" +"(let-values((()" +"(begin" +"(hash-set! recompileds_0 k_0 'in-process)" +"(values))))" +"(let-values(((b_0)(hash-ref bundles_0 k_0 #f)))" +"(begin" +"(if b_0" +"(void)" +"(let-values()" +"(raise-arguments-error" +" 'compiled-expression-recompile" +" \"cannot find submodule\"" +" \"submodule path\"" +" k_0)))" +"(hash-set!" +" recompileds_0" +" k_0" +"(recompile-bundle b_0 force-recompile-bundle_0 ns_0)))))))" +"(hash-ref recompileds_0 k_0))))))" +"(begin" +"(let-values(((ht_0) bundles_0))" +"(begin" +"(if(variable-reference-from-unsafe?(#%variable-reference))" +"(void)" +"(let-values()(check-in-hash-keys ht_0)))" +"((letrec-values(((for-loop_0)" +"(lambda(i_0)" +"(begin" +" 'for-loop" +"(if i_0" +"(let-values(((k_0)(hash-iterate-key ht_0 i_0)))" +"(let-values((()" +"(let-values()" +"(let-values((()" +"(let-values()" +"(begin" +"(let-values()" +"(force-recompile-bundle_0" +" k_0))" +"(values)))))" +"(values)))))" +"(if(not #f)" +"(for-loop_0(hash-iterate-next ht_0 i_0))" +"(values))))" +"(values))))))" +" for-loop_0)" +"(hash-iterate-first ht_0))))" +"(void)" +"(replace-linklet-bundles c_0 '() recompileds_0)))))))" +"(let-values()(1/compiled-expression-recompile(compiled-in-memory-linklet-directory c_0)))))))))" +"(define-values" +"(extract-linklet-bundles)" +"(lambda(c_0 rev-path_0 accum_0)" +"(begin" +"(if(linklet-bundle? c_0)" +"(let-values()(hash-set accum_0(reverse$1 rev-path_0) c_0))" +"(if(linklet-directory? c_0)" +"(let-values()" +"(let-values(((ht_0)(linklet-directory->hash c_0)))" "(begin" "(if(variable-reference-from-unsafe?(#%variable-reference))" "(void)" "(let-values()(check-in-hash ht_0)))" "((letrec-values(((for-loop_0)" -"(lambda(table_0 i_0)" +"(lambda(accum_1 i_0)" "(begin" " 'for-loop" "(if i_0" "(let-values(((k_0 v_0)(hash-iterate-key+value ht_0 i_0)))" -"(let-values(((table_1)" -"(let-values(((table_1) table_0))" -"(let-values(((table_2)" +"(let-values(((accum_2)" +"(let-values(((accum_2) accum_1))" +"(let-values(((accum_3)" "(let-values()" -"(let-values(((key_0 val_0)" +"(if(symbol? k_0)" "(let-values()" -"(if(1/linklet? v_0)" +"(extract-linklet-bundles" +" v_0" +"(cons k_0 rev-path_0)" +" accum_2))" +"(if(not k_0)" "(let-values()" -"(values" -" k_0" -"(1/recompile-linklet" -" v_0)))" -"(let-values()" -"(values k_0 v_0))))))" -"(hash-set table_1 key_0 val_0)))))" -"(values table_2)))))" -"(if(not #f)(for-loop_0 table_1(hash-iterate-next ht_0 i_0)) table_1)))" -" table_0)))))" +"(extract-linklet-bundles" +" v_0" +" rev-path_0" +" accum_2))" +"(let-values() accum_2))))))" +"(values accum_3)))))" +"(if(not #f)(for-loop_0 accum_2(hash-iterate-next ht_0 i_0)) accum_2)))" +" accum_1)))))" " for-loop_0)" -" '#hasheq()" -"(hash-iterate-first ht_0))))))" +" accum_0" +"(hash-iterate-first ht_0)))))" +"(let-values() accum_0))))))" +"(define-values" +"(replace-linklet-bundles)" +"(lambda(c_0 rev-path_0 recompileds_0)" +"(begin" +"(if(linklet-bundle? c_0)" +"(let-values()(recompiled-bundle(hash-ref recompileds_0(reverse$1 rev-path_0))))" "(if(linklet-directory? c_0)" "(let-values()" "(hash->linklet-directory" @@ -40006,15 +40074,21 @@ static const char *startup_source = "(let-values()" "(let-values(((key_0 val_0)" "(let-values()" -"(if(1/compiled-expression?" -" v_0)" -"(let-values()" "(values" " k_0" -"(1/compiled-expression-recompile" -" v_0)))" +"(if(symbol? k_0)" "(let-values()" -"(values k_0 v_0))))))" +"(replace-linklet-bundles" +" v_0" +"(cons k_0 rev-path_0)" +" recompileds_0))" +"(if(not k_0)" +"(let-values()" +"(replace-linklet-bundles" +" v_0" +" rev-path_0" +" recompileds_0))" +"(void)))))))" "(hash-set table_1 key_0 val_0)))))" "(values table_2)))))" "(if(not #f)(for-loop_0 table_1(hash-iterate-next ht_0 i_0)) table_1)))" @@ -40022,7 +40096,332 @@ static const char *startup_source = " for-loop_0)" " '#hasheq()" "(hash-iterate-first ht_0))))))" -"(let-values() c_0)))))))" +"(let-values() c_0))))))" +"(define-values" +"(struct:recompiled recompiled1.1 recompiled? recompiled-bundle recompiled-phase-to-link-module-uses recompiled-self)" +"(let-values(((struct:_0 make-_0 ?_0 -ref_0 -set!_0)" +"(let-values()" +"(let-values()" +"(make-struct-type" +" 'recompiled" +" #f" +" 3" +" 0" +" #f" +"(list(cons prop:authentic #t))" +"(current-inspector)" +" #f" +" '(0 1 2)" +" #f" +" 'recompiled)))))" +"(values" +" struct:_0" +" make-_0" +" ?_0" +"(make-struct-field-accessor -ref_0 0 'bundle)" +"(make-struct-field-accessor -ref_0 1 'phase-to-link-module-uses)" +"(make-struct-field-accessor -ref_0 2 'self))))" +"(define-values" +"(recompile-bundle)" +"(lambda(b_0 get-submodule-recompiled_0 ns_0)" +"(begin" +"(let-values(((h_0)(linklet-bundle->hash b_0)))" +"(let-values(((eval-linklet*_0)" +"(lambda(l_0)(begin 'eval-linklet*(1/eval-linklet(force-compile-linklet l_0))))))" +"(let-values(((data-instance_0)" +"(1/instantiate-linklet(eval-linklet*_0(hash-ref h_0 'data))(list deserialize-instance))))" +"(let-values(((declaration-instance_0)" +"(1/instantiate-linklet" +"(eval-linklet*_0(hash-ref h_0 'decl))" +"(list deserialize-instance data-instance_0))))" +"(let-values(((decl_0)" +"(lambda(key_0)(begin 'decl(1/instance-variable-value declaration-instance_0 key_0)))))" +"(let-values(((mpis_0)(make-module-path-index-table)))" +"(let-values((()" +"(begin" +"(let-values(((vec_0 len_0)" +"(let-values(((vec_0)" +"(1/instance-variable-value" +" data-instance_0" +" mpi-vector-id)))" +"(begin" +"(check-vector vec_0)" +"(values vec_0(unsafe-vector-length vec_0))))))" +"(begin" +" #f" +"((letrec-values(((for-loop_0)" +"(lambda(pos_0)" +"(begin" +" 'for-loop" +"(if(unsafe-fx< pos_0 len_0)" +"(let-values(((mpi_0)(unsafe-vector-ref vec_0 pos_0)))" +"(let-values((()" +"(let-values()" +"(let-values((()" +"(let-values()" +"(begin" +"(let-values()" +"(add-module-path-index!" +" mpis_0" +" mpi_0))" +"(values)))))" +"(values)))))" +"(if(not #f)" +"(for-loop_0(unsafe-fx+ 1 pos_0))" +"(values))))" +"(values))))))" +" for-loop_0)" +" 0)))" +"(values))))" +"(let-values()" +"(let-values(((self_0)(decl_0 'self-mpi)))" +"(let-values(((phase-to-link-modules_0)(decl_0 'phase-to-link-modules)))" +"(let-values(((find-submodule_0)" +"(lambda(mod-name_0 phase_0)" +"(begin" +" 'find-submodule" +"(let-values(((find-l_0)(1/resolved-module-path-name mod-name_0)))" +"(let-values(((self-l_0)" +"(1/resolved-module-path-name" +"(1/module-path-index-resolve self_0))))" +"(let-values(((root-of_0)" +"(lambda(l_0)" +"(begin 'root-of(if(pair? l_0)(car l_0) l_0)))))" +"(if(equal?(root-of_0 find-l_0)(root-of_0 self-l_0))" +"(let-values()" +"(let-values(((r_0)" +"(get-submodule-recompiled_0" +"(if(pair? find-l_0)(cdr find-l_0) '()))))" +"(let-values((()" +"(begin" +"(if(eq? r_0 'in-process)" +"(let-values()" +"(raise-arguments-error" +" 'compiled-expression-recompile" +" \"cycle in linklet imports\"))" +"(void))" +"(values))))" +"(let-values(((b_1)(recompiled-bundle r_0)))" +"(let-values(((linklet_0)" +"(let-values(((or-part_0)" +"(hash-ref" +"(linklet-bundle->hash b_1)" +" phase_0" +" #f)))" +"(if or-part_0" +" or-part_0" +"(raise-arguments-error" +" 'compiled-expression-recompile" +" \"cannot find submodule at phase\"" +" \"submodule\"" +" mod-name_0" +" \"phase\"" +" phase_0)))))" +"(module-linklet-info2.1" +" linklet_0" +"(hash-ref" +"(recompiled-phase-to-link-module-uses r_0)" +" phase_0" +" #f)" +"(recompiled-self r_0)" +" #f" +"(current-code-inspector)" +" #f))))))" +"(let-values() #f)))))))))" +"(let-values(((body-linklets+module-use*s_0)" +"(let-values(((ht_0) h_0))" +"(begin" +"(if(variable-reference-from-unsafe?(#%variable-reference))" +"(void)" +"(let-values()(check-in-hash ht_0)))" +"((letrec-values(((for-loop_0)" +"(lambda(table_0 i_0)" +"(begin" +" 'for-loop" +"(if i_0" +"(let-values(((phase_0 body-linklet_0)" +"(hash-iterate-key+value ht_0 i_0)))" +"(let-values(((table_1)" +"(let-values(((table_1) table_0))" +"(if(exact-integer? phase_0)" +"(let-values(((table_2)" +" table_1))" +"(let-values(((table_3)" +"(let-values()" +"(let-values(((key_0" +" val_0)" +"(let-values()" +"(let-values(((module-use*s_0)" +"(module-uses-add-extra-inspectorsss" +"(hash-ref" +" phase-to-link-modules_0" +" phase_0)" +" #f)))" +"(let-values(((linklet_0" +" new-module-use*s_0)" +"(let-values(((temp3_0)" +"(if(correlated-linklet?" +" body-linklet_0)" +"(correlated-linklet-expr" +" body-linklet_0)" +" body-linklet_0))" +"((temp4_0)" +"(if(correlated-linklet?" +" body-linklet_0)" +" 1/compile-linklet" +" 1/recompile-linklet))" +"((temp5_0)" +"(list" +"(list" +" get-syntax-literal!-id)" +"(list" +" set-transformer!-id)))" +"((temp6_0)" +"(list" +" empty-syntax-literals-instance" +" empty-module-body-instance))" +"((find-submodule7_0)" +" find-submodule_0)" +"((temp8_0)" +" #t)" +"((module-use*s9_0)" +" module-use*s_0)" +"((temp10_0)" +" #t)" +"((ns11_0)" +" ns_0))" +"(compile-module-linklet51.1" +" temp6_0" +" temp5_0" +" temp4_0" +" temp10_0" +" find-submodule7_0" +" module-use*s9_0" +" ns11_0" +" temp8_0" +" temp3_0))))" +"(values" +" phase_0" +"(cons" +" linklet_0" +" new-module-use*s_0)))))))" +"(hash-set" +" table_2" +" key_0" +" val_0)))))" +"(values table_3)))" +" table_1))))" +"(if(not #f)" +"(for-loop_0" +" table_1" +"(hash-iterate-next ht_0 i_0))" +" table_1)))" +" table_0)))))" +" for-loop_0)" +" '#hash()" +"(hash-iterate-first ht_0))))))" +"(let-values(((h/new-body-linklets_0)" +"(let-values(((ht_0) body-linklets+module-use*s_0))" +"(begin" +"(if(variable-reference-from-unsafe?(#%variable-reference))" +"(void)" +"(let-values()(check-in-hash ht_0)))" +"((letrec-values(((for-loop_0)" +"(lambda(h_1 i_0)" +"(begin" +" 'for-loop" +"(if i_0" +"(let-values(((phase_0 l+mu*s_0)" +"(hash-iterate-key+value" +" ht_0" +" i_0)))" +"(let-values(((h_2)" +"(let-values(((h_2) h_1))" +"(let-values(((h_3)" +"(let-values()" +"(hash-set" +" h_2" +" phase_0" +"(car" +" l+mu*s_0)))))" +"(values h_3)))))" +"(if(not #f)" +"(for-loop_0" +" h_2" +"(hash-iterate-next ht_0 i_0))" +" h_2)))" +" h_1)))))" +" for-loop_0)" +" h_0" +"(hash-iterate-first ht_0))))))" +"(let-values(((phase-to-link-module-uses_0)" +"(let-values(((ht_0) body-linklets+module-use*s_0))" +"(begin" +"(if(variable-reference-from-unsafe?(#%variable-reference))" +"(void)" +"(let-values()(check-in-hash ht_0)))" +"((letrec-values(((for-loop_0)" +"(lambda(table_0 i_0)" +"(begin" +" 'for-loop" +"(if i_0" +"(let-values(((phase_0 l+mu*s_0)" +"(hash-iterate-key+value" +" ht_0" +" i_0)))" +"(let-values(((table_1)" +"(let-values(((table_1)" +" table_0))" +"(let-values(((table_2)" +"(let-values()" +"(let-values(((key_0" +" val_0)" +"(let-values()" +"(values" +" phase_0" +"(module-uses-strip-extra-inspectorsss" +"(cdr" +" l+mu*s_0))))))" +"(hash-set" +" table_1" +" key_0" +" val_0)))))" +"(values table_2)))))" +"(if(not #f)" +"(for-loop_0" +" table_1" +"(hash-iterate-next ht_0 i_0))" +" table_1)))" +" table_0)))))" +" for-loop_0)" +" '#hasheq()" +"(hash-iterate-first ht_0))))))" +"(let-values(((phase-to-link-module-uses-expr_0)" +"(serialize-phase-to-link-module-uses" +" phase-to-link-module-uses_0" +" mpis_0)))" +"(let-values(((data-linklet_0)" +"(1/compile-linklet(generate-module-data-linklet mpis_0) 'data)))" +"(let-values(((declaration-linklet_0)" +"(1/compile-linklet" +"(generate-module-declaration-linklet" +" mpis_0" +" self_0" +"(decl_0 'requires)" +"(decl_0 'provides)" +" phase-to-link-module-uses-expr_0)" +" 'decl)))" +"(let-values(((new-bundle_0)" +"(hash->linklet-bundle" +"(let-values(((h_1) h/new-body-linklets_0))" +"(let-values(((h_2)(hash-set h_1 'data data-linklet_0)))" +"(let-values(((h_3)" +"(hash-set h_2 'decl declaration-linklet_0)))" +" h_3))))))" +"(recompiled1.1" +" new-bundle_0" +" phase-to-link-module-uses_0" +" self_0))))))))))))))))))))))" "(define-values" "(create-compiled-in-memorys-using-shared-data)" "(lambda(tops_0 data-linklet_0 ns_0)"