Skip to content

Commit 6d3a31c

Browse files
authored
[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.
1 parent 65f6a08 commit 6d3a31c

File tree

5 files changed

+57
-16
lines changed

5 files changed

+57
-16
lines changed

src/mono/browser/runtime/cwraps.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const fn_signatures: SigLine[] = [
9999
[true, "mono_jiterp_get_size_of_stackval", "number", []],
100100
[true, "mono_jiterp_parse_option", "number", ["string"]],
101101
[true, "mono_jiterp_get_options_as_json", "number", []],
102+
[true, "mono_jiterp_get_option_as_int", "number", ["string"]],
102103
[true, "mono_jiterp_get_options_version", "number", []],
103104
[true, "mono_jiterp_adjust_abort_count", "number", ["number", "number"]],
104105
[true, "mono_jiterp_register_jit_call_thunk", "void", ["number", "number"]],
@@ -228,6 +229,7 @@ export interface t_Cwraps {
228229
mono_jiterp_type_get_raw_value_size(type: MonoType): number;
229230
mono_jiterp_parse_option(name: string): number;
230231
mono_jiterp_get_options_as_json(): number;
232+
mono_jiterp_get_option_as_int(name: string): number;
231233
mono_jiterp_get_options_version(): number;
232234
mono_jiterp_adjust_abort_count(opcode: number, delta: number): number;
233235
mono_jiterp_register_jit_call_thunk(cinfo: number, func: number): void;

src/mono/browser/runtime/jiterpreter-support.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { MintOpcode } from "./mintops";
99
import cwraps from "./cwraps";
1010
import { mono_log_error, mono_log_info } from "./logging";
1111
import { localHeapViewU8, localHeapViewU32 } from "./memory";
12-
import { utf8ToString } from "./strings";
1312
import {
1413
JiterpNumberMode, BailoutReason, JiterpreterTable,
1514
JiterpCounter, JiterpMember, OpcodeInfoType
@@ -2015,15 +2014,13 @@ export function getOptions () {
20152014
}
20162015

20172016
function updateOptions () {
2018-
const pJson = cwraps.mono_jiterp_get_options_as_json();
2019-
const json = utf8ToString(<any>pJson);
2020-
Module._free(<any>pJson);
2021-
const blob = JSON.parse(json);
2022-
20232017
optionTable = <any>{};
20242018
for (const k in optionNames) {
2025-
const info = optionNames[k];
2026-
(<any>optionTable)[k] = blob[info];
2019+
const value = cwraps.mono_jiterp_get_option_as_int(optionNames[k]);
2020+
if (value > -2147483647)
2021+
(<any>optionTable)[k] = value;
2022+
else
2023+
mono_log_info(`Failed to retrieve value of option ${optionNames[k]}`);
20272024
}
20282025
}
20292026

src/mono/mono/mini/interp/jiterpreter.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1021,8 +1021,28 @@ mono_jiterp_get_options_as_json ()
10211021
return mono_options_get_as_json ();
10221022
}
10231023

1024+
EMSCRIPTEN_KEEPALIVE gint32
1025+
mono_jiterp_get_option_as_int (const char *name)
1026+
{
1027+
MonoOptionType type;
1028+
void *value_address;
1029+
1030+
if (!mono_options_get (name, &type, &value_address))
1031+
return INT32_MIN;
1032+
1033+
switch (type) {
1034+
case MONO_OPTION_BOOL:
1035+
case MONO_OPTION_BOOL_READONLY:
1036+
return (*(guint8 *)value_address) != 0;
1037+
case MONO_OPTION_INT:
1038+
return *(gint32 *)value_address;
1039+
default:
1040+
return INT32_MIN;
1041+
}
1042+
}
1043+
10241044
EMSCRIPTEN_KEEPALIVE int
1025-
mono_jiterp_object_has_component_size (MonoObject ** ppObj)
1045+
mono_jiterp_object_has_component_size (MonoObject **ppObj)
10261046
{
10271047
MonoObject *obj = *ppObj;
10281048
if (!obj)

src/mono/mono/utils/options.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
#include "options.h"
1111
#include "mono/utils/mono-error-internals.h"
1212

13-
typedef enum {
14-
MONO_OPTION_BOOL,
15-
MONO_OPTION_BOOL_READONLY,
16-
MONO_OPTION_INT,
17-
MONO_OPTION_STRING
18-
} MonoOptionType;
19-
2013
/* Define flags */
2114
#define DEFINE_OPTION_FULL(option_type, ctype, c_name, cmd_name, def_value, comment) \
2215
ctype mono_opt_##c_name = def_value;
@@ -333,3 +326,22 @@ mono_options_get_as_json (void)
333326
g_string_free(result, FALSE);
334327
return result_str;
335328
}
329+
330+
gboolean
331+
mono_options_get (const char *name, MonoOptionType *type, void **value_address)
332+
{
333+
GHashTable *hash = get_option_hash ();
334+
OptionData *meta = (OptionData *)g_hash_table_lookup (hash, name);
335+
336+
if (!meta) {
337+
if (value_address)
338+
*value_address = NULL;
339+
return FALSE;
340+
}
341+
342+
if (type)
343+
*type = meta->option_type;
344+
if (value_address)
345+
*value_address = meta->addr;
346+
return TRUE;
347+
}

src/mono/mono/utils/options.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ MONO_BEGIN_DECLS
2222
#include "options-def.h"
2323
MONO_END_DECLS
2424

25+
typedef enum {
26+
MONO_OPTION_BOOL,
27+
MONO_OPTION_BOOL_READONLY,
28+
MONO_OPTION_INT,
29+
MONO_OPTION_STRING
30+
} MonoOptionType;
31+
2532
extern int mono_options_version;
2633

2734
void mono_options_print_usage (void);
@@ -31,4 +38,7 @@ void mono_options_parse_options (const char **args, int argc, int *out_argc, GPt
3138
/* returns a json blob representing the current values of all options */
3239
char * mono_options_get_as_json (void);
3340

41+
gboolean
42+
mono_options_get (const char *name, MonoOptionType *type, void **value_address);
43+
3444
#endif

0 commit comments

Comments
 (0)