adjust docs to explain better about 3m/CGC/CS

This commit is contained in:
Matthew Flatt 2019-01-23 18:36:14 -07:00
parent 8e5e5b9467
commit a38b9e5beb
10 changed files with 205 additions and 58 deletions

View File

@ -375,7 +375,7 @@ as the GC compacts allocated objects to avoid fragmentation. C
functions, meanwhile, expect to receive pointers to objects that will functions, meanwhile, expect to receive pointers to objects that will
stay put. 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), system (perhaps through a function that is provided as an argument),
no garbage collection will happen between the time that a C function no garbage collection will happen between the time that a C function
is called and the time that the function returns. is called and the time that the function returns.

View File

@ -214,7 +214,7 @@ see @|InsideRacket|.
cpointer?]{ cpointer?]{
Allocates a memory block of a specified size using a specified 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 memory, or @racket[#f] if the requested size is zero. Although
not reflected above, the four arguments can appear in not reflected above, the four arguments can appear in
any order, since they are all different types of Racket objects; a size 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.} the new block.}
@item{A symbol @racket[mode] argument can be given, which specifies @item{A symbol @racket[mode] argument can be given, which specifies
what allocation function to use. It should be one of what allocation function to use. It should be one of the following:
@indexed-racket['nonatomic] (uses @cpp{scheme_malloc} from
Racket's C API), @indexed-racket['atomic] @itemlist[
(@cpp{scheme_malloc_atomic}), @indexed-racket['tagged]
(@cpp{scheme_malloc_tagged}), @indexed-racket['stubborn] @item{@indexed-racket['raw] --- Allocates memory that is outside
(@cpp{scheme_malloc_stubborn}), @indexed-racket['uncollectable] the garbage collector's space and is not traced by the garbage
(@cpp{scheme_malloc_uncollectable}), @indexed-racket['eternal] collector (i.e., is treated as holding no pointers to
(@cpp{scheme_malloc_eternal}), @indexed-racket['interior] collectable memory). This memory must be freed with
(@cpp{scheme_malloc_allow_interior}), @racket[free].}
@indexed-racket['atomic-interior]
(@cpp{scheme_malloc_atomic_allow_interior}), or @item{@indexed-racket['atomic] --- Allocates memory that can be
@indexed-racket['raw] (uses the operating system's @cpp{malloc}, reclaimed by the garbage collector, is not traced by the
creating a GC-invisible block).} @item{If an additional garbage collector, and is initially filled with zeros.
@indexed-racket['failok] flag is given, then
@cpp{scheme_malloc_fail_ok} is used to wrap the call.} 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.}
] ]

View File

@ -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} @item{If @racket[blocking?] is true, then a foreign @tech{callout}
deactivates tracking of the calling OS thread---to the degree deactivates tracking of the calling OS thread---to the degree
supported by the Racket variant---during the foreign call. The supported by the Racket variant---during the foreign call. The
value of @racket[blocking?] affects only the @tech[#:doc value of @racket[blocking?] affects only the @CS[] variant of
guide.scrbl]{CS} variant of Racket, where it enable activity Racket, where it enable activity
such as garbage collection in other OS threads while the such as garbage collection in other OS threads while the
@tech{callout} blocks. If the blocking @tech{callout} can @tech{callout} blocks. If the blocking @tech{callout} can
invoke any @tech{callbacks} back to Racket, those invoke any @tech{callbacks} back to Racket, those

View File

@ -19,6 +19,7 @@
reference.scrbl reference.scrbl
->> ->>
tech-place tech-place
3m CGC CS
(all-from-out scribble/manual) (all-from-out scribble/manual)
(for-label (all-from-out racket/base (for-label (all-from-out racket/base
racket/contract racket/contract
@ -44,3 +45,7 @@
(define (tech-place) (define (tech-place)
(tech "place" #:doc '(lib "scribblings/reference/reference.scrbl"))) (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"))

View File

@ -9,7 +9,7 @@
(require (for-label racket/base)) (require (for-label racket/base))
(provide (for-label (all-from-out racket/base))) (provide (for-label (all-from-out racket/base)))
(provide Quick Racket HtDP (provide Quick Racket HtDP inside-doc
tool tool
moreguide moreguide
guideother guideother
@ -66,6 +66,7 @@
(define Racket (other-manual '(lib "scribblings/reference/reference.scrbl"))) (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 r6rs @elem{R@superscript{6}RS})
(define r5rs @elem{R@superscript{5}RS}) (define r5rs @elem{R@superscript{5}RS})

View File

@ -20,7 +20,7 @@ machine level, the gap between the Racket language model and the
underlying computing machinery can be quite large. underlying computing machinery can be quite large.
In this chapter, we narrow the gap by explaining details of the 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. 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} @section[#:tag "JIT"]{The Bytecode and Just-in-Time (JIT) Compilers}
Every definition or expression to be evaluated by Racket is compiled Every definition or expression to be evaluated by Racket is compiled
to an internal bytecode format. In interactive mode, this compilation to an internal bytecode format, although ``bytecode'' may actually be
occurs automatically and on-the-fly. Tools like @exec{raco make} and 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 @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 not have to compile from source every time that you run a program.
program. (Most of the time required to compile a file is actually in See @secref["compile"] for more information on generating
macro expansion; generating bytecode from fully expanded code is bytecode files.
relatively fast.) See @secref["compile"] for more information on
generating bytecode files.
The bytecode compiler applies all standard optimizations, such as The bytecode compiler applies all standard optimizations, such as
constant propagation, constant folding, inlining, and dead-code 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)]) (+ usual binding, the expression @racket[(let ([x 1] [y (lambda () 4)]) (+
1 (y)))] is compiled the same as the constant @racket[5]. 1 (y)))] is compiled the same as the constant @racket[5].
On some platforms, bytecode is further compiled to native code via a For the @tech{CS} variant of Racket, the main bytecode format is
@deftech{just-in-time} or @deftech{JIT} compiler. The @tech{JIT} non-portable machine code. For the @tech{3m} and @tech{CGC} variants
compiler substantially speeds programs that execute tight loops, of Racket, bytecode is portable in the sense that it is
arithmetic on small integers, and arithmetic on inexact real machine-independent. Setting @racket[current-compile-target-machine]
numbers. Currently, @tech{JIT} compilation is supported for x86, to @racket[#f] selects a separate machine-independent and
x86_64 (a.k.a. AMD64), ARM, and 32-bit PowerPC processors. The @tech{JIT} variant-independent format on all Racket variants, but running code in
compiler can be disabled via the @racket[eval-jit-enabled] parameter that format requires an additional internal conversion step to the
or the @DFlag{no-jit}/@Flag{j} command-line flag for @exec{racket}. 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, The @tech{JIT} compiler works incrementally as functions are applied,
but the @tech{JIT} compiler makes only limited use of run-time 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 The module system aids optimization by helping to ensure that
identifiers have the usual bindings. That is, the @racket[+] provided identifiers have the usual bindings. That is, the @racket[+] provided
by @racketmodname[racket/base] can be recognized by the compiler and by @racketmodname[racket/base] can be recognized by the compiler and
inlined, which is especially important for @tech{JIT}-compiled code. inlined. In contrast, in a traditional interactive Scheme system, the top-level
In contrast, in a traditional interactive Scheme system, the top-level
@racket[+] binding might be redefined, so the compiler cannot assume a @racket[+] binding might be redefined, so the compiler cannot assume a
fixed @racket[+] binding (unless special flags or declarations fixed @racket[+] binding (unless special flags or declarations
are used to compensate for the lack of a module system). 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 environment. Although this optimization within modules is important
for performance, it hinders some forms of interactive development and for performance, it hinders some forms of interactive development and
exploration. The @racket[compile-enforce-module-constants] parameter 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 definitions when interactive exploration is more important. See
@secref["module-set"] for more information. @secref["module-set"] for more information.
@ -179,7 +235,7 @@ inlining, but a programmer can wrap a function definition with
of the function. of the function.
Primitive operations like @racket[pair?], @racket[car], and 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 compiler. See also the later section @secref["fixnums+flonums"] for
information about inlined arithmetic operations. 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. correspond to 64-bit IEEE floating-point numbers on all platforms.
Inlined fixnum and flonum arithmetic operations are among the most 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 @racket[+] is applied to two arguments, the generated machine code
tests whether the two arguments are fixnums, and if so, it uses the 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 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 The @racketmodname[racket/flonum] library provides flonum-specific
operations, and combinations of flonum operations allow the @tech{JIT} 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, results. Besides results within immediate combinations,
flonum-specific results that are bound with @racket[let] and consumed flonum-specific results that are bound with @racket[let] and consumed
by a later flonum-specific operation are unboxed within temporary 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} @section[#:tag "ffi-pointer-access"]{Foreign Pointers}
The @racketmodname[ffi/unsafe] library provides functions for unsafely 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 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: a direct reference to one of the following built-in C types:
@racket[_int8], @racket[_int16], @racket[_int32], @racket[_int64], @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 The bytecode compiler will optimize references to integer
abbreviations like @racket[_int] to C types like abbreviations like @racket[_int] to C types like
@racket[_int32]---where the representation sizes are constant across @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 types such as @racket[_long] or @racket[_intptr] are not constant
across platforms, so their uses are currently not specialized by the across platforms, so their uses are not as consistently specialized.
JIT.
Pointer reads and writes using @racket[_float] or @racket[_double] are Pointer reads and writes using @racket[_float] or @racket[_double] are
not currently subject to unboxing optimizations. 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} @section[#:tag "gc-perf"]{Memory Management}
The Racket implementation is available in three variants: @deftech{3m}, The @tech{3m} (default) and @tech{CS} Racket
@deftech{CGC}, and @deftech{CS}. The @tech{3m} and @tech{CS} variants use a modern, @seclink["virtual-machines"]{virtual machines} each use a modern,
@deftech{generational garbage collector} that makes allocation @deftech{generational garbage collector} that makes allocation
relatively cheap for short-lived objects. The @tech{CGC} variant uses relatively cheap for short-lived objects. The @tech{CGC} variant uses
a @deftech{conservative garbage collector} which facilitates a @deftech{conservative garbage collector} which facilitates
interaction with C code at the expense of both precision and speed for 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 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 can be avoided sometimes is in @deftech{closures}, which are the
run-time representation of functions that contain free variables. run-time representation of functions that contain free variables.
For example, For example,

View File

@ -6,8 +6,11 @@
@author["Matthew Flatt"] @author["Matthew Flatt"]
This manual describes the C interface of Racket's run-time system. The This manual describes the C interface of Racket's runtime system for
C interface is relevant primarily when interacting with foreign 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 libraries as described in @other-manual['(lib
"scribblings/foreign/foreign.scrbl")]; even though interactions with "scribblings/foreign/foreign.scrbl")]; even though interactions with
foreign code are constructed in pure Racket using the foreign code are constructed in pure Racket using the

View File

@ -671,7 +671,7 @@ or @cppi{MZ_REGISTER_STATIC} too early.
[size_t n])]{ [size_t n])]{
Allocates @var{n} bytes of collectable memory, initially filled with 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.} pointers.}
@function[(void* scheme_malloc_atomic @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])]{ [size_t size])]{
Attempts to allocate @var{size} bytes using @var{mallocf}. If the 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.} raised.}
@function[(void** scheme_malloc_immobile_box @function[(void** scheme_malloc_immobile_box

View File

@ -626,11 +626,12 @@ reports the running Racket's native target machine.
A @tech{parameter} that determines whether the native-code just-in-time 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 compiler (@deftech{JIT}) is enabled for code (compiled or not) that is passed to
the default evaluation handler. A true parameter value is effective the default evaluation handler. A true parameter value is effective
only on platforms for which the JIT is supported, and changing the value only on platforms for which the JIT is supported and for Racket virtual machines
from its initial setting affects only forms that are outside of @racket[module]. that rely on a JIT.
The default is @racket[#t], unless the JIT is not supported by the 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 @Flag{j}/@DFlag{no-jit} command-line flag to stand-alone Racket (or
GRacket), and unless it is disabled through the GRacket), and unless it is disabled through the
@as-index{@envvar{PLTNOMZJIT}} environment variable (set to any @as-index{@envvar{PLTNOMZJIT}} environment variable (set to any

View File

@ -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 @racket[64] to indicate whether Racket is running as a 32-bit program
or 64-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, In @indexed-racket['vm] mode,
the possible symbol results are: the possible symbol results are: