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
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.

View File

@ -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.}
]

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}
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

View File

@ -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"))

View File

@ -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})

View File

@ -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,

View File

@ -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

View File

@ -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

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
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

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
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: