readline scribblings; set GC alignment to 8-byte by default
svn: r8320
This commit is contained in:
parent
707416a13f
commit
62f38e2a40
|
@ -1,140 +0,0 @@
|
||||||
|
|
||||||
The _readline_ collection (not to be confused with MzScheme's
|
|
||||||
`read-line' procedure) provides glue for using GNU's readline library
|
|
||||||
with the MzScheme read-eval-print-loop.
|
|
||||||
|
|
||||||
|
|
||||||
Normal use of readline
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
The _rep.ss_ library installs a readline-based input port, and hooks
|
|
||||||
the prompt-and-read part of MzScheme's read-eval-print loop to
|
|
||||||
interact with it.
|
|
||||||
|
|
||||||
You can start MzScheme with
|
|
||||||
|
|
||||||
mzscheme -L rep.ss readline
|
|
||||||
|
|
||||||
or you can put the following in your ~/.mzschemerc so that MzScheme
|
|
||||||
starts with readline support when appropriate:
|
|
||||||
|
|
||||||
(when (regexp-match? #rx"xterm" (getenv "TERM"))
|
|
||||||
(dynamic-require '(lib "rep.ss" "readline") #f))
|
|
||||||
|
|
||||||
The "rep.ss" module is actually a wrapper around "rep-start.ss", it
|
|
||||||
will *not* invoke it if the input port is not a terminal port (eg,
|
|
||||||
when the input is redirected from a file). Still the TERM condition
|
|
||||||
above is useful for starting MzScheme in dumb terminals, eg, inside
|
|
||||||
Emacs.
|
|
||||||
|
|
||||||
Completion is set to use the visible bindings in the current
|
|
||||||
namespace; this is far from ideal, but it's better than readline's
|
|
||||||
default filename completion which is rarely useful. In addition, the
|
|
||||||
readline history is stored across invocations in MzScheme's
|
|
||||||
preferences file, assuming MzScheme exits normally.
|
|
||||||
|
|
||||||
|
|
||||||
Interacting with the readline-enabled input port
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
The _pread.ss_ library provides customization, and support for
|
|
||||||
prompt-reading after "rep.ss" installs the new input port.
|
|
||||||
|
|
||||||
The reading facility that the new input port provides can be
|
|
||||||
customized with these parameters:
|
|
||||||
|
|
||||||
> currnet-prompt
|
|
||||||
The prompt that is used, as a byte string. Defaults to #"> ".
|
|
||||||
|
|
||||||
> show-all-prompts
|
|
||||||
If #f, no prompt is shown until you write input that is completely
|
|
||||||
readable. For example, when you type
|
|
||||||
(foo bar) (+ 1
|
|
||||||
2)
|
|
||||||
you will see a single prompt in the beginning.
|
|
||||||
|
|
||||||
The problem is that the first expression can be `(read-line)' which
|
|
||||||
normally consumes the rest of the text on the *same* line. The
|
|
||||||
default value of this parameter is therefore #t, making it mimic
|
|
||||||
plain I/O interactions.
|
|
||||||
|
|
||||||
> max-history
|
|
||||||
The number of history entries to save. Defaults to 100.
|
|
||||||
|
|
||||||
> keep-duplicates
|
|
||||||
If this is #f (the default), then lines that are equal to the
|
|
||||||
previous one are not added as new history items.
|
|
||||||
|
|
||||||
> keep-blanks
|
|
||||||
If #f (the default), blank input lines are not kept in history.
|
|
||||||
|
|
||||||
The new input port that you get when you require "rep.ss" is a custom
|
|
||||||
port that uses readline for all inputs. The problem is when you want
|
|
||||||
to display a prompt and then read some input: readline will get
|
|
||||||
confused if it's not used when the cursor is at the beginning of the
|
|
||||||
line, which is why it has a `prompt' argument. To use this prompt:
|
|
||||||
|
|
||||||
(parameterize ([readline-prompt some-byte-string])
|
|
||||||
...code-that-reads...)
|
|
||||||
|
|
||||||
This will make the first call to readline use the prompt, and
|
|
||||||
subsequent calls will use an all-spaces prompt of the same length (for
|
|
||||||
example, when you're reading an s-expression). The normal value of
|
|
||||||
`readline-prompt' is #f for an empty prompt (and 'spaces after the
|
|
||||||
prompt is used, which is why you should use `parameterize' to restore
|
|
||||||
it to #f).
|
|
||||||
|
|
||||||
A proper solution would be to install a custom output port too which
|
|
||||||
keeps track of text that is displayed without a trailing newline. As
|
|
||||||
a cheaper solution, if line-counting is enabled for the terminal's
|
|
||||||
output-port, then a newline is printed before reading if the column is
|
|
||||||
not 0. ("rep.ss" enables line-counting for the output port.)
|
|
||||||
|
|
||||||
|
|
||||||
Warning
|
|
||||||
-------
|
|
||||||
|
|
||||||
The readline library uses the output port directly. You should not
|
|
||||||
use it when `current-input-port' has been modified, or when it was not
|
|
||||||
a terminal port when MzScheme was started (eg, when reading input from
|
|
||||||
a pipe). Expect problems if you ignore this warning (not too bad,
|
|
||||||
mostly problems with detecting an EOF).
|
|
||||||
|
|
||||||
|
|
||||||
Direct bindings for readline hackers
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
The _readline.ss_ library provides these functions:
|
|
||||||
|
|
||||||
> (readline prompt-string)
|
|
||||||
prints the given prompt string and reads a line
|
|
||||||
|
|
||||||
> (readline-bytes prompt-bytes)
|
|
||||||
same as above, but using raw byte-strings for the prompt and
|
|
||||||
returning a byte string
|
|
||||||
|
|
||||||
> (add-history s)
|
|
||||||
adds the given string to the readline history, which is accessible
|
|
||||||
to the user via the up-arrow key
|
|
||||||
|
|
||||||
> (add-history-bytes s)
|
|
||||||
adds the given byte string to the readline history, which is
|
|
||||||
accessible to the user via the up-arrow key
|
|
||||||
|
|
||||||
> (set-completion-function! proc [type])
|
|
||||||
sets readline's `rl_completion_entry_function' function according to
|
|
||||||
proc, which is expected to be a `string -> (list-of string/bytes)'
|
|
||||||
procedure; the `type' argument defaults to `_string' but you can use
|
|
||||||
it with `_bytes' instead to have your function receive a byte
|
|
||||||
string.
|
|
||||||
|
|
||||||
|
|
||||||
License Issues
|
|
||||||
--------------
|
|
||||||
|
|
||||||
GNU's readline library is covered by the GPL, and that applies to code
|
|
||||||
that links with it. PLT Scheme is LGPL, so this code is not used by
|
|
||||||
default -- you should explicitly enable it if you want to. Also, be
|
|
||||||
aware that if you write code that uses this library, it will make your
|
|
||||||
code link to the readline library when invoked -- with the usual GPL
|
|
||||||
implications.
|
|
|
@ -2,6 +2,7 @@
|
||||||
(module info setup/infotab
|
(module info setup/infotab
|
||||||
(define doc.txt "doc.txt")
|
(define doc.txt "doc.txt")
|
||||||
(define name "readline")
|
(define name "readline")
|
||||||
|
(define scribblings '(("readline.scrbl")))
|
||||||
(define blurb
|
(define blurb
|
||||||
`("The readline collection provides glue for using GNU's readline library"
|
`("The readline collection provides glue for using GNU's readline library"
|
||||||
" with the MzScheme read-eval-print-loop.")))
|
" with the MzScheme read-eval-print-loop.")))
|
||||||
|
|
185
collects/readline/readline.scrbl
Normal file
185
collects/readline/readline.scrbl
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
#lang scribble/doc
|
||||||
|
@(require scribble/manual
|
||||||
|
(for-label scheme/base
|
||||||
|
readline/pread
|
||||||
|
readline/readline))
|
||||||
|
|
||||||
|
@(define readline "Readline")
|
||||||
|
@(define Readline "Readline")
|
||||||
|
|
||||||
|
@title{@bold{Readline}: Terminal Interaction}
|
||||||
|
|
||||||
|
The @filepath{readline} collection (not to be confused with MzScheme's
|
||||||
|
@scheme[read-line] function) provides glue for using GNU's @|readline|
|
||||||
|
library with the MzScheme @scheme[read-eval-print-loop].
|
||||||
|
|
||||||
|
@section{Normal Use of @|Readline|}
|
||||||
|
|
||||||
|
@defmodule*[(readline/rep readline/rep-start)]
|
||||||
|
|
||||||
|
The @schememodname[readline/rep] library installs a @|readline|-based
|
||||||
|
input port, and hooks the prompt-and-read part of MzScheme's
|
||||||
|
@scheme[read-eval-print-loop] to interact with it
|
||||||
|
|
||||||
|
You can start MzScheme with
|
||||||
|
|
||||||
|
@commandline{mzscheme -il readline/rep}
|
||||||
|
|
||||||
|
or you can put the following in your @filepath{~/.mzschemerc} so that
|
||||||
|
MzScheme starts with @|readline| support when appropriate:
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(when (regexp-match? #rx"xterm"
|
||||||
|
(getenv "TERM"))
|
||||||
|
(dynamic-require 'readline/rep #f))
|
||||||
|
]
|
||||||
|
|
||||||
|
The @schememodname[readline/rep] module is actually a wrapper around
|
||||||
|
@schememodname[readline/rep-start]; it will @emph{not} invoke
|
||||||
|
@schememodname[readline/rep-start] if the input port is not a terminal
|
||||||
|
port (e.g., when the input is redirected from a file); see
|
||||||
|
@scheme[terminal-port?]. Still, the @envvar{TERM} condition
|
||||||
|
above is useful for starting MzScheme in dumb terminals (e.g., inside
|
||||||
|
Emacs.)
|
||||||
|
|
||||||
|
Completion is set to use the visible bindings in the current
|
||||||
|
namespace; this is far from ideal, but it's better than @|readline|'s
|
||||||
|
default filename completion which is rarely useful. In addition, the
|
||||||
|
@|readline| history is stored across invocations in MzScheme's
|
||||||
|
preferences file, assuming that MzScheme exits normally.
|
||||||
|
|
||||||
|
|
||||||
|
@section{Interacting with the @|Readline|-Enabled Input Port }
|
||||||
|
|
||||||
|
@defmodule[readline/pread]{ The @schememodname[readline/pread] library
|
||||||
|
provides customization, and support for prompt-reading after
|
||||||
|
@schememodname[readline/rep] installs the new input port.}
|
||||||
|
|
||||||
|
The reading facility that the new input port provides can be
|
||||||
|
customized with the following parameters.
|
||||||
|
|
||||||
|
|
||||||
|
@defparam[current-prompt bstr bytes?]{
|
||||||
|
|
||||||
|
A parameter that determines the prompt that is used, as a byte string.
|
||||||
|
Defaults to @scheme[#"> "].}
|
||||||
|
|
||||||
|
|
||||||
|
@defboolparam[show-all-prompts on?]{
|
||||||
|
|
||||||
|
A parameter. If @scheme[#f], no prompt is shown until you write input
|
||||||
|
that is completely readable. For example, when you type
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(foo bar) (+ 1
|
||||||
|
2)
|
||||||
|
]
|
||||||
|
|
||||||
|
you will see a single prompt in the beginning.
|
||||||
|
|
||||||
|
The problem is that the first expression can be @scheme[(read-line)],
|
||||||
|
which normally consumes the rest of the text on the @emph{same} line.
|
||||||
|
The default value of this parameter is therefore @scheme[#t], making
|
||||||
|
it mimic plain I/O interactions.}
|
||||||
|
|
||||||
|
|
||||||
|
@defparam[max-history n nonnegative-exact-integer?]{
|
||||||
|
|
||||||
|
A parameter that determines the number of history entries to save,
|
||||||
|
defaults to @scheme[100].}
|
||||||
|
|
||||||
|
|
||||||
|
@defboolparam[keep-duplicates keep?]{
|
||||||
|
|
||||||
|
A parameter. If @scheme[#f] (the default), then lines that are equal
|
||||||
|
to the previous one are not added as new history items.}
|
||||||
|
|
||||||
|
|
||||||
|
@defboolparam[keep-blanks keep?]{
|
||||||
|
|
||||||
|
A parameter. If @scheme[#f] (the default), blank input lines are not
|
||||||
|
kept in history.}
|
||||||
|
|
||||||
|
|
||||||
|
@defparam[readline-prompt status (or/c false/c bytes? (one-of/c 'space))]{
|
||||||
|
|
||||||
|
The new input port that you get when you require
|
||||||
|
@schememodname[readline/rep] is a custom port that uses @|readline| for
|
||||||
|
all inputs. The problem is when you want to display a prompt and then
|
||||||
|
read some input, @|readline| will get confused if it is not used when the
|
||||||
|
cursor is at the beginning of the line (which is why it has a
|
||||||
|
@scheme[_prompt] argument.) To use this prompt:
|
||||||
|
|
||||||
|
@schemeblock[
|
||||||
|
(parameterize ([readline-prompt some-byte-string])
|
||||||
|
...code-that-reads...)
|
||||||
|
]
|
||||||
|
|
||||||
|
This expression makes the first call to @|readline| use the prompt, and
|
||||||
|
subsequent calls will use an all-spaces prompt of the same length (for
|
||||||
|
example, when you're reading an S-expression). The normal value of
|
||||||
|
@scheme[readline-prompt] is @scheme[#f] for an empty prompt (and
|
||||||
|
spaces after the prompt is used, which is why you should use
|
||||||
|
@scheme[parameterize] to restore it to @scheme[#f]).
|
||||||
|
|
||||||
|
A proper solution would be to install a custom output port, too, which
|
||||||
|
keeps track of text that is displayed without a trailing newline. As
|
||||||
|
a cheaper solution, if line-counting is enabled for the terminal's
|
||||||
|
output-port, then a newline is printed before reading if the column is
|
||||||
|
not 0. (The @schememodname[readline/rep] library enables line-counting
|
||||||
|
for the output port.)
|
||||||
|
|
||||||
|
@bold{Warning:} The @|readline| library uses the output port directly.
|
||||||
|
You should not use it when @scheme[current-input-port] has been
|
||||||
|
modified, or when it was not a terminal port when MzScheme was started
|
||||||
|
(eg, when reading input from a pipe). Expect some problems if you
|
||||||
|
ignore this warning (not too bad, mostly problems with detecting an
|
||||||
|
EOF).}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@section{Direct Bindings for @|Readline| Hackers}
|
||||||
|
|
||||||
|
@defmodule[readline/readline]
|
||||||
|
|
||||||
|
@defproc[(readline [prompt string?]) string?]{
|
||||||
|
|
||||||
|
Prints the given prompt string and reads a line.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(readline-bytes [prompt bytes?]) bytes?]{
|
||||||
|
|
||||||
|
Like @scheme[readline], but using raw byte-strings for the prompt and
|
||||||
|
returning a byte string.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(add-history [str string?]) void?]{
|
||||||
|
|
||||||
|
Adds the given string to the @|readline| history, which is accessible to
|
||||||
|
the user via the up-arrow key.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(add-history-bytes [str string?]) void?]{
|
||||||
|
|
||||||
|
Adds the given byte string to the @|readline| history, which is
|
||||||
|
accessible to the user via the up-arrow key.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(set-completion-function! [proc ((or/c string? bytes?)
|
||||||
|
. -> . (listof (or/c string? bytes?)))]
|
||||||
|
[type (one-of/c 'string 'bytes) 'string])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Sets @|readline|'s @tt{rl_completion_entry_function} to
|
||||||
|
@scheme[proc]. The @scheme[type] argument determines the type of value
|
||||||
|
upplied to the @scheme[proc].}
|
||||||
|
|
||||||
|
|
||||||
|
@section{License Issues}
|
||||||
|
|
||||||
|
GNU's @|readline| library is covered by the GPL, and that applies to code
|
||||||
|
that links with it. PLT Scheme is LGPL, so this code is not used by
|
||||||
|
default; you should explicitly enable it if you want to. Also, be
|
||||||
|
aware that if you write code that uses this library, it will make your
|
||||||
|
code link to the @|readline| library when invoked, with the usual GPL
|
||||||
|
implications.
|
|
@ -57,7 +57,11 @@ by @scheme[kind], which must be one of the following:
|
||||||
@item{@indexed-scheme['temp-dir] --- the standard directory for
|
@item{@indexed-scheme['temp-dir] --- the standard directory for
|
||||||
storing temporary files. Under @|AllUnix|, this is the directory
|
storing temporary files. Under @|AllUnix|, this is the directory
|
||||||
specified by the @indexed-envvar{TMPDIR} environment variable, if it
|
specified by the @indexed-envvar{TMPDIR} environment variable, if it
|
||||||
is defined.}
|
is defined, otherwise it is the first path that exists among
|
||||||
|
@filepath{/var/tmp}, @filepath{/usr/tmp}, and @filepath{/tmp}. Under
|
||||||
|
Windows, the result is the directory specified by the
|
||||||
|
@indexed-envvar{TMP} or @indexed-envvar{TEMP} environment variable,
|
||||||
|
if it is defined, otherwise it is the current directory.}
|
||||||
|
|
||||||
@item{@indexed-scheme['init-dir] --- the directory containing the
|
@item{@indexed-scheme['init-dir] --- the directory containing the
|
||||||
initialization file used by stand-alone @exec{mzscheme} executable.
|
initialization file used by stand-alone @exec{mzscheme} executable.
|
||||||
|
|
|
@ -42,7 +42,21 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(sparc) || defined(__sparc) || defined(__sparc__)
|
#if defined(sparc) || defined(__sparc) || defined(__sparc__)
|
||||||
# define ALIGN_DOUBLES
|
/* Required for `double' operations: */
|
||||||
|
# define GC_ALIGN_EIGHT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Even when 8-byte alginment is not required by the processor, it's
|
||||||
|
better for floating-point performance (PowerPC) and may be required
|
||||||
|
for some libraries (VecLib in Mac OS X, including x86).
|
||||||
|
|
||||||
|
Under Windows, Mac OS X, and Linux x86_64, malloc() returns 16-byte
|
||||||
|
aligned data. And, actually, VecLib says that it requires
|
||||||
|
16-byte-aligned data. So, in those cases, GC_ALIGN_SIXTEEN might be
|
||||||
|
better --- but that's a lot more expensive, increasing DrScheme's
|
||||||
|
initial footprint by almost 10%. */
|
||||||
|
#ifndef GC_ALIGN_EIGHT
|
||||||
|
# define GC_ALIGN_EIGHT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "msgprint.c"
|
#include "msgprint.c"
|
||||||
|
@ -229,14 +243,24 @@ struct mpage {
|
||||||
void **backtrace;
|
void **backtrace;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ALIGN_DOUBLES
|
/* Make sure alloction starts out double-word aligned.
|
||||||
/* Make sure alloction starts out double-word aligned: */
|
The header on each allocated object is one word, so to make
|
||||||
# define PREFIX_SIZE WORD_SIZE
|
the content double-word aligned, we deeper. */
|
||||||
# define PREFIX_WSIZE 1
|
#ifdef GC_ALIGN_SIXTEEN
|
||||||
|
# ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
# define PREFIX_WSIZE 1
|
||||||
|
# else
|
||||||
|
# define PREFIX_WSIZE 3
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# define PREFIX_SIZE 0
|
# if defined(GC_ALIGN_EIGHT) && !defined(SIXTY_FOUR_BIT_INTEGERS)
|
||||||
# define PREFIX_WSIZE 0
|
# define PREFIX_WSIZE 1
|
||||||
|
# else
|
||||||
|
# define PREFIX_WSIZE 0
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
#define PREFIX_SIZE (PREFIX_WSIZE * WORD_SIZE)
|
||||||
|
|
||||||
|
|
||||||
/* this is the maximum size of an object that will fit on a page, in words.
|
/* this is the maximum size of an object that will fit on a page, in words.
|
||||||
the "- 3" is basically used as a fudge/safety factor, and has no real,
|
the "- 3" is basically used as a fudge/safety factor, and has no real,
|
||||||
|
@ -441,12 +465,35 @@ static void *allocate_big(size_t sizeb, int type)
|
||||||
return PTR(NUM(addr) + PREFIX_SIZE + WORD_SIZE);
|
return PTR(NUM(addr) + PREFIX_SIZE + WORD_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ALIGN_DOUBLES
|
/* ALIGN_BYTES_SIZE can assume that the argument is already word-aligned. */
|
||||||
# define ALIGN_SIZE(sizew) (((sizew) & 0x1) ? ((sizew) + 1) : (sizew))
|
/* INSET_WORDS is how many words in a tagged array can be padding, plus one; it
|
||||||
# define ALIGN_BYTES_SIZE(sizeb) (((sizeb) & WORD_SIZE) ? ((sizeb) + WORD_SIZE) : (sizeb))
|
must also be no more than the minimum size of a tagged element. */
|
||||||
|
#ifdef GC_ALIGN_SIXTEEN
|
||||||
|
# ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
# define ALIGN_SIZE(sizew) (((sizew) & 0x1) ? ((sizew) + 1) : (sizew))
|
||||||
|
# define ALIGN_BYTES_SIZE(sizeb) (((sizeb) & WORD_SIZE) ? ((sizeb) + WORD_SIZE) : (sizeb))
|
||||||
|
# define INSET_WORDS 1
|
||||||
|
# else
|
||||||
|
# define ALIGN_SIZE(sizew) (((sizew) & 0x3) ? ((sizew) + (4 - ((sizew) & 0x3))) : (sizew))
|
||||||
|
# define ALIGN_BYTES_SIZE(sizeb) (((sizeb) & (3 * WORD_SIZE)) ? ((sizeb) + ((4 * WORD_SIZE) - ((sizeb) & (3 * WORD_SIZE)))) : (sizeb))
|
||||||
|
# define INSET_WORDS 3
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# define ALIGN_SIZE(sizew) (sizew)
|
# ifdef GC_ALIGN_EIGHT
|
||||||
# define ALIGN_BYTES_SIZE(sizeb) (sizeb)
|
# ifdef SIXTY_FOUR_BIT_INTEGERS
|
||||||
|
# define ALIGN_SIZE(sizew) (sizew)
|
||||||
|
# define ALIGN_BYTES_SIZE(sizeb) (sizeb)
|
||||||
|
# define INSET_WORDS 0
|
||||||
|
# else
|
||||||
|
# define ALIGN_SIZE(sizew) (((sizew) & 0x1) ? ((sizew) + 1) : (sizew))
|
||||||
|
# define ALIGN_BYTES_SIZE(sizeb) (((sizeb) & WORD_SIZE) ? ((sizeb) + WORD_SIZE) : (sizeb))
|
||||||
|
# define INSET_WORDS 1
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
# define ALIGN_SIZE(sizew) (sizew)
|
||||||
|
# define ALIGN_BYTES_SIZE(sizeb) (sizeb)
|
||||||
|
# define INSET_WORDS 0
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline static void *allocate(size_t sizeb, int type)
|
inline static void *allocate(size_t sizeb, int type)
|
||||||
|
@ -901,7 +948,7 @@ static void *get_backtrace(struct mpage *page, void *ptr)
|
||||||
unsigned long delta;
|
unsigned long delta;
|
||||||
|
|
||||||
if (page->big_page)
|
if (page->big_page)
|
||||||
ptr = PTR(page->addr + PREFIX_SIZE);
|
ptr = PTR(page->addr + PREFIX_SIZE + WORD_SIZE);
|
||||||
|
|
||||||
delta = PPTR(ptr) - PPTR(page->addr);
|
delta = PPTR(ptr) - PPTR(page->addr);
|
||||||
return page->backtrace[delta - 1];
|
return page->backtrace[delta - 1];
|
||||||
|
@ -1690,7 +1737,7 @@ inline static void mark_normal_obj(struct mpage *page, void *ptr)
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
struct objhead *info = (struct objhead *)((char*)ptr - WORD_SIZE);
|
struct objhead *info = (struct objhead *)((char*)ptr - WORD_SIZE);
|
||||||
unsigned short tag = *(unsigned short*)ptr;
|
unsigned short tag = *(unsigned short*)ptr;
|
||||||
void **temp = ptr, **end = PPTR(info) + (info->size - 1);
|
void **temp = ptr, **end = PPTR(info) + (info->size - INSET_WORDS);
|
||||||
|
|
||||||
while(temp < end) temp += mark_table[tag](temp);
|
while(temp < end) temp += mark_table[tag](temp);
|
||||||
break;
|
break;
|
||||||
|
@ -1718,7 +1765,7 @@ inline static void mark_acc_big_page(struct mpage *page)
|
||||||
case PAGE_XTAGGED: GC_mark_xtagged(start); break;
|
case PAGE_XTAGGED: GC_mark_xtagged(start); break;
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= 1;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2295,7 +2342,7 @@ inline static void internal_mark(void *p)
|
||||||
case PAGE_XTAGGED: GC_mark_xtagged(start); break;
|
case PAGE_XTAGGED: GC_mark_xtagged(start); break;
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= 1;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2316,7 +2363,7 @@ inline static void internal_mark(void *p)
|
||||||
}
|
}
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
void **start = p;
|
void **start = p;
|
||||||
void **end = PPTR(info) + (info->size - 1);
|
void **end = PPTR(info) + (info->size - INSET_WORDS);
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
while(start < end) start += mark_table[tag](start);
|
while(start < end) start += mark_table[tag](start);
|
||||||
break;
|
break;
|
||||||
|
@ -2798,7 +2845,7 @@ static void repair_heap(void)
|
||||||
break;
|
break;
|
||||||
case PAGE_TARRAY: {
|
case PAGE_TARRAY: {
|
||||||
unsigned short tag = *(unsigned short *)start;
|
unsigned short tag = *(unsigned short *)start;
|
||||||
end -= 1;
|
end -= INSET_WORDS;
|
||||||
while(start < end) start += fixup_table[tag](start);
|
while(start < end) start += fixup_table[tag](start);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2851,7 +2898,7 @@ static void repair_heap(void)
|
||||||
struct objhead *info = (struct objhead *)start;
|
struct objhead *info = (struct objhead *)start;
|
||||||
size_t size = info->size;
|
size_t size = info->size;
|
||||||
if(info->mark) {
|
if(info->mark) {
|
||||||
void **tempend = (start++) + (size - 1);
|
void **tempend = (start++) + (size - INSET_WORDS);
|
||||||
unsigned short tag = *(unsigned short*)start;
|
unsigned short tag = *(unsigned short*)start;
|
||||||
while(start < tempend)
|
while(start < tempend)
|
||||||
start += fixup_table[tag](start);
|
start += fixup_table[tag](start);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user