Skip to content

Commit 8b8b261

Browse files
committed
move the 16-byte realignment offset to the start of the type pool rather than every object (fix #10898)
1 parent 3961eed commit 8b8b261

File tree

3 files changed

+26
-31
lines changed

3 files changed

+26
-31
lines changed

src/array.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
extern "C" {
1515
#endif
1616

17-
#define JL_ARRAY_ALIGN(jl_value, nbytes) (LLT_ALIGN((jl_value)+sizeof(jl_taggedvalue_t), nbytes)-sizeof(jl_taggedvalue_t))
17+
#define JL_ARRAY_ALIGN(jl_value, nbytes) LLT_ALIGN(jl_value, nbytes)
1818

1919

2020
// array constructors ---------------------------------------------------------

src/gc.c

+25-24
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ typedef struct _gcval_t {
184184

185185
#define GC_PAGE_LG2 14 // log2(size of a page)
186186
#define GC_PAGE_SZ (1 << GC_PAGE_LG2) // 16k
187+
#define GC_PAGE_OFFSET (16 - (sizeof(jl_taggedvalue_t) % 16))
187188

188189
// pool page metadata
189190
typedef struct _gcpage_t {
@@ -219,7 +220,7 @@ typedef struct {
219220
char pages[REGION_PG_COUNT][GC_PAGE_SZ]; // must be first, to preserve page alignment
220221
uint32_t freemap[REGION_PG_COUNT/32];
221222
gcpage_t meta[REGION_PG_COUNT];
222-
} region_t;
223+
} region_t __attribute__((aligned(GC_PAGE_SZ)));
223224
static region_t *regions[REGION_COUNT] = {NULL};
224225
// store a lower bound of the first free page in each region
225226
static int regions_lb[REGION_COUNT] = {0};
@@ -234,12 +235,12 @@ typedef struct _pool_t {
234235
uint16_t nfree; // number of free objects in page pointed into by free_list
235236
} pool_t;
236237

237-
#define PAGE_INDEX(region, data) ((GC_PAGE_DATA(data) - &(region)->pages[0][0])/GC_PAGE_SZ)
238+
#define PAGE_INDEX(region, data) ((GC_PAGE_DATA((data) - GC_PAGE_OFFSET) - &(region)->pages[0][0])/GC_PAGE_SZ)
238239
static region_t *find_region(void *ptr)
239240
{
240241
// on 64bit systems we could probably use a single region and remove this loop
241242
for (int i = 0; i < REGION_COUNT && regions[i]; i++) {
242-
if (regions[i] && (char*)ptr >= (char*)regions[i] && (char*)ptr <= (char*)regions[i] + sizeof(region_t))
243+
if ((char*)ptr >= (char*)regions[i] && (char*)ptr <= (char*)regions[i] + sizeof(region_t))
243244
return regions[i];
244245
}
245246
assert(0 && "find_region failed");
@@ -257,7 +258,7 @@ static uint8_t *page_age(gcpage_t *pg)
257258
return pg->ages;
258259
}
259260

260-
#define GC_POOL_END_OFS(osize) (((GC_PAGE_SZ/osize) - 1)*osize)
261+
#define GC_POOL_END_OFS(osize) ((((GC_PAGE_SZ - GC_PAGE_OFFSET)/(osize)) - 1)*(osize) + GC_PAGE_OFFSET)
261262

262263

263264
// layout for big (>2k) objects
@@ -701,7 +702,7 @@ static void free_page(void *p)
701702
int pg_idx = -1;
702703
int i;
703704
for(i = 0; i < REGION_COUNT && regions[i] != NULL; i++) {
704-
pg_idx = PAGE_INDEX(regions[i], p);
705+
pg_idx = PAGE_INDEX(regions[i], (char*)p+GC_PAGE_OFFSET);
705706
if (pg_idx >= 0 && pg_idx < REGION_PG_COUNT) break;
706707
}
707708
assert(i < REGION_COUNT && regions[i] != NULL);
@@ -717,7 +718,7 @@ static void free_page(void *p)
717718
size_t n_pages = (GC_PAGE_SZ + system_page_size - 1) / GC_PAGE_SZ;
718719
decommit_size = system_page_size;
719720
p = (void*)((uintptr_t)&region->pages[pg_idx][0] & ~(system_page_size - 1)); // round down to the nearest page
720-
pg_idx = PAGE_INDEX(region, p);
721+
pg_idx = PAGE_INDEX(region, (char*)p+GC_PAGE_OFFSET);
721722
if (pg_idx + n_pages > REGION_PG_COUNT) goto no_decommit;
722723
for (; n_pages--; pg_idx++) {
723724
msk = (uint32_t)(1 << ((pg_idx % 32)));
@@ -985,15 +986,15 @@ static void sweep_malloced_arrays(void)
985986
static inline gcval_t *reset_page(pool_t *p, gcpage_t *pg, gcval_t *fl)
986987
{
987988
pg->gc_bits = 0;
988-
pg->nfree = GC_PAGE_SZ/p->osize;
989+
pg->nfree = (GC_PAGE_SZ - GC_PAGE_OFFSET) / p->osize;
989990
pg->pool_n = p - norm_pools;
990-
memset(page_age(pg), 0, (GC_PAGE_SZ/p->osize + 7)/8);
991-
gcval_t *beg = (gcval_t*)pg->data;
991+
memset(page_age(pg), 0, LLT_ALIGN(GC_PAGE_SZ / p->osize, 8));
992+
gcval_t *beg = (gcval_t*)(pg->data + GC_PAGE_OFFSET);
992993
gcval_t *end = (gcval_t*)((char*)beg + (pg->nfree - 1)*p->osize);
993994
end->next = fl;
994995
pg->allocd = 0;
995-
pg->fl_begin_offset = 0;
996-
pg->fl_end_offset = (char*)end - (char*)beg;
996+
pg->fl_begin_offset = GC_PAGE_OFFSET;
997+
pg->fl_end_offset = (char*)end - (char*)beg + GC_PAGE_OFFSET;
997998
return beg;
998999
}
9991000

@@ -1002,10 +1003,10 @@ static NOINLINE void add_page(pool_t *p)
10021003
char *data = (char*)malloc_page();
10031004
if (data == NULL)
10041005
jl_throw(jl_memory_exception);
1005-
gcpage_t *pg = page_metadata(data);
1006+
gcpage_t *pg = page_metadata(data + GC_PAGE_OFFSET);
10061007
pg->data = data;
10071008
pg->osize = p->osize;
1008-
pg->ages = (uint8_t*)malloc((GC_PAGE_SZ/p->osize + 7)/8);
1009+
pg->ages = (uint8_t*)malloc(LLT_ALIGN(GC_PAGE_SZ / p->osize, 8));
10091010
gcval_t *fl = reset_page(p, pg, p->newpages);
10101011
p->newpages = fl;
10111012
}
@@ -1132,7 +1133,7 @@ static void sweep_pool_region(int region_i, int sweep_mask)
11321133
last = p->newpages;
11331134
if (last) {
11341135
gcpage_t* pg = page_metadata(last);
1135-
pg->nfree = (GC_PAGE_SZ - ((char*)last - GC_PAGE_DATA(last)))/p->osize;
1136+
pg->nfree = (GC_PAGE_SZ - ((char*)last - GC_PAGE_DATA(last))) / p->osize;
11361137
pg->allocd = 1;
11371138
}
11381139
p->newpages = NULL;
@@ -1187,11 +1188,11 @@ static gcval_t** sweep_page(pool_t* p, gcpage_t* pg, gcval_t **pfl, int sweep_ma
11871188
gcval_t *v;
11881189
size_t old_nfree = 0, nfree = 0;
11891190
int pg_freedall = 0, pg_total = 0, pg_skpd = 0;
1190-
int obj_per_page = GC_PAGE_SZ/osize;
1191+
int obj_per_page = (GC_PAGE_SZ - GC_PAGE_OFFSET)/osize;
11911192
char *data = pg->data;
11921193
uint8_t *ages = page_age(pg);
1193-
v = (gcval_t*)data;
1194-
char *lim = (char*)v + GC_PAGE_SZ - osize;
1194+
v = (gcval_t*)(data + GC_PAGE_OFFSET);
1195+
char *lim = (char*)v + GC_PAGE_SZ - GC_PAGE_OFFSET - osize;
11951196
freedall = 1;
11961197
old_nfree += pg->nfree;
11971198

@@ -1909,10 +1910,10 @@ static void clear_mark(int bits)
19091910
if (!!~line) {
19101911
for (int j = 0; j < 32; j++) {
19111912
if (!((line >> j) & 1)) {
1912-
gcpage_t *pg = page_metadata(region->pages[pg_i*32 + j]);
1913+
gcpage_t *pg = page_metadata(&region->pages[pg_i*32 + j][0] + GC_PAGE_OFFSET);
19131914
pool_t *pool = &norm_pools[pg->pool_n];
1914-
pv = (gcval_t*)pg->data;
1915-
char *lim = (char*)pv + GC_PAGE_SZ - pool->osize;
1915+
pv = (gcval_t*)(pg->data + GC_PAGE_OFFSET);
1916+
char *lim = (char*)pv + GC_PAGE_SZ - GC_PAGE_OFFSET - pool->osize;
19161917
while ((char*)pv <= lim) {
19171918
if (!verifying) arraylist_push(&bits_save[gc_bits(pv)], pv);
19181919
gc_bits(pv) = bits;
@@ -2439,7 +2440,7 @@ static void jl_mk_thread_heap(void) {
24392440
p[i].osize = szc[i];
24402441
p[i].freelist = NULL;
24412442
p[i].newpages = NULL;
2442-
p[i].end_offset = ((GC_PAGE_SZ/szc[i]) - 1)*szc[i];
2443+
p[i].end_offset = GC_POOL_END_OFS(szc[i]);
24432444
}
24442445
arraylist_new(&preserved_values, 0);
24452446
arraylist_new(&weak_refs, 0);
@@ -2504,8 +2505,8 @@ static size_t pool_stats(pool_t *p, size_t *pwaste, size_t *np, size_t *pnold)
25042505

25052506
while (pg != NULL) {
25062507
npgs++;
2507-
v = (gcval_t*)pg->data;
2508-
char *lim = (char*)v + GC_PAGE_SZ - osize;
2508+
v = (gcval_t*)(pg->data + GC_PAGE_OFFSET);
2509+
char *lim = (char*)v + GC_PAGE_SZ - GC_PAGE_OFFSET - osize;
25092510
int i = 0;
25102511
while ((char*)v <= lim) {
25112512
if (!gc_marked(v)) {
@@ -2523,7 +2524,7 @@ static size_t pool_stats(pool_t *p, size_t *pwaste, size_t *np, size_t *pnold)
25232524
gcpage_t *nextpg = NULL;
25242525
pg = nextpg;
25252526
}
2526-
*pwaste = npgs*GC_PAGE_SZ - (nused*p->osize);
2527+
*pwaste = npgs * GC_PAGE_SZ - (nused * p->osize);
25272528
*np = npgs;
25282529
*pnold = nold;
25292530
if (npgs != 0) {

src/julia.h

-6
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,6 @@ typedef struct {
101101
#endif
102102
};
103103
};
104-
#ifdef _P64
105-
uintptr_t realign16;
106-
#endif
107104
jl_value_t value;
108105
} jl_taggedvalue_t;
109106

@@ -115,9 +112,6 @@ typedef struct {
115112
static inline void jl_set_typeof(void *v, void *t)
116113
{
117114
jl_taggedvalue_t *tag = jl_astaggedvalue(v);
118-
#ifdef _P64
119-
tag->realign16 = 0xA1164A1164A11640ull;
120-
#endif
121115
tag->type = (jl_value_t*)t;
122116
}
123117
#define jl_typeis(v,t) (jl_typeof(v)==(jl_value_t*)(t))

0 commit comments

Comments
 (0)