Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 6a4e02a

Browse files
committed
We need to have seg_mapping_table aligned on its natural alignement (ptr size). When it's not aligned,
aside from the perf problem, we also have a functional problem when an address that's not on a heap segment is passed - we could read an intermediate value which would cause an AV. If the address is on a heap segment it means we are guaranteed to read a ptr size atomically. This only affects functions like IsHeapPointer which can be run when EE is not suspended.
1 parent f6ad954 commit 6a4e02a

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

src/gc/gc.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3377,6 +3377,13 @@ size_t size_seg_mapping_table_of (uint8_t* from, uint8_t* end)
33773377
return sizeof (seg_mapping)*((end - from) / gc_heap::min_segment_size);
33783378
}
33793379

3380+
// for seg_mapping_table we want it to start from a pointer sized address.
3381+
inline
3382+
size_t align_for_seg_mapping_table (size_t size)
3383+
{
3384+
return ((size + (sizeof (uint8_t*) - 1)) &~ (sizeof (uint8_t*) - 1));
3385+
}
3386+
33803387
inline
33813388
size_t seg_mapping_word_of (uint8_t* add)
33823389
{
@@ -6910,6 +6917,10 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
69106917

69116918
#ifdef GROWABLE_SEG_MAPPING_TABLE
69126919
size_t st = size_seg_mapping_table_of (g_lowest_address, g_highest_address);
6920+
size_t st_table_offset = sizeof(card_table_info) + cs + bs + cb + wws;
6921+
size_t st_table_offset_aligned = align_for_seg_mapping_table (st_table_offset);
6922+
6923+
st += (st_table_offset_aligned - st_table_offset);
69136924
#else //GROWABLE_SEG_MAPPING_TABLE
69146925
size_t st = 0;
69156926
#endif //GROWABLE_SEG_MAPPING_TABLE
@@ -6958,7 +6969,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
69586969
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
69596970

69606971
#ifdef GROWABLE_SEG_MAPPING_TABLE
6961-
seg_mapping_table = (seg_mapping*)((uint8_t*)card_table_brick_table (ct) + bs + cb + wws);
6972+
seg_mapping_table = (seg_mapping*)(mem + st_table_offset_aligned);
69626973
seg_mapping_table = (seg_mapping*)((uint8_t*)seg_mapping_table -
69636974
size_seg_mapping_table_of (0, (align_lower_segment (g_lowest_address))));
69646975
#endif //GROWABLE_SEG_MAPPING_TABLE
@@ -7098,6 +7109,9 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
70987109

70997110
#ifdef GROWABLE_SEG_MAPPING_TABLE
71007111
size_t st = size_seg_mapping_table_of (saved_g_lowest_address, saved_g_highest_address);
7112+
size_t st_table_offset = sizeof(card_table_info) + cs + bs + cb + wws;
7113+
size_t st_table_offset_aligned = align_for_seg_mapping_table (st_table_offset);
7114+
st += (st_table_offset_aligned - st_table_offset);
71017115
#else //GROWABLE_SEG_MAPPING_TABLE
71027116
size_t st = 0;
71037117
#endif //GROWABLE_SEG_MAPPING_TABLE
@@ -7120,7 +7134,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
71207134
dprintf (GC_TABLE_LOG, ("Table alloc for %Id bytes: [%Ix, %Ix[",
71217135
alloc_size, (size_t)mem, (size_t)((uint8_t*)mem+alloc_size)));
71227136

7123-
{
7137+
{
71247138
// mark array will be committed separately (per segment).
71257139
size_t commit_size = alloc_size - ms;
71267140

@@ -7160,7 +7174,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
71607174

71617175
#ifdef GROWABLE_SEG_MAPPING_TABLE
71627176
{
7163-
seg_mapping* new_seg_mapping_table = (seg_mapping*)((uint8_t*)card_table_brick_table (ct) + bs + cb + wws);
7177+
seg_mapping* new_seg_mapping_table = (seg_mapping*)(mem + st_table_offset_aligned);
71647178
new_seg_mapping_table = (seg_mapping*)((uint8_t*)new_seg_mapping_table -
71657179
size_seg_mapping_table_of (0, (align_lower_segment (saved_g_lowest_address))));
71667180
memcpy(&new_seg_mapping_table[seg_mapping_word_of(g_lowest_address)],

0 commit comments

Comments
 (0)