Skip to content

Commit

Permalink
[mono] Optimize (typedef|table|declsec)_locator metadata loading (#10…
Browse files Browse the repository at this point in the history
…0157)

* Optimize typedef_locator, table_locator and declsec_locator by hoisting initialization out
* Cleanup duplicated code with different understandings of locator_t
  • Loading branch information
kg authored Apr 12, 2024
1 parent 4e98e57 commit be3ad0d
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 157 deletions.
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;
mono_locator_t *loc = (mono_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 = mono_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
25 changes: 9 additions & 16 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,20 +761,11 @@ 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)
{
locator_t *loc = (locator_t *)a;
mono_locator_t *loc = (mono_locator_t *)a;
const char *bb = (const char *)b;
guint32 table_index = GPTRDIFF_TO_UINT32 ((bb - loc->t->base) / loc->t->row_size);
guint32 col;
Expand Down Expand Up @@ -808,14 +799,16 @@ lookup_custom_debug_information (MonoImage* image, guint32 token, uint8_t parent
{
MonoTableInfo *tables = image->tables;
MonoTableInfo *table = &tables[MONO_TABLE_CUSTOMDEBUGINFORMATION];
locator_t loc;
mono_locator_t loc;

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 = mono_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;
} mono_locator_t;

MONO_ALWAYS_INLINE static mono_locator_t
mono_locator_init (MonoTableInfo *t, guint32 idx, guint32 col_idx)
{
mono_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

0 comments on commit be3ad0d

Please sign in to comment.