Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] [hotreload] Adjust row_size and size_bitfield from the baseline based on the delta sizes #113995

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
106 changes: 60 additions & 46 deletions src/mono/mono/component/hot_reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,24 +924,69 @@ delta_info_initialize_mutants (const MonoImage *base, const BaselineInfo *base_i
g_assert (prev_table != NULL);

MonoTableInfo *tbl = &delta->mutants [i];
if (prev_table->rows_ == 0) {
/* table was empty in the baseline and it was empty in the prior generation, but now we have some rows. Use the format of the mutant table. */
g_assert (prev_table->row_size == 0);
tbl->row_size = delta->delta_image->tables [i].row_size;
tbl->size_bitfield = delta->delta_image->tables [i].size_bitfield;
} else {
tbl->row_size = prev_table->row_size;
tbl->size_bitfield = prev_table->size_bitfield;
}
tbl->row_size = delta->delta_image->tables [i].row_size;
tbl->size_bitfield = delta->delta_image->tables [i].size_bitfield;
mono_metadata_compute_column_offsets (tbl);
tbl->rows_ = rows;
g_assert (tbl->rows_ > 0 && tbl->row_size != 0);

tbl->base = mono_mempool_alloc (delta->pool, tbl->row_size * rows);
g_assert (table_info_get_rows (prev_table) == count->prev_gen_rows);

/* copy the old rows and zero out the new ones */
memcpy ((char*)tbl->base, prev_table->base, count->prev_gen_rows * tbl->row_size);
/* copy the old rows and zero out the new ones */
/* we need to copy following the new format (uncompressed one)*/
for (guint32 j = 0 ; j < count->prev_gen_rows; j++)
{
guint32 src_offset = 0, dst_offset = 0;
guint32 dst_bitfield = tbl->size_bitfield;
guint32 src_bitfield = prev_table->size_bitfield;
const char *src_base = (char*)prev_table->base + j * prev_table->row_size;
char *dst_base = (char*)tbl->base + j * tbl->row_size;
for (guint col = 0; col < mono_metadata_table_count (dst_bitfield); ++col) {
guint32 dst_col_size = mono_metadata_table_size (dst_bitfield, col);
guint32 src_col_size = mono_metadata_table_size (src_bitfield, col);
{
const char *src = src_base + src_offset;
char *dst = dst_base + dst_offset;

/* copy src to dst, via a temporary to adjust for size differences */
/* FIXME: unaligned access, endianness */
guint32 tmp;

switch (src_col_size) {
case 1:
tmp = *(guint8*)src;
break;
case 2:
tmp = *(guint16*)src;
break;
case 4:
tmp = *(guint32*)src;
break;
default:
g_assert_not_reached ();
}

/* FIXME: unaligned access, endianness */
switch (dst_col_size) {
case 1:
*(guint8*)dst = (guint8)tmp;
break;
case 2:
*(guint16*)dst = (guint16)tmp;
break;
case 4:
*(guint32*)dst = tmp;
break;
default:
g_assert_not_reached ();
}
}
src_offset += src_col_size;
dst_offset += dst_col_size;
}
g_assert (dst_offset == tbl->row_size);
}
memset (((char*)tbl->base) + count->prev_gen_rows * tbl->row_size, 0, count->inserted_rows * tbl->row_size);
}
}
Expand Down Expand Up @@ -1386,8 +1431,8 @@ delta_info_mutate_row (MonoImage *image_dmeta, DeltaInfo *cur_delta, guint32 log

/* The complication here is that we want the mutant table to look like the table in
* the baseline image with respect to column widths, but the delta tables are generally coming in
* uncompressed (4-byte columns). So we have to copy one column at a time and adjust the
* widths as we go.
* uncompressed (4-byte columns). And we have already adjusted the baseline image column widths
* so we can use memcpy here.
*/

guint32 dst_bitfield = cur_delta->mutants [token_table].size_bitfield;
Expand All @@ -1401,41 +1446,10 @@ delta_info_mutate_row (MonoImage *image_dmeta, DeltaInfo *cur_delta, guint32 log
guint32 dst_col_size = mono_metadata_table_size (dst_bitfield, col);
guint32 src_col_size = mono_metadata_table_size (src_bitfield, col);
if ((m_SuppressedDeltaColumns [token_table] & (1 << col)) == 0) {
g_assert(src_col_size == dst_col_size);
const char *src = src_base + src_offset;
char *dst = dst_base + dst_offset;

/* copy src to dst, via a temporary to adjust for size differences */
/* FIXME: unaligned access, endianness */
guint32 tmp;

switch (src_col_size) {
case 1:
tmp = *(guint8*)src;
break;
case 2:
tmp = *(guint16*)src;
break;
case 4:
tmp = *(guint32*)src;
break;
default:
g_assert_not_reached ();
}

/* FIXME: unaligned access, endianness */
switch (dst_col_size) {
case 1:
*(guint8*)dst = (guint8)tmp;
break;
case 2:
*(guint16*)dst = (guint16)tmp;
break;
case 4:
*(guint32*)dst = tmp;
break;
default:
g_assert_not_reached ();
}
memcpy(dst, src, src_col_size);
}
src_offset += src_col_size;
dst_offset += dst_col_size;
Expand Down
Loading