diff --git a/pkgs/racket-test-core/tests/racket/namespac.rktl b/pkgs/racket-test-core/tests/racket/namespac.rktl index d57e5595e5..d08b1402c9 100644 --- a/pkgs/racket-test-core/tests/racket/namespac.rktl +++ b/pkgs/racket-test-core/tests/racket/namespac.rktl @@ -147,7 +147,7 @@ (test #f variable-reference->module-path-index (#%variable-reference test)) -(test (module-path-index-join ''#%runtime #f) +(test (module-path-index-join ''#%kernel #f) variable-reference->module-path-index (#%variable-reference +)) (require (only-in racket/unsafe/ops [unsafe-fx+ $$unsafe-fx+])) diff --git a/racket/collects/ffi/unsafe/objc.rkt b/racket/collects/ffi/unsafe/objc.rkt index 2ce50374da..d1d7259b97 100644 --- a/racket/collects/ffi/unsafe/objc.rkt +++ b/racket/collects/ffi/unsafe/objc.rkt @@ -98,8 +98,10 @@ (define (strcpy s) (let* ([n (cast s _string _bytes)] - [p (malloc 'raw (add1 (bytes-length n)))]) - (memcpy p n (add1 (bytes-length n))) + [len (bytes-length n)] + [p (malloc 'raw (add1 len))]) + (memcpy p n len) + (ptr-set! p _byte len 0) p)) (define (allocate-class-pair-the-hard-way superclass name) @@ -508,7 +510,7 @@ [send send/typed] [(send-arg ...) send-args]) (quasisyntax/loc stx - ((send (type-vector #,result-type type ...)) + ((send (type-vector '(tag ...) #,result-type type ...)) send-arg ... #,(register-selector (combine #'(tag ...))) arg ...))))) @@ -530,13 +532,13 @@ (let ([m #'method]) (check-method-name m stx) (quasisyntax/loc stx - ((objc_msgSend/typed (type-vector t)) target #,(register-selector (syntax-e m)))))] + ((objc_msgSend/typed (type-vector 'method t)) target #,(register-selector (syntax-e m)))))] [(_ target method) (not (keyword? (syntax-e #'target))) (let ([m #'method]) (check-method-name m stx) (quasisyntax/loc stx - ((objc_msgSend/typed (type-vector _id)) target #,(register-selector (syntax-e m)))))] + ((objc_msgSend/typed (type-vector 'method _id)) target #,(register-selector (syntax-e m)))))] [(_ #:type result-type target method/arg ...) (build-send stx #'result-type #'objc_msgSend/typed #'(target) @@ -561,37 +563,39 @@ prims))))) (define-syntax (type-vector stx) - (let ([types (cdr (syntax->list stx))]) - (let ([vec-exp (quasisyntax/loc stx (vector . #,types))] - [type-exprs (cdr (syntax->list stx))]) - (cond - [(andmap liftable-type? type-exprs) - ;; Recognized types => simple lift - (syntax-local-lift-expression #`(intern-type-vector #,vec-exp))] - [(andmap (lambda (type-expr) - (and (identifier? type-expr) - (pair? (identifier-binding type-expr)))) - type-exprs) - ;; Types bound as imports => lift with cache and `#%variable-reference-constant?` check - (let* ([expanded-type-exprs - (map (lambda (type-expr) - (local-expand type-expr 'expression #f)) - type-exprs)] - [expanded-vec-exp #`(vector . #,expanded-type-exprs)]) - (cond - [(andmap identifier? expanded-type-exprs) - (let ([saved-vector-id (syntax-local-lift-expression #'(box #f))]) - (quasisyntax/loc stx - (or (unbox #,saved-vector-id) - (maybe-cache-type-vector-in-box - #,expanded-vec-exp - #,saved-vector-id - (vector #,@(for/list ([expanded-type-expr (in-list expanded-type-exprs)]) - #`(variable-reference-constant? (#%variable-reference #,expanded-type-expr))))))))] - [else expanded-vec-exp]))] - [else - ;; General case: construct type vector every time - vec-exp])))) + (syntax-case stx () + [(_ who . types) + (let* ([type-exprs (syntax->list #'types)] + [vec-exp (quasisyntax/loc stx (vector . #,type-exprs))]) + (cond + [(andmap liftable-type? type-exprs) + ;; Recognized types => simple lift + (syntax-local-lift-expression #`(intern-type-vector #,vec-exp))] + [(andmap (lambda (type-expr) + (and (identifier? type-expr) + (pair? (identifier-binding type-expr)))) + type-exprs) + ;; Types bound as imports => lift with cache and `#%variable-reference-constant?` check + (let* ([expanded-type-exprs + (map (lambda (type-expr) + (local-expand type-expr 'expression #f)) + type-exprs)] + [expanded-vec-exp #`(vector . #,expanded-type-exprs)]) + (cond + [(andmap identifier? expanded-type-exprs) + (let ([saved-vector-id (syntax-local-lift-expression #'(box #f))]) + (quasisyntax/loc stx + (or (unbox #,saved-vector-id) + (maybe-cache-type-vector-in-box + who + #,expanded-vec-exp + #,saved-vector-id + (vector #,@(for/list ([expanded-type-expr (in-list expanded-type-exprs)]) + #`(variable-reference-constant? (#%variable-reference #,expanded-type-expr))))))))] + [else expanded-vec-exp]))] + [else + ;; General case: construct type vector every time + vec-exp]))])) (define type-vectors (make-hash)) (define (intern-type-vector v) @@ -600,10 +604,15 @@ (hash-set! type-vectors v v) v))) -(define (maybe-cache-type-vector-in-box vec saved-vec-box const?s) - (when (for/and ([c? (in-vector const?s)]) - c?) - (set-box! saved-vec-box vec)) +(define-logger ffi/unsafe/objc) + +(define (maybe-cache-type-vector-in-box who vec saved-vec-box const?s) + (cond + [(for/and ([c? (in-vector const?s)]) + c?) + (set-box! saved-vec-box vec)] + [else + (log-ffi/unsafe/objc-debug "not a known-constant type vector for ~s" who)]) vec) ;; ---------------------------------------- @@ -907,7 +916,7 @@ (let ([m #'method]) (check-method-name m stx) (quasisyntax/loc stx - ((objc_msgSendSuper/typed (type-vector t)) + ((objc_msgSendSuper/typed (type-vector 'method t)) (make-objc_super self super-class) #,(register-selector (syntax-e m)))))] [(_ method) @@ -915,7 +924,7 @@ (let ([m #'method]) (check-method-name m stx) (quasisyntax/loc stx - ((objc_msgSendSuper/typed (type-vector _id)) + ((objc_msgSendSuper/typed (type-vector 'method _id)) (make-objc_super self super-class) #,(register-selector (syntax-e m)))))] [(_ #:type result-type method/arg ...) diff --git a/racket/src/cs/Makefile b/racket/src/cs/Makefile index adc27acdb9..db44c75d8b 100644 --- a/racket/src/cs/Makefile +++ b/racket/src/cs/Makefile @@ -5,7 +5,7 @@ RACKET = ../../bin/racket SCHEME = scheme # Controls whether Racket layers are built as unsafe: -UNSAFE_COMP = # --unsafe +UNSAFE_COMP = --unsafe # Controls whether Racket layers are built with expression-level debugging: DEBUG_COMP = # --debug diff --git a/racket/src/cs/linklet.sls b/racket/src/cs/linklet.sls index 456cfdc112..06db3eb4c3 100644 --- a/racket/src/cs/linklet.sls +++ b/racket/src/cs/linklet.sls @@ -229,9 +229,10 @@ (define (code-from-bytevector bv) (let ([i (open-bytevector-input-port bv)]) - (performance-region - 'outer - ((load-compiled-from-port i))))) + (let ([r (load-compiled-from-port i)]) + (performance-region + 'outer + (r))))) (define-values (lookup-code insert-code delete-code) (let ([get-procs!-maker @@ -757,7 +758,7 @@ (linklet-bundle-hash b)) (define-record variable-reference (instance ; the use-site instance - var-or-info)) ; the referenced variable + var-or-info)) ; the referenced variable, 'constant, 'mutable, #f, or 'primitive (define variable-reference->instance (case-lambda @@ -775,12 +776,21 @@ (if (eq? i #!bwp) (variable-reference->instance vr #t) i))] + [(eq? v 'primitive) + ;; FIXME: We don't have the right primitive instance name + ;; ... but '#%kernel is usually right. + '|#%kernel|] [else ;; Local variable, so same as use-site (variable-reference->instance vr #t)]))])) (define (variable-reference-constant? vr) - (eq? (variable-reference-var-or-info vr) 'constant)) + (let ([v (variable-reference-var-or-info vr)]) + (cond + [(variable? v) + (and (variable-constance v) #t)] + [(eq? v 'mutable) #f] + [else (and v #t)]))) (define (variable-reference-from-unsafe? vr) #f) diff --git a/racket/src/cs/linklet/performance.ss b/racket/src/cs/linklet/performance.ss index 57f5243055..747e14193e 100644 --- a/racket/src/cs/linklet/performance.ss +++ b/racket/src/cs/linklet/performance.ss @@ -43,15 +43,19 @@ (define (linklet-performance-report!) (when measure-performance? - (let ([total 0]) + (let* ([total (apply + (hash-table-map region-times (lambda (k v) (round (inexact->exact v)))))] + [gc-total (apply + (hash-table-map region-gc-times (lambda (k v) v)))] + [name-len (apply max (hash-table-map region-times (lambda (k v) (string-length (symbol->string k)))))] + [len (string-length (number->string total))] + [gc-len (string-length (number->string gc-total))]) (define (pad v w) (let ([s (chez:format "~a" v)]) (string-append (make-string (max 0 (- w (string-length s))) #\space) s))) (define (report label n n-extra units extra) - (chez:printf ";; ~a: ~a~a ~a~a\n" - (pad label 15) - (pad (round (inexact->exact n)) 5) + (chez:printf ";; ~a: ~a~a ~a~a\n" + (pad label name-len) + (pad (round (inexact->exact n)) len) n-extra units extra)) @@ -61,16 +65,15 @@ (for-each (lambda (p) (let ([label (car p)] [n (cdr p)]) - (set! total (+ total n)) (report label n - (chez:format " [~a]" (pad (hashtable-ref region-gc-times label 0) 5)) + (chez:format " [~a]" (pad (hashtable-ref region-gc-times label 0) gc-len)) 'ms (let ([c (hashtable-ref region-counts label 0)]) (if (zero? c) "" (chez:format " ; ~a times" c)))))) (ht->sorted-list region-times)) - (report 'total total "" 'ms "") + (report 'total total (#%format " [~a]" gc-total) 'ms "") (chez:printf ";;\n") (for-each (lambda (p) (report (car p) (/ (cdr p) 1024 1024) "" 'MB "")) (ht->sorted-list region-memories))))) diff --git a/racket/src/expander/expand/expr.rkt b/racket/src/expander/expand/expr.rkt index 9581632d71..1b49d12999 100644 --- a/racket/src/expander/expand/expr.rkt +++ b/racket/src/expander/expand/expr.rkt @@ -737,10 +737,9 @@ (raise-syntax-error #f "identifier does not refer to a variable" var-id s)) (if (expand-context-to-parsed? ctx) (parsed-#%variable-reference (keep-properties-only~ s) - ;; Intentionally not using `parsed-primitive-id`; - ;; see also `variable-reference->namespace` (cond [(top-m) (parsed-top-id var-id binding #f)] + [primitive? (parsed-primitive-id var-id binding #f)] [else (parsed-id var-id binding #f)])) s)] [else diff --git a/racket/src/expander/namespace/variable-reference.rkt b/racket/src/expander/namespace/variable-reference.rkt index 0b736929f8..33d3c60571 100644 --- a/racket/src/expander/namespace/variable-reference.rkt +++ b/racket/src/expander/namespace/variable-reference.rkt @@ -38,8 +38,7 @@ (cond [(symbol? inst) ;; This case happens for `(#%variable-reference id)` where `id` - ;; refers directly to a primitive. The expander doesn't currently - ;; generate that, but just in case... We get a namespace for a + ;; refers directly to a primitive. We get a namespace for a ;; primitive instance; that might not be the same module as ;; reorted by `identifier-binding`, but close enough. (module->namespace `',inst (instance-data (variable-reference->instance vr #t)))] diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index f8ac77364d..68cba4993a 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -3701,12 +3701,14 @@ static Scheme_Object *ffi_call_or_curry(const char *who, int curry, int argc, Sc GC_CAN_IGNORE ffi_cif *cif; int i, nargs, save_errno; Scheme_Object *lock = scheme_false; + Scheme_Performance_State perf_state; # ifdef MZ_USE_PLACES int orig_place = MZ_USE_FFIPOLL_COND; # define FFI_CALL_VEC_SIZE 9 # else /* MZ_USE_PLACES undefined */ # define FFI_CALL_VEC_SIZE 8 # endif /* MZ_USE_PLACES */ + scheme_performance_record_start(&perf_state); if (!curry) { cp = unwrap_cpointer_property(argv[ARGPOS(0)]); if (!SCHEME_FFIANYPTRP(cp)) @@ -3784,6 +3786,8 @@ static Scheme_Object *ffi_call_or_curry(const char *who, int curry, int argc, Sc scheme_register_finalizer(data, free_fficall_data, cif, NULL, NULL); a[0] = data; + scheme_performance_record_end("comp-ffi", &perf_state); + if (curry) { return scheme_make_prim_closure_w_arity(make_ffi_call_from_curried, 1, a, @@ -4137,6 +4141,7 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc GC_CAN_IGNORE closure_and_cif *cl_cif_args; GC_CAN_IGNORE ffi_callback_t do_callback; GC_CAN_IGNORE void *callback_data; + Scheme_Performance_State perf_state; # ifdef MZ_USE_MZRT int keep_queue = 0; void *constant_reply = NULL; @@ -4164,6 +4169,8 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc return NULL; } + scheme_performance_record_start(&perf_state); + if (((argc > ARGPOS(5)) && SCHEME_TRUEP(argv[ARGPOS(5)]))) { # ifdef MZ_USE_MZRT if (!ffi_sync_queue) { @@ -4265,6 +4272,8 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc # endif /* MZ_USE_MZRT */ scheme_register_finalizer(data, free_cl_cif_args, cl_cif_args, NULL, NULL); + scheme_performance_record_end("comp-ffi-back", &perf_state); + return (Scheme_Object*)data; #undef ARGPOS } diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index 993f020e56..147fa70a53 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -2872,12 +2872,14 @@ static Scheme_Object *ffi_call_or_curry(const char *who, int curry, int argc, Sc GC_CAN_IGNORE ffi_cif *cif; int i, nargs, save_errno; Scheme_Object *lock = scheme_false; + Scheme_Performance_State perf_state; @@@IFDEF{MZ_USE_PLACES}{ int orig_place = MZ_USE_FFIPOLL_COND; @DEFINE{FFI_CALL_VEC_SIZE 9} }{ @DEFINE{FFI_CALL_VEC_SIZE 8} } + scheme_performance_record_start(&perf_state); if (!curry) { cp = unwrap_cpointer_property(argv[ARGPOS(0)]); if (!SCHEME_FFIANYPTRP(cp)) @@ -2955,6 +2957,8 @@ static Scheme_Object *ffi_call_or_curry(const char *who, int curry, int argc, Sc scheme_register_finalizer(data, free_fficall_data, cif, NULL, NULL); a[0] = data; + scheme_performance_record_end("comp-ffi", &perf_state); + if (curry) { return scheme_make_prim_closure_w_arity(make_ffi_call_from_curried, 1, a, @@ -3298,6 +3302,7 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc GC_CAN_IGNORE closure_and_cif *cl_cif_args; GC_CAN_IGNORE ffi_callback_t do_callback; GC_CAN_IGNORE void *callback_data; + Scheme_Performance_State perf_state; @@IFDEF{MZ_USE_MZRT}{ int keep_queue = 0; void *constant_reply = NULL; @@ -3324,6 +3329,8 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc /* all checks are done */ return NULL; } + + scheme_performance_record_start(&perf_state); if (((argc > ARGPOS(5)) && SCHEME_TRUEP(argv[ARGPOS(5)]))) { @@IFDEF{MZ_USE_MZRT}{ @@ -3422,6 +3429,8 @@ static Scheme_Object *ffi_callback_or_curry(const char *who, int curry, int argc } scheme_register_finalizer(data, free_cl_cif_args, cl_cif_args, NULL, NULL); + scheme_performance_record_end("comp-ffi-back", &perf_state); + return (Scheme_Object*)data; #undef ARGPOS } diff --git a/racket/src/racket/src/jitstate.c b/racket/src/racket/src/jitstate.c index 107a4ad46a..fed3104ebb 100644 --- a/racket/src/racket/src/jitstate.c +++ b/racket/src/racket/src/jitstate.c @@ -218,6 +218,7 @@ void *scheme_generate_one(mz_jit_state *old_jitter, intptr_t size_pre_retained = 0, size_pre_retained_double = 0, num_retained = 0, num_retained_double = 0, padding; int mappings_size = JIT_INIT_MAPPINGS_SIZE; int ok, max_extra_pushed = 0; + Scheme_Performance_State perf_state; #ifdef SET_DEFAULT_LONG_JUMPS int use_long_jumps = default_long_jumps; #endif @@ -232,6 +233,8 @@ void *scheme_generate_one(mz_jit_state *old_jitter, fnl_obj = NULL; #endif + scheme_performance_record_start(&perf_state); + if (!jit_buffer_cache_registered) { jit_buffer_cache_registered = 1; REGISTER_SO(jit_buffer_cache); @@ -316,6 +319,7 @@ void *scheme_generate_one(mz_jit_state *old_jitter, then switch over to long-jump mode. */ if (check_long_mode((uintptr_t)buffer, size)) { /* start over */ + scheme_performance_record_end("jit", &perf_state); return scheme_generate_one(old_jitter, generate, data, gcable, save_ptr, ndata); } @@ -368,6 +372,7 @@ void *scheme_generate_one(mz_jit_state *old_jitter, if (!use_long_jumps) { if (check_long_mode((uintptr_t)buffer, size)) { /* start over */ + scheme_performance_record_end("jit", &perf_state); return scheme_generate_one(old_jitter, generate, data, gcable, save_ptr, ndata); } @@ -431,6 +436,7 @@ void *scheme_generate_one(mz_jit_state *old_jitter, if (known_size) { /* That was in the permanent area, so return: */ jit_flush_code(buffer, jit_get_raw_ip()); + scheme_performance_record_end("jit", &perf_state); return buffer; } else { /* Allocate permanent area and jit again: */ diff --git a/racket/src/racket/src/linklet.c b/racket/src/racket/src/linklet.c index 9b5731eca4..8f89c6f221 100644 --- a/racket/src/racket/src/linklet.c +++ b/racket/src/racket/src/linklet.c @@ -1166,6 +1166,9 @@ static Scheme_Linklet *compile_and_or_optimize_linklet(Scheme_Object *form, Sche { Scheme_Config *config; int enforce_const, set_undef, can_inline; + Scheme_Performance_State perf_state; + + scheme_performance_record_start(&perf_state); config = scheme_current_config(); enforce_const = SCHEME_TRUEP(scheme_get_param(config, MZCONFIG_COMPILE_MODULE_CONSTS)); @@ -1202,6 +1205,8 @@ static Scheme_Linklet *compile_and_or_optimize_linklet(Scheme_Object *form, Sche if (validate_compile_result) scheme_validate_linklet(NULL, linklet); + scheme_performance_record_end("compile", &perf_state); + return linklet; } @@ -1351,6 +1356,9 @@ static void *instantiate_linklet_k(void) int depth; Scheme_Object *b, *v; Scheme_Hash_Tree *source_names; + Scheme_Performance_State perf_state; + + scheme_performance_record_start(&perf_state); p->ku.k.p1 = NULL; p->ku.k.p2 = NULL; @@ -1403,6 +1411,8 @@ static void *instantiate_linklet_k(void) if (!multi) v = scheme_check_one_value(v); + scheme_performance_record_end("instantiate", &perf_state); + return (void *)v; } @@ -1713,6 +1723,200 @@ int check_pruned_prefix(void *p) XFORM_SKIP_PROC } #endif +/*========================================================================*/ +/* Recorindg performance times */ +/*========================================================================*/ + +static intptr_t nested_delta, nested_gc_delta; +static int perf_reg, perf_count; + +typedef struct { + const char *name; + intptr_t accum; + intptr_t gc_accum; + intptr_t count; +} Performance_Entry; + +#define MAX_PERF_ENTRIES 16 + +static Performance_Entry perf_entries[MAX_PERF_ENTRIES]; + +static char *do_tab(int len, char *tab, int max_len) +{ + int i; + + len = max_len - len; + if (len < 0) + len = 0; + for (i = 0; i < len; i++) { + tab[i] = ' '; + } + tab[i] = 0; + + return tab; +} + +static int numlen(intptr_t n) +{ + int len = 1; + + while (n >= 10) { + n = n / 10; + len++; + } + + return len; +} + +static char *tab_number(intptr_t n, char *tab, int max_len) +{ + return do_tab(numlen(n), tab, max_len); +} + +static char *tab_string(const char *s, char *tab, int max_len) +{ + return do_tab(strlen(s), tab, max_len); +} + +static void sort_perf(int lo, int hi) +{ + int i, pivot; + + if (lo >= hi) + return; + + pivot = lo; + for (i = lo + 1; i < hi; i++) { + if (perf_entries[i].accum < perf_entries[pivot].accum) { + Performance_Entry tmp = perf_entries[pivot]; + perf_entries[pivot] = perf_entries[i]; + perf_entries[i] = perf_entries[pivot+1]; + perf_entries[pivot+1] = tmp; + pivot++; + } + } + + sort_perf(lo, pivot); + sort_perf(pivot+1, hi); +} + +static void show_perf() +{ + intptr_t total = 0, gc_total = 0; + int i, name_len = 0, len, gc_len; + char name_tab[16], tab[10], gc_tab[10]; + + sort_perf(0, perf_count); + + for (i = 0; i < perf_count; i++) { + len = strlen(perf_entries[i].name); + if (len > name_len) name_len = len; + total += perf_entries[i].accum; + gc_total += perf_entries[i].gc_accum; + } + + len = numlen(total); + gc_len = numlen(gc_total); + + if (name_len >= sizeof(name_tab)) + name_len = sizeof(name_tab) - 1; + if (len >= sizeof(tab)) + len = sizeof(tab) - 1; + if (gc_len >= sizeof(gc_tab)) + gc_len = sizeof(gc_tab) -1; + + for (i = 0; i < perf_count; i++) { + fprintf(stderr, ";; %s%s: %s%"PRIdPTR " [%s%"PRIdPTR"] ms ; %"PRIdPTR" times\n", + tab_string(perf_entries[i].name, name_tab, name_len), + perf_entries[i].name, + tab_number(perf_entries[i].accum, tab, len), + perf_entries[i].accum, + tab_number(perf_entries[i].gc_accum, gc_tab, gc_len), + perf_entries[i].gc_accum, + perf_entries[i].count); + } + + fprintf(stderr, ";; %stotal: %s%"PRIdPTR " [%s%"PRIdPTR"] ms\n", + tab_string("total", name_tab, name_len), + tab_number(total, tab, len), + total, + tab_number(gc_total, gc_tab, gc_len), + gc_total); +} + +void scheme_performance_record_start(GC_CAN_IGNORE Scheme_Performance_State *perf_state) +{ +#if defined(MZ_USE_PLACES) + if (scheme_current_place_id != 0) + return; +#endif + + if (!perf_reg) { + if (scheme_getenv("PLT_LINKLET_TIMES")) { + perf_reg = 1; + scheme_atexit(show_perf); + } else { + perf_reg = -1; + } + } + + if (perf_reg < 0) + return; + + perf_state->gc_start = scheme_total_gc_time; + perf_state->start = scheme_get_process_milliseconds(); + perf_state->old_nested_delta = nested_delta; + perf_state->old_nested_gc_delta = nested_gc_delta; + + nested_delta = 0; + nested_gc_delta = 0; +} + +void scheme_performance_record_end(const char *who, GC_CAN_IGNORE Scheme_Performance_State *perf_state) +{ + int i; + intptr_t d, gc_d; + +#if defined(MZ_USE_PLACES) + if (scheme_current_place_id != 0) + return; +#endif + + if (perf_reg < 0) + return; + + for (i = 0; i < MAX_PERF_ENTRIES; i++) { + if (perf_entries[i].name) { + if (!strcmp(perf_entries[i].name, who)) + break; + } else + break; + } + + if (i >= MAX_PERF_ENTRIES) + return; + + d = (scheme_get_process_milliseconds() - perf_state->start); + gc_d = (scheme_total_gc_time - perf_state->gc_start); + + perf_state->old_nested_delta += d; + perf_state->old_nested_gc_delta += gc_d; + + d -= nested_delta; + gc_d -= nested_gc_delta; + + nested_delta = perf_state->old_nested_delta; + nested_gc_delta = perf_state->old_nested_gc_delta; + + if (!perf_entries[i].name) { + perf_entries[i].name = who; + perf_count++; + } + perf_entries[i].accum += d; + perf_entries[i].gc_accum += gc_d; + perf_entries[i].count++; +} + /*========================================================================*/ /* precise GC traversers */ /*========================================================================*/ diff --git a/racket/src/racket/src/read.c b/racket/src/racket/src/read.c index 2ebbc8d037..01115180db 100644 --- a/racket/src/racket/src/read.c +++ b/racket/src/racket/src/read.c @@ -3854,7 +3854,10 @@ static Scheme_Object *read_compiled(Scheme_Object *port, Scheme_Object *dir; Scheme_Config *config; char hash_code[20]; - + Scheme_Performance_State perf_state; + + scheme_performance_record_start(&perf_state); + while (1) { bundle_pos = SCHEME_INT_VAL(scheme_file_position(1, &port)) - 2; /* -2 for "#~" */ @@ -4125,11 +4128,14 @@ static Scheme_Object *read_compiled(Scheme_Object *port, v = bundle_list_to_hierarchical_directory(bundles); if (!v) scheme_read_err(port, "read (compiled): bad shape for bundle-directory tree"); + scheme_performance_record_end("read", &perf_state); return v; } /* otherwise, continue reading bundles */ - } else + } else { + scheme_performance_record_end("read", &perf_state); return result; + } } else { scheme_read_err(port, "read (compiled): found bad mode"); } @@ -4163,6 +4169,7 @@ static Scheme_Object *read_compiled(Scheme_Object *port, v = bundle_list_to_hierarchical_directory(bundles); if (!v) scheme_read_err(port, "read (compiled): bad shape for bundle-directory tree"); + scheme_performance_record_end("read", &perf_state); return v; } } else { @@ -4226,7 +4233,10 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in Scheme_Object * volatile v_exn; Scheme_Hash_Table ** volatile ht; mz_jmp_buf newbuf, * volatile savebuf; + Scheme_Performance_State perf_state; + scheme_performance_record_start(&perf_state); + /* Remove from cache-clearing chain: */ if (!delay_info->perma_cache) { if (delay_info->clear_bytes_prev) @@ -4353,7 +4363,9 @@ Scheme_Object *scheme_load_delayed_code(int _which, Scheme_Load_Delay *_delay_in } scheme_end_atomic_no_swap(); - + + scheme_performance_record_end("demand-read", &perf_state); + if (v) { /* Although `which` is a symbol-table index for `v`, we don't actually record v, because the delayed diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 52964c4dda..6dd64abd15 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -3847,6 +3847,14 @@ void *scheme_environment_variables_to_block(Scheme_Object *env, int *_need_free) int scheme_compare_equal(void *v1, void *v2); +typedef struct Scheme_Performance_State { + intptr_t start, gc_start; + intptr_t old_nested_delta, old_nested_gc_delta; +} Scheme_Performance_State; + +void scheme_performance_record_start(Scheme_Performance_State *perf_state); +void scheme_performance_record_end(const char *who, Scheme_Performance_State *perf_state); + /*========================================================================*/ /* places */ /*========================================================================*/ diff --git a/racket/src/racket/src/startup.inc b/racket/src/racket/src/startup.inc index 2a7b9209d6..5ba2728499 100644 --- a/racket/src/racket/src/startup.inc +++ b/racket/src/racket/src/startup.inc @@ -67960,7 +67960,9 @@ static const char *startup_source = "(keep-properties-only~ s_720)" "(if ok?_61" "(let-values()(parsed-top-id4.1 var-id_0 binding_30 #f))" -"(let-values()(parsed-id2.1 var-id_0 binding_30 #f))))" +"(if primitive?_12" +"(let-values()(parsed-primitive-id3.1 var-id_0 binding_30 #f))" +"(let-values()(parsed-id2.1 var-id_0 binding_30 #f)))))" " s_720))))))))" "(let-values()" "(if(expand-context-to-parsed? ctx_103)" diff --git a/racket/src/schemify/schemify.rkt b/racket/src/schemify/schemify.rkt index 69793959d4..0b531c1529 100644 --- a/racket/src/schemify/schemify.rkt +++ b/racket/src/schemify/schemify.rkt @@ -479,11 +479,20 @@ `(,(if allow-set!-undefined? 'variable-set! 'variable-set!/check-undefined) ,(export-id ex) ,(schemify rhs) '#f) `(set! ,id ,(schemify rhs)))] [`(variable-reference-constant? (#%variable-reference ,id)) - (let ([id (unwrap id)]) - (and (not (hash-ref mutated id #f)) - (let ([im (hash-ref imports id #f)]) - (or (not im) - (known-constant? (import-lookup im))))))] + (define u-id (unwrap id)) + (cond + [(hash-ref mutated u-id #f) #f] + [else + (define im (hash-ref imports u-id #f)) + (cond + [(not im) + ;; Not imported and not mutable => a constant or local defined + ;; in this linklet or a direct primitive reference + #t] + [(known-constant? (import-lookup im)) #t] + [else + ;; Not statically known + `(variable-reference-constant? ,(schemify `(#%variable-reference ,id)))])])] [`(variable-reference-from-unsafe? (#%variable-reference)) unsafe-mode?] [`(#%variable-reference) @@ -500,9 +509,10 @@ ,v) `(make-instance-variable-reference instance-variable-reference - ',(if (hash-ref mutated u #f) - 'mutable - 'immutable)))] + ',(cond + [(hash-ref mutated u #f) 'mutable] + [(hash-ref prim-knowns u #f) 'primitive] + [else 'constant])))] [`(equal? ,exp1 ,exp2) (let ([exp1 (schemify exp1)] [exp2 (schemify exp2)])