From 6d3a31c536de71c8b89aef901a88d91bf9635484 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 18 Apr 2024 00:11:53 -0700 Subject: [PATCH] [wasm] Optimize jiterpreter option table updates (#101207) The encode-decode-parse flow for the options JSON wastes some time during startup, this approach is a bit faster. The use of a string key still adds some overhead but it's much smaller than the previous overhead, and it's dwarfed by the cost of cwrap/ccall. --- src/mono/browser/runtime/cwraps.ts | 2 ++ .../browser/runtime/jiterpreter-support.ts | 13 ++++------ src/mono/mono/mini/interp/jiterpreter.c | 22 +++++++++++++++- src/mono/mono/utils/options.c | 26 ++++++++++++++----- src/mono/mono/utils/options.h | 10 +++++++ 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/mono/browser/runtime/cwraps.ts b/src/mono/browser/runtime/cwraps.ts index ed64d5c541d4b..61ae0be40c768 100644 --- a/src/mono/browser/runtime/cwraps.ts +++ b/src/mono/browser/runtime/cwraps.ts @@ -99,6 +99,7 @@ const fn_signatures: SigLine[] = [ [true, "mono_jiterp_get_size_of_stackval", "number", []], [true, "mono_jiterp_parse_option", "number", ["string"]], [true, "mono_jiterp_get_options_as_json", "number", []], + [true, "mono_jiterp_get_option_as_int", "number", ["string"]], [true, "mono_jiterp_get_options_version", "number", []], [true, "mono_jiterp_adjust_abort_count", "number", ["number", "number"]], [true, "mono_jiterp_register_jit_call_thunk", "void", ["number", "number"]], @@ -228,6 +229,7 @@ export interface t_Cwraps { mono_jiterp_type_get_raw_value_size(type: MonoType): number; mono_jiterp_parse_option(name: string): number; mono_jiterp_get_options_as_json(): number; + mono_jiterp_get_option_as_int(name: string): number; mono_jiterp_get_options_version(): number; mono_jiterp_adjust_abort_count(opcode: number, delta: number): number; mono_jiterp_register_jit_call_thunk(cinfo: number, func: number): void; diff --git a/src/mono/browser/runtime/jiterpreter-support.ts b/src/mono/browser/runtime/jiterpreter-support.ts index e71c3700e09d8..f3f6e6a9f6b48 100644 --- a/src/mono/browser/runtime/jiterpreter-support.ts +++ b/src/mono/browser/runtime/jiterpreter-support.ts @@ -9,7 +9,6 @@ import { MintOpcode } from "./mintops"; import cwraps from "./cwraps"; import { mono_log_error, mono_log_info } from "./logging"; import { localHeapViewU8, localHeapViewU32 } from "./memory"; -import { utf8ToString } from "./strings"; import { JiterpNumberMode, BailoutReason, JiterpreterTable, JiterpCounter, JiterpMember, OpcodeInfoType @@ -2015,15 +2014,13 @@ export function getOptions () { } function updateOptions () { - const pJson = cwraps.mono_jiterp_get_options_as_json(); - const json = utf8ToString(pJson); - Module._free(pJson); - const blob = JSON.parse(json); - optionTable = {}; for (const k in optionNames) { - const info = optionNames[k]; - (optionTable)[k] = blob[info]; + const value = cwraps.mono_jiterp_get_option_as_int(optionNames[k]); + if (value > -2147483647) + (optionTable)[k] = value; + else + mono_log_info(`Failed to retrieve value of option ${optionNames[k]}`); } } diff --git a/src/mono/mono/mini/interp/jiterpreter.c b/src/mono/mono/mini/interp/jiterpreter.c index 12678e10e828a..43b71e70cd3d5 100644 --- a/src/mono/mono/mini/interp/jiterpreter.c +++ b/src/mono/mono/mini/interp/jiterpreter.c @@ -1021,8 +1021,28 @@ mono_jiterp_get_options_as_json () return mono_options_get_as_json (); } +EMSCRIPTEN_KEEPALIVE gint32 +mono_jiterp_get_option_as_int (const char *name) +{ + MonoOptionType type; + void *value_address; + + if (!mono_options_get (name, &type, &value_address)) + return INT32_MIN; + + switch (type) { + case MONO_OPTION_BOOL: + case MONO_OPTION_BOOL_READONLY: + return (*(guint8 *)value_address) != 0; + case MONO_OPTION_INT: + return *(gint32 *)value_address; + default: + return INT32_MIN; + } +} + EMSCRIPTEN_KEEPALIVE int -mono_jiterp_object_has_component_size (MonoObject ** ppObj) +mono_jiterp_object_has_component_size (MonoObject **ppObj) { MonoObject *obj = *ppObj; if (!obj) diff --git a/src/mono/mono/utils/options.c b/src/mono/mono/utils/options.c index 2a8dc6f60480b..eb94a7c220574 100644 --- a/src/mono/mono/utils/options.c +++ b/src/mono/mono/utils/options.c @@ -10,13 +10,6 @@ #include "options.h" #include "mono/utils/mono-error-internals.h" -typedef enum { - MONO_OPTION_BOOL, - MONO_OPTION_BOOL_READONLY, - MONO_OPTION_INT, - MONO_OPTION_STRING -} MonoOptionType; - /* Define flags */ #define DEFINE_OPTION_FULL(option_type, ctype, c_name, cmd_name, def_value, comment) \ ctype mono_opt_##c_name = def_value; @@ -333,3 +326,22 @@ mono_options_get_as_json (void) g_string_free(result, FALSE); return result_str; } + +gboolean +mono_options_get (const char *name, MonoOptionType *type, void **value_address) +{ + GHashTable *hash = get_option_hash (); + OptionData *meta = (OptionData *)g_hash_table_lookup (hash, name); + + if (!meta) { + if (value_address) + *value_address = NULL; + return FALSE; + } + + if (type) + *type = meta->option_type; + if (value_address) + *value_address = meta->addr; + return TRUE; +} diff --git a/src/mono/mono/utils/options.h b/src/mono/mono/utils/options.h index e7f2906eeb052..27667e114af10 100644 --- a/src/mono/mono/utils/options.h +++ b/src/mono/mono/utils/options.h @@ -22,6 +22,13 @@ MONO_BEGIN_DECLS #include "options-def.h" MONO_END_DECLS +typedef enum { + MONO_OPTION_BOOL, + MONO_OPTION_BOOL_READONLY, + MONO_OPTION_INT, + MONO_OPTION_STRING +} MonoOptionType; + extern int mono_options_version; void mono_options_print_usage (void); @@ -31,4 +38,7 @@ void mono_options_parse_options (const char **args, int argc, int *out_argc, GPt /* returns a json blob representing the current values of all options */ char * mono_options_get_as_json (void); +gboolean +mono_options_get (const char *name, MonoOptionType *type, void **value_address); + #endif