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] Optimize (typedef|table|declsec)_locator metadata loading #100157

Merged
merged 7 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
13 changes: 2 additions & 11 deletions src/mono/mono/component/hot_reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -2776,14 +2776,6 @@ add_param_info_for_method (BaselineInfo *base_info, uint32_t param_token, uint32
}
}

/* HACK - keep in sync with locator_t in metadata/metadata.c */
typedef struct {
guint32 idx; /* The index that we are trying to locate */
guint32 col_idx; /* The index in the row where idx may be stored */
MonoTableInfo *t; /* pointer to the table */
guint32 result;
} upd_locator_t;

void*
hot_reload_metadata_linear_search (MonoImage *base_image, MonoTableInfo *base_table, const void *key, BinarySearchComparer comparer)
{
Expand All @@ -2804,11 +2796,10 @@ hot_reload_metadata_linear_search (MonoImage *base_image, MonoTableInfo *base_ta
g_assert (success);
uint32_t rows = table_info_get_rows (latest_mod_table);

upd_locator_t *loc = (upd_locator_t*)key;
locator_t *loc = (locator_t*)key;
g_assert (loc);
loc->result = 0;
/* HACK: this is so that the locator can compute the row index of the given row. but passing the mutant table to other metadata functions could backfire. */
loc->t = (MonoTableInfo*)latest_mod_table;
*loc = locator_init ((MonoTableInfo*)latest_mod_table, loc->idx, loc->col_idx);
for (uint32_t idx = 0; idx < rows; ++idx) {
const char *row = latest_mod_table->base + idx * latest_mod_table->row_size;
if (!comparer (loc, row))
Expand Down
21 changes: 7 additions & 14 deletions src/mono/mono/metadata/debug-mono-ppdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ enum {
MONO_HAS_CUSTOM_DEBUG_MASK = 0x1f
};

gboolean
gboolean
mono_get_pe_debug_info_full (MonoImage *image, guint8 *out_guid, gint32 *out_age, gint32 *out_timestamp, guint8 **ppdb_data,
int *ppdb_uncompressed_size, int *ppdb_compressed_size, char **pdb_path, GArray *pdb_checksum_hash_type, GArray *pdb_checksum)
{
Expand Down Expand Up @@ -761,16 +761,7 @@ mono_ppdb_lookup_locals (MonoDebugMethodInfo *minfo)
return mono_ppdb_lookup_locals_internal (image, method_idx);
}

/*
* We use this to pass context information to the row locator
*/
typedef struct {
guint32 idx; /* The index that we are trying to locate */
guint32 col_idx; /* The index in the row where idx may be stored */
MonoTableInfo *t; /* pointer to the table */
guint32 result;
} locator_t;

// FIXME: This duplicates table_locator from metadata.c
static int
table_locator (const void *a, const void *b)
{
Expand Down Expand Up @@ -813,9 +804,11 @@ lookup_custom_debug_information (MonoImage* image, guint32 token, uint8_t parent
if (!table->base)
return 0;

loc.idx = (mono_metadata_token_index (token) << MONO_HAS_CUSTOM_DEBUG_BITS) | parent_type;
loc.col_idx = MONO_CUSTOMDEBUGINFORMATION_PARENT;
loc.t = table;
loc = locator_init (
table,
(mono_metadata_token_index (token) << MONO_HAS_CUSTOM_DEBUG_BITS) | parent_type,
MONO_CUSTOMDEBUGINFORMATION_PARENT
);

if (!mono_binary_search (&loc, table->base, table_info_get_rows (table), table->row_size, table_locator))
return NULL;
Expand Down
50 changes: 50 additions & 0 deletions src/mono/mono/metadata/metadata-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,56 @@ mono_metadata_get_class_guid (MonoClass* klass, uint8_t* guid, MonoError *error)

#define MONO_CLASS_IS_INTERFACE_INTERNAL(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_INTERFACE) || mono_type_is_generic_parameter (m_class_get_byval_arg (c)))

/*
* We use this to pass context information to the row locator
*/
typedef struct {
// caller inputs
// note: we can't optimize around locator_t.idx yet because a few call sites mutate it
guint32 idx; /* The index that we are trying to locate */
// no call sites mutate this so we can optimize around it
guint32 col_idx; /* The index in the row where idx may be stored */
// no call sites mutate this so we can optimize around it
MonoTableInfo *t; /* pointer to the table */

// optimization data
gint32 metadata_has_updates; // -1: uninitialized. 0/1: value
const char * t_base;
guint t_row_size;
guint32 t_rows;
guint32 column_size;
const char * first_column_data;

// result
guint32 result;
} locator_t;
kg marked this conversation as resolved.
Show resolved Hide resolved

MONO_ALWAYS_INLINE static locator_t
kg marked this conversation as resolved.
Show resolved Hide resolved
locator_init (MonoTableInfo *t, guint32 idx, guint32 col_idx)
kg marked this conversation as resolved.
Show resolved Hide resolved
{
locator_t result = { 0, };

result.idx = idx;
result.col_idx = col_idx;
result.t = t;

g_assert (t);
// FIXME: Callers shouldn't rely on this
if (!t->base)
return result;

// optimization data for decode_locator_row
result.metadata_has_updates = -1;
result.t_base = t->base;
result.t_row_size = t->row_size;
result.t_rows = table_info_get_rows (t);
g_assert (col_idx < mono_metadata_table_count (t->size_bitfield));
result.column_size = mono_metadata_table_size (t->size_bitfield, col_idx);
result.first_column_data = result.t_base + t->column_offsets [col_idx];

return result;
}

static inline gboolean
m_image_is_raw_data_allocated (MonoImage *image)
{
Expand Down
Loading
Loading