Skip to content

Commit

Permalink
[wasm] Optimize jiterpreter option table updates (#101207)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kg authored Apr 18, 2024
1 parent 65f6a08 commit 6d3a31c
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 16 deletions.
2 changes: 2 additions & 0 deletions src/mono/browser/runtime/cwraps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"]],
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 5 additions & 8 deletions src/mono/browser/runtime/jiterpreter-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -2015,15 +2014,13 @@ export function getOptions () {
}

function updateOptions () {
const pJson = cwraps.mono_jiterp_get_options_as_json();
const json = utf8ToString(<any>pJson);
Module._free(<any>pJson);
const blob = JSON.parse(json);

optionTable = <any>{};
for (const k in optionNames) {
const info = optionNames[k];
(<any>optionTable)[k] = blob[info];
const value = cwraps.mono_jiterp_get_option_as_int(optionNames[k]);
if (value > -2147483647)
(<any>optionTable)[k] = value;
else
mono_log_info(`Failed to retrieve value of option ${optionNames[k]}`);
}
}

Expand Down
22 changes: 21 additions & 1 deletion src/mono/mono/mini/interp/jiterpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 19 additions & 7 deletions src/mono/mono/utils/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
10 changes: 10 additions & 0 deletions src/mono/mono/utils/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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

0 comments on commit 6d3a31c

Please sign in to comment.