Skip to content

Commit

Permalink
Allow the pool of hipe constants to grow at runtime
Browse files Browse the repository at this point in the history
The implementation replaces the static pool with a simple linked-list of
pools. The rationale for keeping a list of pools is to be able to
iterate on all hipe constants in hipe_bifs_show_literals_0.

There was an outdated comment about an interaction with the garbage
collector. The current implementation of the gc does not refer to the
pool at all and related #include directives were removed.
  • Loading branch information
pguyot committed Aug 29, 2010
1 parent 980773b commit d94f2c6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 44 deletions.
1 change: 0 additions & 1 deletion erts/emulator/beam/erl_nmgc.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "erl_nmgc.h"
#include "erl_debug.h"
#if HIPE
#include "hipe_bif0.h" /* for hipe_constants_{start,next} */
#include "hipe_stack.h"
#endif

Expand Down
71 changes: 39 additions & 32 deletions erts/emulator/hipe/hipe_bif0.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,49 +453,56 @@ BIF_RETTYPE hipe_bifs_alloc_data_2(BIF_ALIST_2)
* Memory area for constant Erlang terms.
*
* These constants must not be forwarded by the gc.
* Therefore, the gc needs to be able to distinguish between
* collectible objects and constants. Unfortunately, an Erlang
* process' collectible objects are scattered around in two
* heaps and a list of message buffers, so testing "is X a
* collectible object?" can be expensive.
*
* Instead, constants are placed in a single contiguous area,
* which allows for an inexpensive "is X a constant?" test.
*
* XXX: Allow this area to be grown.
*/

/* not static, needed by garbage collector */
Eterm *hipe_constants_start = NULL;
Eterm *hipe_constants_next = NULL;
static unsigned constants_avail_words = 0;
#define CONSTANTS_BYTES (1536*1024*sizeof(Eterm)) /* 1.5 M words */
struct hipe_constants_pool* hipe_constants_current_pool = NULL;

static Eterm *constants_alloc(unsigned nwords)
{
Eterm *next;
#define POOL_MINSIZE_IN_WORDS (1536*1024) /* 1.5 M words */

static Eterm* constants_alloc(unsigned nwords)
{
Eterm* result;
Eterm* next = NULL;

/* initialise at the first call */
if ((next = hipe_constants_next) == NULL) {
next = (Eterm*)erts_alloc(ERTS_ALC_T_HIPE, CONSTANTS_BYTES);
hipe_constants_start = next;
hipe_constants_next = next;
constants_avail_words = CONSTANTS_BYTES / sizeof(Eterm);
if (hipe_constants_current_pool != NULL) {
result = hipe_constants_current_pool->next;
next = result + nwords;
if (next > hipe_constants_current_pool->end) {
next = NULL; /* allocate a new pool */
} else {
}
}
if (nwords > constants_avail_words) {
fprintf(stderr, "Native code constants pool depleted!\r\n");
/* Must terminate immediately. erl_exit() seems to
continue running some code which then SIGSEGVs. */
exit(1);

if (next == NULL) {
struct hipe_constants_pool* prevpool = hipe_constants_current_pool;
int pool_size = POOL_MINSIZE_IN_WORDS;
if (pool_size < nwords) {
pool_size = nwords;
}
hipe_constants_current_pool = (struct hipe_constants_pool*)erts_alloc(ERTS_ALC_T_HIPE, (pool_size * sizeof(Eterm)) + sizeof(struct hipe_constants_pool));
result = hipe_constants_current_pool + sizeof(struct hipe_constants_pool);
next = result + nwords;

hipe_constants_current_pool->start = result;
hipe_constants_current_pool->end = hipe_constants_current_pool->start + pool_size;
hipe_constants_current_pool->prevpool = prevpool;
}
constants_avail_words -= nwords;
hipe_constants_next = next + nwords;
return next;

hipe_constants_current_pool->next = next;
return result;
}

BIF_RETTYPE hipe_bifs_constants_size_0(BIF_ALIST_0)
{
BIF_RET(make_small(hipe_constants_next - hipe_constants_start));
unsigned int result = 0;
struct hipe_constants_pool* pool = hipe_constants_current_pool;
while (pool != NULL) {
result += (pool->next - pool->start);
pool = pool->prevpool;
}

BIF_RET(make_small(result));
}

/*
Expand Down
12 changes: 9 additions & 3 deletions erts/emulator/hipe/hipe_bif0.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,15 @@

extern Uint *hipe_bifs_find_pc_from_mfa(Eterm mfa);

/* shared with ggc.c -- NOT an official API */
extern Eterm *hipe_constants_start;
extern Eterm *hipe_constants_next;
struct hipe_constants_pool {
Eterm* start;
Eterm* next;
Eterm* end;
struct hipe_constants_pool* prevpool;
};

/* exported for hipe_bifs_show_literals_0 */
extern struct hipe_constants_pool* hipe_constants_current_pool;

extern void hipe_mfa_info_table_init(void);
extern void *hipe_get_remote_na(Eterm m, Eterm f, unsigned int a);
Expand Down
16 changes: 9 additions & 7 deletions erts/emulator/hipe/hipe_bif2.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ BIF_RETTYPE hipe_bifs_show_term_1(BIF_ALIST_1)

BIF_RETTYPE hipe_bifs_show_literals_0(BIF_ALIST_0)
{
Eterm *p;

p = hipe_constants_start;
for (; p < hipe_constants_next; ++p)
printf("0x%0*lx: 0x%0*lx\r\n",
2*(int)sizeof(long), (unsigned long)p,
2*(int)sizeof(long), *p);
struct hipe_constants_pool* pool = hipe_constants_current_pool;
while (pool != NULL) {
Eterm *p = pool->start;
for (; p < pool->next; ++p)
printf("0x%0*lx: 0x%0*lx\r\n",
2*(int)sizeof(long), (unsigned long)p,
2*(int)sizeof(long), *p);
pool = pool->prevpool;
}
BIF_RET(am_true);
}

Expand Down
1 change: 0 additions & 1 deletion erts/emulator/hipe/hipe_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

#include "hipe_stack.h"
#include "hipe_gc.h"
#include "hipe_bif0.h" /* for hipe_constants_{start,next} */

Eterm *fullsweep_nstack(Process *p, Eterm *n_htop)
{
Expand Down

0 comments on commit d94f2c6

Please sign in to comment.