Chez Scheme: fix check on reference displacement
There is no danger of a displcement going off the end of an allocaiton page, but the reason is a little more subtle for a 32-bit platform.
This commit is contained in:
parent
7a81ff13c2
commit
7c27ef2ab0
|
@ -244,7 +244,7 @@ ptr S_find_more_gc_room(thread_gc *tgc, ISPC s, IGEN g, iptr n, ptr old) {
|
|||
|
||||
tgc->during_alloc += 1;
|
||||
|
||||
nsegs = (uptr)(n + ptr_bytes + bytes_per_segment - 1) >> segment_offset_bits;
|
||||
nsegs = (uptr)(n + allocation_segment_tail_padding + bytes_per_segment - 1) >> segment_offset_bits;
|
||||
|
||||
/* block requests to minimize fragmentation and improve cache locality */
|
||||
if (s == space_code && nsegs < 16) nsegs = 16;
|
||||
|
@ -256,7 +256,7 @@ ptr S_find_more_gc_room(thread_gc *tgc, ISPC s, IGEN g, iptr n, ptr old) {
|
|||
|
||||
tgc->base_loc[g][s] = new;
|
||||
tgc->sweep_loc[g][s] = new;
|
||||
tgc->bytes_left[g][s] = (new_bytes - n) - ptr_bytes;
|
||||
tgc->bytes_left[g][s] = (new_bytes - n) - allocation_segment_tail_padding;
|
||||
tgc->next_loc[g][s] = (ptr)((uptr)new + n);
|
||||
|
||||
#if defined(WRITE_XOR_EXECUTE_CODE)
|
||||
|
|
|
@ -338,8 +338,15 @@ static void idiot_checks() {
|
|||
fprintf(stderr, "reference displacement does not match bytevector or flvector displacement\n");
|
||||
oops = 1;
|
||||
}
|
||||
if (reference_disp >= (2 * ptr_bytes)) {
|
||||
fprintf(stderr, "reference displacement is larger than two words\n");
|
||||
|
||||
if (reference_disp >= (allocation_segment_tail_padding
|
||||
/* to determine the minimum distince from the start of an
|
||||
alocated object to the end of its alloted space, take the
|
||||
smaller of the allocation alignment or sizeof(double), where
|
||||
the latter is relevant for a flonum that points into the
|
||||
imaginary half of an inexactnum */
|
||||
+ ((byte_alignment < sizeof(double)) ? byte_alignment : sizeof(double)))) {
|
||||
fprintf(stderr, "reference displacement can extend past the end of an allocation page\n");
|
||||
oops = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -666,7 +666,8 @@ static void enable_code_write(ptr tc, IGEN maxg, IBOOL on, IBOOL current, void *
|
|||
if (addr == NULL) {
|
||||
return;
|
||||
}
|
||||
bytes = (char*)tgc->next_loc[0][space_code] - (char*)tgc->base_loc[0][space_code] + tgc->bytes_left[0][space_code] + ptr_bytes;
|
||||
bytes = ((char*)tgc->next_loc[0][space_code] - (char*)tgc->base_loc[0][space_code]
|
||||
+ tgc->bytes_left[0][space_code] + allocation_segment_tail_padding);
|
||||
if (mprotect(addr, bytes, flags) != 0) {
|
||||
S_error_abort("failed to protect current allocation segments");
|
||||
}
|
||||
|
|
|
@ -112,8 +112,12 @@ FORCEINLINE ptr S_reference_to_object(ptr p) {
|
|||
return ((ptr)((uptr)(p) - reference_disp));
|
||||
}
|
||||
|
||||
/* We take advantage of the fact `reference_disp` is less than two
|
||||
words and that every allocation region has a one-word padding, so
|
||||
/* An allocation region needs room at the end of a formarding pointer
|
||||
as a terminator */
|
||||
#define allocation_segment_tail_padding ptr_bytes
|
||||
|
||||
/* We take advantage of the fact `reference_disp` is less than the
|
||||
minimum allocation size plus `allocation_segment_tail_padding`, so
|
||||
there's no possibility that the referece address for an object will
|
||||
be off of its GC-managed page (even for a pair or an bytevector
|
||||
with an empty payload). */
|
||||
|
|
Loading…
Reference in New Issue
Block a user