adjust docs to explain better about 3m/CGC/CS
This commit is contained in:
parent
8e5e5b9467
commit
a38b9e5beb
|
@ -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.
|
||||
|
|
|
@ -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.}
|
||||
|
||||
]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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})
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user