diff --git a/pkgs/racket-doc/scribblings/foreign/intro.scrbl b/pkgs/racket-doc/scribblings/foreign/intro.scrbl index 2ffa2711a4..0a9c1cedcb 100644 --- a/pkgs/racket-doc/scribblings/foreign/intro.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/intro.scrbl @@ -375,7 +375,7 @@ as the GC compacts allocated objects to avoid fragmentation. C functions, meanwhile, expect to receive pointers to objects that will stay put. -Fortunately, unless a C function calls back into the Racket run-time +Fortunately, unless a C function calls back into the Racket runtime system (perhaps through a function that is provided as an argument), no garbage collection will happen between the time that a C function is called and the time that the function returns. diff --git a/pkgs/racket-doc/scribblings/foreign/pointers.scrbl b/pkgs/racket-doc/scribblings/foreign/pointers.scrbl index 35e4e120ec..8bf3245f2f 100644 --- a/pkgs/racket-doc/scribblings/foreign/pointers.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/pointers.scrbl @@ -214,7 +214,7 @@ see @|InsideRacket|. cpointer?]{ Allocates a memory block of a specified size using a specified -allocation. The result is a @racket[cpointer] to the allocated +allocation. The result is a C pointer to the allocated memory, or @racket[#f] if the requested size is zero. Although not reflected above, the four arguments can appear in any order, since they are all different types of Racket objects; a size @@ -236,21 +236,99 @@ specification is required at minimum: the new block.} @item{A symbol @racket[mode] argument can be given, which specifies - what allocation function to use. It should be one of - @indexed-racket['nonatomic] (uses @cpp{scheme_malloc} from - Racket's C API), @indexed-racket['atomic] - (@cpp{scheme_malloc_atomic}), @indexed-racket['tagged] - (@cpp{scheme_malloc_tagged}), @indexed-racket['stubborn] - (@cpp{scheme_malloc_stubborn}), @indexed-racket['uncollectable] - (@cpp{scheme_malloc_uncollectable}), @indexed-racket['eternal] - (@cpp{scheme_malloc_eternal}), @indexed-racket['interior] - (@cpp{scheme_malloc_allow_interior}), - @indexed-racket['atomic-interior] - (@cpp{scheme_malloc_atomic_allow_interior}), or - @indexed-racket['raw] (uses the operating system's @cpp{malloc}, - creating a GC-invisible block).} @item{If an additional - @indexed-racket['failok] flag is given, then - @cpp{scheme_malloc_fail_ok} is used to wrap the call.} + what allocation function to use. It should be one of the following: + + @itemlist[ + + @item{@indexed-racket['raw] --- Allocates memory that is outside + the garbage collector's space and is not traced by the garbage + collector (i.e., is treated as holding no pointers to + collectable memory). This memory must be freed with + @racket[free].} + + @item{@indexed-racket['atomic] --- Allocates memory that can be + reclaimed by the garbage collector, is not traced by the + garbage collector, and is initially filled with zeros. + + For the @3m[] and @CGC[] Racket variants, this allocation mode corresponds + to @cpp{scheme_malloc_atomic} in the C API.} + + @item{@indexed-racket['nonatomic] --- Allocates memory that can + be reclaimed by the garbage collector, is treated by the + garbage collector as holding only pointers, and is initially + filled with zeros. + + For the @3m[] and @CGC[] Racket variants, this allocation mode corresponds + to @cpp{scheme_malloc} in the C API. + + For the @CS[] Racket variant, this mode is of limited use, + because a pointer allocated this way cannot be passed to + foreign functions that expect a pointer to pointers. The result + can only be used with functions like @racket[ptr-set!] and + @racket[ptr-ref].} + + @item{@indexed-racket['atomic-interior] --- Like + @racket['atomic], but the allocated object will not be moved by + the garbage collector as long as the allocated object is + sufficiently retained as described below. + + For the @3m[] and @CGC[] Racket variants, ``sufficiently retained'' + means that the garbage collector does not collect the allocated + object because some pointer (that is visible to the collector) + refers to the object. Furthermore, that reference can point to + the interior of the object, insteda of its starting address. + This allocation mode corresponds to + @cpp{scheme_malloc_atomic_allow_interior} in the C API. + + For the @CS[] Racket variant, ``sufficiently retained'' means that the + specific C pointer object returned by @racket[malloc] remains + accessible. Note that casting the pointer via @racket[cast], for example, + generates a new pointer object which would not by itself + prevent the result of @racket[malloc] from moving, even though + a reference to the same memory could prevent the object from + being reclaimed.} + + @item{@indexed-racket['nonatomic-interior] --- Like + @racket['nonatomic], but the allocated object will not be moved + by the garbage collector as long as the allocated object is + retained. + + This mode is supported only for the @3m[] and @CGC[] Racket variants, and + it corresponds to @cpp{scheme_malloc_allow_interior} in the C + API.} + + @item{@indexed-racket['tagged] --- Allocates memory that must + start with a @tt{short} value that is registered as a tag with + the garbage collector. + + This mode is supported only for the @3m[] and @CGC[] Racket variants, and + it corresponds to @cpp{scheme_malloc_tagged} in the C API.} + + @item{@indexed-racket['stubborn] --- Like @racket['nonatomic], + but supports a hint to the GC via @racket[end-stubborn-change] + after all changes to the object have been made. + + This mode is supported only for the @3m[] and @CGC[] Racket variants, and + it corresponds to @cpp{scheme_malloc_stubborn} in the C API.} + + @item{@indexed-racket['eternal] --- Like @racket['raw], except the + allocated memory cannot be freed. + + This mode is supported only for the @CGC[] Racket variant, and + it corresponds to @cpp{scheme_malloc_uncollectable} in the C API.} + + @item{@indexed-racket['uncollectable] --- Allocates memory that is + never collected, cannot be freed, and potentially contains + pointers to collectable memory. + + This mode is supported only for the @CGC[] Racket variant, and + it corresponds to @cpp{scheme_malloc_uncollectable} in the C API.} + + ]} + + @item{If an additional @indexed-racket['failok] flag is given, then + some effort may be made to detect an allocation failure and + raise @racket[exn:fail:out-of-memory] instead of crashing.} ] diff --git a/pkgs/racket-doc/scribblings/foreign/types.scrbl b/pkgs/racket-doc/scribblings/foreign/types.scrbl index 6117d50f59..11a7901cdb 100644 --- a/pkgs/racket-doc/scribblings/foreign/types.scrbl +++ b/pkgs/racket-doc/scribblings/foreign/types.scrbl @@ -564,8 +564,8 @@ For @tech{callouts} to foreign functions with the generated type: @item{If @racket[blocking?] is true, then a foreign @tech{callout} deactivates tracking of the calling OS thread---to the degree supported by the Racket variant---during the foreign call. The - value of @racket[blocking?] affects only the @tech[#:doc - guide.scrbl]{CS} variant of Racket, where it enable activity + value of @racket[blocking?] affects only the @CS[] variant of + Racket, where it enable activity such as garbage collection in other OS threads while the @tech{callout} blocks. If the blocking @tech{callout} can invoke any @tech{callbacks} back to Racket, those diff --git a/pkgs/racket-doc/scribblings/foreign/utils.rkt b/pkgs/racket-doc/scribblings/foreign/utils.rkt index ea51ae4c31..29d7e32ada 100644 --- a/pkgs/racket-doc/scribblings/foreign/utils.rkt +++ b/pkgs/racket-doc/scribblings/foreign/utils.rkt @@ -19,6 +19,7 @@ reference.scrbl ->> tech-place + 3m CGC CS (all-from-out scribble/manual) (for-label (all-from-out racket/base racket/contract @@ -44,3 +45,7 @@ (define (tech-place) (tech "place" #:doc '(lib "scribblings/reference/reference.scrbl"))) + +(define (CGC) (tech #:doc guide.scrbl "CGC")) +(define (3m) (tech #:doc guide.scrbl "3m")) +(define (CS) (tech #:doc guide.scrbl "CS")) diff --git a/pkgs/racket-doc/scribblings/guide/guide-utils.rkt b/pkgs/racket-doc/scribblings/guide/guide-utils.rkt index 2ddb96bd23..3a69d795ba 100644 --- a/pkgs/racket-doc/scribblings/guide/guide-utils.rkt +++ b/pkgs/racket-doc/scribblings/guide/guide-utils.rkt @@ -9,7 +9,7 @@ (require (for-label racket/base)) (provide (for-label (all-from-out racket/base))) -(provide Quick Racket HtDP +(provide Quick Racket HtDP inside-doc tool moreguide guideother @@ -66,6 +66,7 @@ (define Racket (other-manual '(lib "scribblings/reference/reference.scrbl"))) +(define inside-doc '(lib "scribblings/inside/inside.scrbl")) + (define r6rs @elem{R@superscript{6}RS}) (define r5rs @elem{R@superscript{5}RS}) - diff --git a/pkgs/racket-doc/scribblings/guide/performance.scrbl b/pkgs/racket-doc/scribblings/guide/performance.scrbl index 3a558c1822..8574c8d36a 100644 --- a/pkgs/racket-doc/scribblings/guide/performance.scrbl +++ b/pkgs/racket-doc/scribblings/guide/performance.scrbl @@ -20,7 +20,7 @@ machine level, the gap between the Racket language model and the underlying computing machinery can be quite large. In this chapter, we narrow the gap by explaining details of the -Racket compiler and run-time system and how they affect the run-time +Racket compiler and runtime system and how they affect the runtime and memory performance of Racket code. @; ---------------------------------------------------------------------- @@ -50,17 +50,63 @@ Non-interactive mode should be used instead of the @; ---------------------------------------------------------------------- +@section[#:tag "virtual-machines"]{Racket Virtual Machine Implementations} + +Racket is available in three implementation variants: @deftech{3m}, +@deftech{CGC}, and @deftech{CS}: + +@itemlist[ + + @item{@tech{3m} is the current default implementation, so it's + probably the one that you're using. + + For this variant, @racket[(system-type 'vm)] reports + @racket['racket] and @racket[(system-type 'gc)] reports + @racket['3m].} + + @item{@tech{CGC} is an older variant. It's the same basic + implementation as @tech{3m} (i.e., the same virtual machine), + but compiled to rely on a ``conservative'' garbage collector, + which affects the way that Racket interacts with C code. (See + @secref["CGC versus 3m" #:doc inside-doc] in + @other-manual[inside-doc] for more information.) + + For this variant, @racket[(system-type 'vm)] reports + @racket['racket] and @racket[(system-type 'gc)] reports + @racket['cgc].} + + @item{@tech{CS} is a newer implementation that builds on + @hyperlink["https://www.scheme.com/"]{Chez Scheme} as its core + virtual machine. This implementation performs better for some + programs, and it is likely to improve and eventually replace + the @tech{3m} implementation as the default. + + For this variant, @racket[(system-type 'vm)] reports + @racket['chez-scheme] and @racket[(system-type 'gc)] reports + @racket['cs].} + +] + +In general, Racket programs should run the same in all variants. +Furthermore, the performance characteristics of Racket program should +be similar in the @tech{3m} and @tech{CS} variants. The cases where a +program may depends on the variant will typically involve interactions +with foreign libraries; in particular, the Racket C API described in +@other-doc[inside-doc] is available only for the virtual machine of +the @tech{3m} and @tech{CGC} variants. + +@; ---------------------------------------------------------------------- + @section[#:tag "JIT"]{The Bytecode and Just-in-Time (JIT) Compilers} Every definition or expression to be evaluated by Racket is compiled -to an internal bytecode format. In interactive mode, this compilation -occurs automatically and on-the-fly. Tools like @exec{raco make} and +to an internal bytecode format, although ``bytecode'' may actually be +native machine code. In interactive mode, this compilation occurs +automatically and on-the-fly. Tools like @exec{raco make} and @exec{raco setup} marshal compiled bytecode to a file, so that you do -not have to compile from source every time that you run a -program. (Most of the time required to compile a file is actually in -macro expansion; generating bytecode from fully expanded code is -relatively fast.) See @secref["compile"] for more information on -generating bytecode files. +not have to compile from source every time that you run a program. +See @secref["compile"] for more information on generating +bytecode files. The bytecode compiler applies all standard optimizations, such as constant propagation, constant folding, inlining, and dead-code @@ -68,14 +114,25 @@ elimination. For example, in an environment where @racket[+] has its usual binding, the expression @racket[(let ([x 1] [y (lambda () 4)]) (+ 1 (y)))] is compiled the same as the constant @racket[5]. -On some platforms, bytecode is further compiled to native code via a -@deftech{just-in-time} or @deftech{JIT} compiler. The @tech{JIT} -compiler substantially speeds programs that execute tight loops, -arithmetic on small integers, and arithmetic on inexact real -numbers. Currently, @tech{JIT} compilation is supported for x86, -x86_64 (a.k.a. AMD64), ARM, and 32-bit PowerPC processors. The @tech{JIT} -compiler can be disabled via the @racket[eval-jit-enabled] parameter -or the @DFlag{no-jit}/@Flag{j} command-line flag for @exec{racket}. +For the @tech{CS} variant of Racket, the main bytecode format is +non-portable machine code. For the @tech{3m} and @tech{CGC} variants +of Racket, bytecode is portable in the sense that it is +machine-independent. Setting @racket[current-compile-target-machine] +to @racket[#f] selects a separate machine-independent and +variant-independent format on all Racket variants, but running code in +that format requires an additional internal conversion step to the +variant's main bytecode format. + +Machine-independent bytecode for @tech{3m} or @tech{CGC} is further +compiled to native code via a @deftech{just-in-time} or @deftech{JIT} +compiler. The @tech{JIT} compiler substantially speeds programs that +execute tight loops, arithmetic on small integers, and arithmetic on +inexact real numbers. Currently, @tech{JIT} compilation is supported +for x86, x86_64 (a.k.a. AMD64), ARM, and 32-bit PowerPC processors. +The @tech{JIT} compiler can be disabled via the +@racket[eval-jit-enabled] parameter or the @DFlag{no-jit}/@Flag{j} +command-line flag for @exec{racket}. Setting @racket[eval-jit-enabled] +to @racket[#f] has not effect on the @tech{CS} variant of Racket. The @tech{JIT} compiler works incrementally as functions are applied, but the @tech{JIT} compiler makes only limited use of run-time @@ -93,8 +150,7 @@ difficult to detect. The module system aids optimization by helping to ensure that identifiers have the usual bindings. That is, the @racket[+] provided by @racketmodname[racket/base] can be recognized by the compiler and -inlined, which is especially important for @tech{JIT}-compiled code. -In contrast, in a traditional interactive Scheme system, the top-level +inlined. In contrast, in a traditional interactive Scheme system, the top-level @racket[+] binding might be redefined, so the compiler cannot assume a fixed @racket[+] binding (unless special flags or declarations are used to compensate for the lack of a module system). @@ -111,7 +167,7 @@ time. Such optimizations are unavailable in the top-level environment. Although this optimization within modules is important for performance, it hinders some forms of interactive development and exploration. The @racket[compile-enforce-module-constants] parameter -disables the @tech{JIT} compiler's assumptions about module +disables the compiler's assumptions about module definitions when interactive exploration is more important. See @secref["module-set"] for more information. @@ -179,7 +235,7 @@ inlining, but a programmer can wrap a function definition with of the function. Primitive operations like @racket[pair?], @racket[car], and -@racket[cdr] are inlined at the machine-code level by the @tech{JIT} +@racket[cdr] are inlined at the machine-code level by the bytecode or @tech{JIT} compiler. See also the later section @secref["fixnums+flonums"] for information about inlined arithmetic operations. @@ -298,7 +354,7 @@ A @deftech{flonum} is used to represent any inexact real number. They correspond to 64-bit IEEE floating-point numbers on all platforms. Inlined fixnum and flonum arithmetic operations are among the most -important advantages of the @tech{JIT} compiler. For example, when +important advantages of the compiler. For example, when @racket[+] is applied to two arguments, the generated machine code tests whether the two arguments are fixnums, and if so, it uses the machine's instruction to add the numbers (and check for overflow). If @@ -321,7 +377,8 @@ typically cheap to use. The @racketmodname[racket/flonum] library provides flonum-specific operations, and combinations of flonum operations allow the @tech{JIT} -compiler to generate code that avoids boxing and unboxing intermediate +compiler for the @tech{3m} and @tech{CGC} variants of Racket +to generate code that avoids boxing and unboxing intermediate results. Besides results within immediate combinations, flonum-specific results that are bound with @racket[let] and consumed by a later flonum-specific operation are unboxed within temporary @@ -366,7 +423,7 @@ crashes or memory corruption. @section[#:tag "ffi-pointer-access"]{Foreign Pointers} The @racketmodname[ffi/unsafe] library provides functions for unsafely -reading and writing arbitrary pointer values. The JIT recognizes uses +reading and writing arbitrary pointer values. The compiler recognizes uses of @racket[ptr-ref] and @racket[ptr-set!] where the second argument is a direct reference to one of the following built-in C types: @racket[_int8], @racket[_int16], @racket[_int32], @racket[_int64], @@ -378,10 +435,9 @@ inline in the generated code. The bytecode compiler will optimize references to integer abbreviations like @racket[_int] to C types like @racket[_int32]---where the representation sizes are constant across -platforms---so the JIT can specialize access with those C types. C +platforms---so the compiler can specialize access with those C types. C types such as @racket[_long] or @racket[_intptr] are not constant -across platforms, so their uses are currently not specialized by the -JIT. +across platforms, so their uses are not as consistently specialized. Pointer reads and writes using @racket[_float] or @racket[_double] are not currently subject to unboxing optimizations. @@ -421,16 +477,16 @@ string or byte string, write a constant @tech{regexp} using an @section[#:tag "gc-perf"]{Memory Management} -The Racket implementation is available in three variants: @deftech{3m}, -@deftech{CGC}, and @deftech{CS}. The @tech{3m} and @tech{CS} variants use a modern, +The @tech{3m} (default) and @tech{CS} Racket +@seclink["virtual-machines"]{virtual machines} each use a modern, @deftech{generational garbage collector} that makes allocation relatively cheap for short-lived objects. The @tech{CGC} variant uses a @deftech{conservative garbage collector} which facilitates interaction with C code at the expense of both precision and speed for -Racket memory management. The @tech{3m} variant is currently the standard one. +Racket memory management. Although memory allocation is reasonably cheap, avoiding allocation -altogether is normally faster. One particular place where allocation +altogether is often faster. One particular place where allocation can be avoided sometimes is in @deftech{closures}, which are the run-time representation of functions that contain free variables. For example, diff --git a/pkgs/racket-doc/scribblings/inside/inside.scrbl b/pkgs/racket-doc/scribblings/inside/inside.scrbl index 4a99e44512..bc2e08683e 100644 --- a/pkgs/racket-doc/scribblings/inside/inside.scrbl +++ b/pkgs/racket-doc/scribblings/inside/inside.scrbl @@ -6,8 +6,11 @@ @author["Matthew Flatt"] -This manual describes the C interface of Racket's run-time system. The -C interface is relevant primarily when interacting with foreign +This manual describes the C interface of Racket's runtime system for +the 3m and CGC variants of Racket (but not the CS variant; see +@secref[#:doc '(lib "scribblings/guide/guide.scrbl") +"virtual-machines"]). The C +interface is relevant primarily when interacting with foreign libraries as described in @other-manual['(lib "scribblings/foreign/foreign.scrbl")]; even though interactions with foreign code are constructed in pure Racket using the diff --git a/pkgs/racket-doc/scribblings/inside/memory.scrbl b/pkgs/racket-doc/scribblings/inside/memory.scrbl index 2866164484..4966c8134d 100644 --- a/pkgs/racket-doc/scribblings/inside/memory.scrbl +++ b/pkgs/racket-doc/scribblings/inside/memory.scrbl @@ -671,7 +671,7 @@ or @cppi{MZ_REGISTER_STATIC} too early. [size_t n])]{ Allocates @var{n} bytes of collectable memory, initially filled with -zeros. In 3m, the allocated object is treated as an array of +zeros. The allocated object is treated as an array of pointers.} @function[(void* scheme_malloc_atomic @@ -747,7 +747,7 @@ Copies the null-terminated string @var{str}; the copy will never be freed.} [size_t size])]{ Attempts to allocate @var{size} bytes using @var{mallocf}. If the -allocation fails, the @racket[exn:misc:out-of-memory] exception is +allocation fails, the @racket[exn:fail:out-of-memory] exception is raised.} @function[(void** scheme_malloc_immobile_box diff --git a/pkgs/racket-doc/scribblings/reference/eval.scrbl b/pkgs/racket-doc/scribblings/reference/eval.scrbl index eabfb31412..bcf9271b99 100644 --- a/pkgs/racket-doc/scribblings/reference/eval.scrbl +++ b/pkgs/racket-doc/scribblings/reference/eval.scrbl @@ -626,11 +626,12 @@ reports the running Racket's native target machine. A @tech{parameter} that determines whether the native-code just-in-time compiler (@deftech{JIT}) is enabled for code (compiled or not) that is passed to the default evaluation handler. A true parameter value is effective -only on platforms for which the JIT is supported, and changing the value -from its initial setting affects only forms that are outside of @racket[module]. +only on platforms for which the JIT is supported and for Racket virtual machines +that rely on a JIT. The default is @racket[#t], unless the JIT is not supported by the -current platform, unless it is disabled through the +current platform but is supported on the same virtual machine for other +platforms, unless it is disabled through the @Flag{j}/@DFlag{no-jit} command-line flag to stand-alone Racket (or GRacket), and unless it is disabled through the @as-index{@envvar{PLTNOMZJIT}} environment variable (set to any diff --git a/pkgs/racket-doc/scribblings/reference/runtime.scrbl b/pkgs/racket-doc/scribblings/reference/runtime.scrbl index 362246d8b8..6456362bed 100644 --- a/pkgs/racket-doc/scribblings/reference/runtime.scrbl +++ b/pkgs/racket-doc/scribblings/reference/runtime.scrbl @@ -26,6 +26,9 @@ In @indexed-racket['word] mode, the result is either @racket[32] or @racket[64] to indicate whether Racket is running as a 32-bit program or 64-bit program. +@margin-note{See @guidesecref["virtual-machines"] for more information + about the @racket['vm] and @racket['gc] mode results.} + In @indexed-racket['vm] mode, the possible symbol results are: