Skip to content

[mbr] Add a global has_updates flag #47716

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

Merged
merged 1 commit into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 20 additions & 3 deletions src/mono/mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -910,20 +910,37 @@ void
mono_image_append_class_to_reflection_info_set (MonoClass *klass);

#ifndef ENABLE_METADATA_UPDATE
static inline gboolean
mono_metadata_has_updates (void)
{
return FALSE;
}

static inline void
mono_image_effective_table (const MonoTableInfo **t, int *idx)
{
}
#else /* ENABLE_METADATA_UPDATE */
extern int mono_metadata_update_has_updates_private;

/* returns TRUE if there's at least one update */
static inline gboolean
mono_metadata_has_updates (void)
{
return mono_metadata_update_has_updates_private != 0;
}

void
mono_image_effective_table_slow (const MonoTableInfo **t, int *idx);

static inline void
mono_image_effective_table (const MonoTableInfo **t, int *idx)
{
if (G_LIKELY (*idx < (*t)->rows))
return;
mono_image_effective_table_slow (t, idx);
if (G_UNLIKELY (mono_metadata_has_updates ())) {
if (G_UNLIKELY (*idx >= (*t)->rows)) {
mono_image_effective_table_slow (t, idx);
}
}
}

int
Expand Down
18 changes: 18 additions & 0 deletions src/mono/mono/metadata/metadata-update.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ static MonoNativeTlsKey exposed_generation_id;
#define UPDATE_DEBUG(stmt) /*empty */
#endif

/*
* set to non-zero if at least one update has been published.
*/
int mono_metadata_update_has_updates_private;

/* For each delta image, for each table:
* - the total logical number of rows for the previous generation
* - the number of modified rows in the current generation
Expand Down Expand Up @@ -172,6 +177,7 @@ metadata_update_local_generation (MonoImage *base, MonoImage *delta);
void
mono_metadata_update_init (void)
{
mono_metadata_update_has_updates_private = 0;
table_to_image_init ();
mono_native_tls_alloc (&exposed_generation_id, NULL);
}
Expand Down Expand Up @@ -232,6 +238,15 @@ thread_set_exposed_generation (uint32_t value)
mono_native_tls_set_value (exposed_generation_id, GUINT_TO_POINTER((guint)value));
}

/**
* LOCKING: assumes the publish_lock is held
*/
static void
metadata_update_set_has_updates (void)
{
mono_metadata_update_has_updates_private = 1;
}

uint32_t
mono_metadata_update_prepare (MonoDomain *domain) {
mono_lazy_initialize (&metadata_update_lazy_init, initialize);
Expand All @@ -240,6 +255,8 @@ mono_metadata_update_prepare (MonoDomain *domain) {
*/
publish_lock ();
uint32_t alloc_gen = ++update_alloc_frontier;
/* Have to set this here so the updater starts using the slow path of metadata lookups */
metadata_update_set_has_updates ();
/* Expose the alloc frontier to the updater thread */
thread_set_exposed_generation (alloc_gen);
return alloc_gen;
Expand Down Expand Up @@ -320,6 +337,7 @@ mono_image_append_delta (MonoImage *base, MonoImage *delta)
return;
}
g_assert (((MonoImage*)base->delta_image_last->data)->generation < delta->generation);
/* FIXME: g_list_append returns the previous end of the list, not the newly appended element! */
base->delta_image_last = g_list_append (base->delta_image_last, delta);
}

Expand Down
44 changes: 41 additions & 3 deletions src/mono/mono/metadata/metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,9 @@ dword_align (const unsigned char *ptr)
return (const unsigned char *) (((gsize) (ptr + 3)) & ~3);
}

static void
mono_metadata_decode_row_slow (const MonoTableInfo *t, int idx, guint32 *res, int res_size);

/**
* mono_metadata_decode_row:
* \param t table to extract information from.
Expand All @@ -1351,8 +1354,17 @@ dword_align (const unsigned char *ptr)
void
mono_metadata_decode_row (const MonoTableInfo *t, int idx, guint32 *res, int res_size)
{
mono_image_effective_table (&t, &idx);
if (G_UNLIKELY (mono_metadata_has_updates ())) {
mono_metadata_decode_row_slow (t, idx, res, res_size);
} else {
mono_metadata_decode_row_raw (t, idx, res, res_size);
}
}

void
mono_metadata_decode_row_slow (const MonoTableInfo *t, int idx, guint32 *res, int res_size)
{
mono_image_effective_table (&t, &idx);
mono_metadata_decode_row_raw (t, idx, res, res_size);
}

Expand Down Expand Up @@ -1470,6 +1482,11 @@ mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const M
return TRUE;
}

static guint32
mono_metadata_decode_row_col_raw (const MonoTableInfo *t, int idx, guint col);
static guint32
mono_metadata_decode_row_col_slow (const MonoTableInfo *t, int idx, guint col);

/**
* mono_metadata_decode_row_col:
* \param t table to extract information from.
Expand All @@ -1481,13 +1498,34 @@ mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const M
*/
guint32
mono_metadata_decode_row_col (const MonoTableInfo *t, int idx, guint col)
{
if (G_UNLIKELY (mono_metadata_has_updates ())) {
return mono_metadata_decode_row_col_slow (t, idx, col);
} else {
return mono_metadata_decode_row_col_raw (t, idx, col);
}
}

guint32
mono_metadata_decode_row_col_slow (const MonoTableInfo *t, int idx, guint col)
{
mono_image_effective_table (&t, &idx);
return mono_metadata_decode_row_col_raw (t, idx, col);
}

/**
* mono_metadata_decode_row_col_raw:
*
* Same as \c mono_metadata_decode_row_col but doesn't look for the effective
* table on metadata updates.
*/
guint32
mono_metadata_decode_row_col_raw (const MonoTableInfo *t, int idx, guint col)
{
int i;
const char *data;
int n;

mono_image_effective_table (&t, &idx);

guint32 bitfield = t->size_bitfield;

g_assert (idx < t->rows);
Expand Down