mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
gpgscm: Allocate small integers in the rodata section.
* tests/gpgscm/Makefile.am (gpgscm_SOURCES): Add new file. * tests/gpgscm/scheme-private.h (struct cell): Move number to the top of the union so that we can initialize it. (struct scheme): Remove 'integer_segment'. * tests/gpgscm/scheme.c (initialize_small_integers): Remove function. (small_integers): New variable. (MAX_SMALL_INTEGER): Compute. (mk_small_integer): Adapt. (mark): Avoid marking objects already marked. This allows us to run the algorithm over objects in the rodata section if they are already marked. (scheme_init_custom_alloc): Remove initialization. (scheme_deinit): Remove deallocation. * tests/gpgscm/small-integers.h: New file. -- Allocate small integers from a fixed pool in the rodata section. This spares us the initialization, and deduplicates integers across different processes. It also makes the integers immutable, increasing memory safety. Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
parent
c9c3fe8832
commit
8640fa880d
4 changed files with 861 additions and 37 deletions
|
@ -1312,31 +1312,22 @@ INTERFACE pointer mk_character(scheme *sc, int c) {
|
|||
|
||||
/* s_save assumes that all opcodes can be expressed as a small
|
||||
* integer. */
|
||||
#define MAX_SMALL_INTEGER OP_MAXDEFINED
|
||||
static const struct cell small_integers[] = {
|
||||
#define DEFINE_INTEGER(n) { T_NUMBER | T_ATOM | MARK, {{ 1, {n}}}},
|
||||
#include "small-integers.h"
|
||||
#undef DEFINE_INTEGER
|
||||
{0}
|
||||
};
|
||||
|
||||
static int
|
||||
initialize_small_integers(scheme *sc)
|
||||
{
|
||||
int i;
|
||||
if (_alloc_cellseg(sc, MAX_SMALL_INTEGER, &sc->integer_segment))
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < MAX_SMALL_INTEGER; i++) {
|
||||
pointer x = &sc->integer_segment->cells[i];
|
||||
typeflag(x) = T_NUMBER | T_ATOM | MARK;
|
||||
ivalue_unchecked(x) = i;
|
||||
set_num_integer(x);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#define MAX_SMALL_INTEGER (sizeof small_integers / sizeof *small_integers - 1)
|
||||
|
||||
static INLINE pointer
|
||||
mk_small_integer(scheme *sc, long n)
|
||||
{
|
||||
#define mk_small_integer_allocates 0
|
||||
(void) sc;
|
||||
assert(0 <= n && n < MAX_SMALL_INTEGER);
|
||||
return &sc->integer_segment->cells[n];
|
||||
return (pointer) &small_integers[n];
|
||||
}
|
||||
#else
|
||||
|
||||
|
@ -1644,7 +1635,8 @@ static void mark(pointer a) {
|
|||
|
||||
t = (pointer) 0;
|
||||
p = a;
|
||||
E2: setmark(p);
|
||||
E2: if (! is_mark(p))
|
||||
setmark(p);
|
||||
if(is_vector(p)) {
|
||||
int i;
|
||||
for (i = 0; i < vector_length(p); i++) {
|
||||
|
@ -5629,13 +5621,6 @@ int scheme_init_custom_alloc(scheme *sc, func_alloc malloc, func_dealloc free) {
|
|||
sc->F = &sc->_HASHF;
|
||||
sc->EOF_OBJ=&sc->_EOF_OBJ;
|
||||
|
||||
#if USE_SMALL_INTEGERS
|
||||
if (initialize_small_integers(sc)) {
|
||||
sc->no_memory=1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
sc->free_cell = &sc->_NIL;
|
||||
sc->fcells = 0;
|
||||
sc->inhibit_gc = GC_ENABLED;
|
||||
|
@ -5789,10 +5774,6 @@ void scheme_deinit(scheme *sc) {
|
|||
sc->gc_verbose=0;
|
||||
gc(sc,sc->NIL,sc->NIL);
|
||||
|
||||
#if USE_SMALL_INTEGERS
|
||||
_dealloc_cellseg(sc, sc->integer_segment);
|
||||
#endif
|
||||
|
||||
for (s = sc->cell_segments; s; s = _dealloc_cellseg(sc, s)) {
|
||||
/* nop */
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue