Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
36d9693
checkpoint: allow adding methods to existing classes.
lambdageek Jun 8, 2021
0c4aa74
fixme in loader
lambdageek Jun 22, 2021
c68b895
[metadata] Add mono_metadata_table_num_rows
lambdageek Jul 13, 2021
d0b7d77
add table to ptr table helper
lambdageek Jul 13, 2021
25e2fb8
Param attr lookups for deltas can have param_index == 0
lambdageek Jul 13, 2021
099edb5
WIP: start adding support for parameter additions.
lambdageek Jul 13, 2021
6cbee0b
WIP: add MethodDef -> TypeDef lookup
lambdageek Jul 15, 2021
8cfb9fb
Add hot reload test for lambda capturing this
lambdageek Jul 15, 2021
287654e
clarify comments about MONO_METHOD_PARAMLIST
lambdageek Jul 15, 2021
6336699
[hot_reload] Store debug info of updated methods
lambdageek Jul 16, 2021
cdfb9a7
[hot_reload] Allocate modifiable tables in DeltaInfo
lambdageek Nov 12, 2021
4b250b9
[mini] Allow MONO_VERBOSE_METHOD='*:*'
lambdageek Nov 12, 2021
cdcf003
populate mutated table rows
lambdageek Nov 12, 2021
ac0ac83
[hot_reload] Switch lookups to the mutant tables
lambdageek Nov 16, 2021
25253f7
cleanup: remove of effective_table calculation
lambdageek Nov 19, 2021
38b17da
cleanup: Remove relative_delta_index from component API
lambdageek Nov 19, 2021
d1c1c8e
cleanup: Pass DeltaInfo to relative_delta_index
lambdageek Nov 19, 2021
629075d
cleanup: Store a list of DeltaInfo in the BaselineInfo
lambdageek Nov 19, 2021
3114871
Turn off method addition support, for now
lambdageek Nov 19, 2021
6e56f85
Fix null ptr when checking for updated ppdb info
lambdageek Nov 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
populate mutated table rows
leave suppressed columns unchanged
  • Loading branch information
lambdageek committed Nov 12, 2021
commit cdcf003398d9cbce71911d3a412fe27b7ae8153c
89 changes: 85 additions & 4 deletions src/mono/mono/component/hot_reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#define ALLOW_METHOD_ADD

typedef struct _DeltaInfo DeltaInfo;

static void
hot_reload_init (void);
Expand Down Expand Up @@ -64,6 +65,10 @@ hot_reload_apply_changes (int origin, MonoImage *base_image, gconstpointer dmeta
static int
hot_reload_relative_delta_index (MonoImage *image_dmeta, int token);

static int
hot_reload_relative_delta_index_full (MonoImage *image_dmeta, DeltaInfo *delta_info, int token);


static void
hot_reload_close_except_pools_all (MonoImage *base_image);

Expand Down Expand Up @@ -167,7 +172,7 @@ typedef struct _delta_row_count {
} delta_row_count;

/* Additional informaiton for MonoImages representing deltas */
typedef struct _DeltaInfo {
struct _DeltaInfo {
uint32_t generation; /* global update ID that added this delta image */

/* Maps MethodDef token indices to a pointer into the RVA of the delta IL */
Expand All @@ -185,7 +190,7 @@ typedef struct _DeltaInfo {
MonoMemPool *pool; /* mutated tables are allocated here */

MonoTableInfo mutants[MONO_TABLE_NUM];
} DeltaInfo;
};


/* Additional informaiton for baseline MonoImages */
Expand All @@ -205,8 +210,12 @@ typedef struct _BaselineInfo {
GHashTable *method_parent; /* maps added methoddef tokens to typedef tokens */
} BaselineInfo;


#define DOTNET_MODIFIABLE_ASSEMBLIES "DOTNET_MODIFIABLE_ASSEMBLIES"

/* See Note: Suppressed Columns */
static guint16 m_SuppressedDeltaColumns [MONO_TABLE_NUM];

/**
* mono_metadata_update_enable:
* \param modifiable_assemblies_out: set to MonoModifiableAssemblies value
Expand Down Expand Up @@ -516,6 +525,12 @@ hot_reload_init (void)
{
table_to_image_init ();
mono_native_tls_alloc (&exposed_generation_id, NULL);

/* See CMiniMdRW::ApplyDelta in metamodelenc.cpp in CoreCLR */
m_SuppressedDeltaColumns[MONO_TABLE_EVENTMAP] = (1 << MONO_EVENT_MAP_EVENTLIST);
m_SuppressedDeltaColumns[MONO_TABLE_PROPERTYMAP] = (1 << MONO_PROPERTY_MAP_PROPERTY_LIST);
m_SuppressedDeltaColumns[MONO_TABLE_METHOD] = (1 << MONO_METHOD_PARAMLIST);
m_SuppressedDeltaColumns[MONO_TABLE_TYPEDEF] = (1 << MONO_TYPEDEF_FIELD_LIST)|(1<<MONO_TYPEDEF_METHOD_LIST);
}

static
Expand Down Expand Up @@ -959,7 +974,6 @@ int
hot_reload_relative_delta_index (MonoImage *image_dmeta, int token)
{
MonoTableInfo *encmap = &image_dmeta->tables [MONO_TABLE_ENCMAP];
int table = mono_metadata_token_table (token);
int index = mono_metadata_token_index (token);

/* this helper expects and returns as "index origin = 1" */
Expand All @@ -971,14 +985,30 @@ hot_reload_relative_delta_index (MonoImage *image_dmeta, int token)
DeltaInfo *delta_info = delta_info_lookup (image_dmeta);
g_assert (delta_info);

return hot_reload_relative_delta_index_full (image_dmeta, delta_info, token);
}


int
hot_reload_relative_delta_index_full (MonoImage *image_dmeta, DeltaInfo *delta_info, int token)
{
MonoTableInfo *encmap = &image_dmeta->tables [MONO_TABLE_ENCMAP];

int table = mono_metadata_token_table (token);
int index = mono_metadata_token_index (token);

int index_map = delta_info->enc_recs [table];
int encmap_rows = table_info_get_rows (encmap);

if (!table_info_get_rows (encmap) || !image_dmeta->minimal_delta)
return mono_metadata_token_index (token);

/* if the table didn't have any updates in this generation and the
* table index is bigger than the last table that got updates,
* enc_recs will point past the last row */
if (index_map - 1 == encmap_rows)
return -1;

guint32 cols[MONO_ENCMAP_SIZE];
mono_metadata_decode_row (encmap, index_map - 1, cols, MONO_ENCMAP_SIZE);
int map_entry = cols [MONO_ENCMAP_TOKEN];
Expand Down Expand Up @@ -1144,6 +1174,41 @@ funccode_to_str (int func_code)
return NULL;
}

/*
* Apply the row from the delta image given by log_token to the cur_delta mutated table.
*
*/
static void
delta_info_mutate_row (MonoImage *image_base, MonoImage *image_dmeta, DeltaInfo *cur_delta, guint32 log_token)
{
int token_table = mono_metadata_token_table (log_token);
int token_index = mono_metadata_token_index (log_token); /* 1-based */

gboolean modified = token_index <= cur_delta->count [token_table].prev_gen_rows;

int delta_index = hot_reload_relative_delta_index_full (image_dmeta, cur_delta, log_token);

guint32 bitfield = image_base->tables [token_table].size_bitfield;

const char *src_base = image_dmeta->tables [token_table].base + delta_index * image_dmeta->tables [token_table].row_size;
char *dst_base = (char*)cur_delta->mutants [token_table].base + token_index * image_base->tables [token_table].row_size;

guint32 offset = 0;
for (int col = 0; col < mono_metadata_table_count (bitfield); ++col) {
guint32 col_size = mono_metadata_table_size (bitfield, col);
if ((m_SuppressedDeltaColumns [token_table] & (1 << col)) == 0) {
/* copy */
const char *src = src_base + offset;
char *dst = dst_base + offset;
memcpy (dst, src, col_size);
}
offset += col_size;
}
g_assert (offset == image_base->tables [token_table].row_size);

mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "mutate: table=0x%02x row=0x%04x delta row=0x%04x %s", token_table, token_index, delta_index, modified ? "Mod" : "Add");
}

/* Run some sanity checks first. If we detect unsupported scenarios, this
* function will fail and the metadata update should be aborted. This should
* run before anything in the metadata world is updated. */
Expand Down Expand Up @@ -1449,6 +1514,22 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen
* have it in writable memory (and not mmap-ed pages), so we can rewrite the table values.
*/


/* Prepare the mutated metadata tables */
for (int i = 0; i < rows ; ++i) {
guint32 cols [MONO_ENCLOG_SIZE];
mono_metadata_decode_row (table_enclog, i, cols, MONO_ENCLOG_SIZE);

int log_token = cols [MONO_ENCLOG_TOKEN];
int func_code = cols [MONO_ENCLOG_FUNC_CODE];

if (func_code != ENC_FUNC_DEFAULT)
continue;

delta_info_mutate_row (image_base, image_dmeta, delta_info, log_token);
}


MonoClass *add_method_klass = NULL;
uint32_t add_param_method_index = 0;

Expand Down Expand Up @@ -1882,7 +1963,7 @@ hot_reload_table_bounds_check (MonoImage *base_image, int table_index, int token
list = list->next;
table = &dmeta->tables [table_index];
/* mono_image_relative_delta_index returns a 1-based index */
ridx = hot_reload_relative_delta_index (dmeta, original_token) - 1;
ridx = hot_reload_relative_delta_index_full (dmeta, delta_info, original_token) - 1;
} while (ridx < 0 || ridx >= table_info_get_rows (table));

return FALSE;
Expand Down