Skip to content

Commit

Permalink
Update jiterpreter interp_entry wrapper generator and re-enable jiterp
Browse files Browse the repository at this point in the history
  • Loading branch information
kg authored and BrzVlad committed May 8, 2023
1 parent 617cc22 commit 23e4de7
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 42 deletions.
7 changes: 5 additions & 2 deletions src/mono/mono/mini/interp/interp-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,15 @@ mono_jiterp_overflow_check_u4 (guint32 lhs, guint32 rhs, int opcode);
void
mono_jiterp_ld_delegate_method_ptr (gpointer *destination, MonoDelegate **source);

int
void
mono_jiterp_stackval_to_data (MonoType *type, stackval *val, void *data);

int
void
mono_jiterp_stackval_from_data (MonoType *type, stackval *result, const void *data);

int
mono_jiterp_get_arg_offset (InterpMethod *imethod, MonoMethodSignature *sig, int index);

gpointer
mono_jiterp_frame_data_allocator_alloc (FrameDataAllocator *stack, InterpFrame *frame, int size);

Expand Down
26 changes: 16 additions & 10 deletions src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -8687,18 +8687,22 @@ mono_ee_interp_init (const char *opts)
}

#ifdef HOST_BROWSER
EMSCRIPTEN_KEEPALIVE int
EMSCRIPTEN_KEEPALIVE void
mono_jiterp_stackval_to_data (MonoType *type, stackval *val, void *data)
{
g_error ("FIXME");
return 0; //stackval_to_data (type, val, data, FALSE);
stackval_to_data (type, val, data, FALSE);
}

EMSCRIPTEN_KEEPALIVE int
EMSCRIPTEN_KEEPALIVE void
mono_jiterp_stackval_from_data (MonoType *type, stackval *result, const void *data)
{
g_error ("FIXME");
return 0; //stackval_from_data (type, result, data, FALSE);
stackval_from_data (type, result, data, FALSE);
}

EMSCRIPTEN_KEEPALIVE int
mono_jiterp_get_arg_offset (InterpMethod *imethod, MonoMethodSignature *sig, int index)
{
return get_arg_offset_fast (imethod, sig, index);
}

EMSCRIPTEN_KEEPALIVE int
Expand Down Expand Up @@ -8778,7 +8782,7 @@ mono_jiterp_isinst (MonoObject* object, MonoClass* klass)
// in the correct place and compute the stack offset, then it passes that in to this
// function in order to actually enter the interpreter and process the return value
EMSCRIPTEN_KEEPALIVE void
mono_jiterp_interp_entry (JiterpEntryData *_data, stackval *sp_args, void *res)
mono_jiterp_interp_entry (JiterpEntryData *_data, void *res)
{
JiterpEntryDataHeader header;
MonoType *type;
Expand All @@ -8791,7 +8795,6 @@ mono_jiterp_interp_entry (JiterpEntryData *_data, stackval *sp_args, void *res)

g_assert(header.rmethod);
g_assert(header.rmethod->method);
g_assert(sp_args);

stackval *sp = (stackval*)header.context->stack_pointer;

Expand All @@ -8800,8 +8803,11 @@ mono_jiterp_interp_entry (JiterpEntryData *_data, stackval *sp_args, void *res)
frame.stack = sp;
frame.retval = sp;

header.context->stack_pointer = (guchar*)sp_args;
g_assert ((guchar*)sp_args < header.context->stack_end);
int params_size = get_arg_offset_fast (header.rmethod, NULL, header.params_count);
// g_printf ("jiterp_interp_entry: rmethod=%d, params_count=%d, params_size=%d\n", header.rmethod, header.params_count, params_size);
header.context->stack_pointer = (guchar*)ALIGN_TO ((guchar*)sp + params_size, MINT_STACK_ALIGNMENT);
;
g_assert (header.context->stack_pointer < header.context->stack_end);

MONO_ENTER_GC_UNSAFE;
mono_interp_exec_method (&frame, header.context, NULL);
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/mini/interp/jiterpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ mono_jiterp_trace_transfer (
#define JITERP_MEMBER_BACKWARD_BRANCH_OFFSETS 10
#define JITERP_MEMBER_BACKWARD_BRANCH_OFFSETS_COUNT 11
#define JITERP_MEMBER_CLAUSE_DATA_OFFSETS 12
#define JITERP_MEMBER_PARAMS_COUNT 13

// we use these helpers at JIT time to figure out where to do memory loads and stores
EMSCRIPTEN_KEEPALIVE size_t
Expand Down Expand Up @@ -1196,6 +1197,8 @@ mono_jiterp_get_member_offset (int member) {
return offsetof (InterpMethod, clause_data_offsets);
case JITERP_MEMBER_RMETHOD:
return offsetof (JiterpEntryDataHeader, rmethod);
case JITERP_MEMBER_PARAMS_COUNT:
return offsetof (JiterpEntryDataHeader, params_count);
case JITERP_MEMBER_SPAN_LENGTH:
return offsetof (MonoSpanOfVoid, _length);
case JITERP_MEMBER_SPAN_DATA:
Expand Down
3 changes: 2 additions & 1 deletion src/mono/mono/mini/interp/jiterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ typedef struct {
ThreadContext *context;
gpointer orig_domain;
gpointer attach_cookie;
int params_count;
} JiterpEntryDataHeader;

// we optimize delegate calls by attempting to cache the delegate invoke
Expand Down Expand Up @@ -136,7 +137,7 @@ void
mono_jiterp_do_safepoint (InterpFrame *frame, guint16 *ip);

void
mono_jiterp_interp_entry (JiterpEntryData *_data, stackval *sp_args, void *res);
mono_jiterp_interp_entry (JiterpEntryData *_data, void *res);

gpointer
mono_jiterp_imethod_to_ftnptr (InterpMethod *imethod);
Expand Down
14 changes: 7 additions & 7 deletions src/mono/mono/utils/options-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ DEFINE_BOOL(interp_simd_packedsimd, "interp-simd-packedsimd", FALSE, "Enable int
// and wasm modules between threads. before these can be enabled we need to implement all that
#ifdef DISABLE_THREADS
// traces_enabled controls whether the jiterpreter will JIT individual interpreter opcode traces
DEFINE_BOOL(jiterpreter_traces_enabled, "jiterpreter-traces-enabled", FALSE, "JIT interpreter opcode traces into WASM")
DEFINE_BOOL(jiterpreter_traces_enabled, "jiterpreter-traces-enabled", TRUE, "JIT interpreter opcode traces into WASM")
// interp_entry_enabled controls whether specialized interp_entry wrappers will be jitted
DEFINE_BOOL(jiterpreter_interp_entry_enabled, "jiterpreter-interp-entry-enabled", FALSE, "JIT specialized WASM interp_entry wrappers")
DEFINE_BOOL(jiterpreter_interp_entry_enabled, "jiterpreter-interp-entry-enabled", TRUE, "JIT specialized WASM interp_entry wrappers")
// jit_call_enabled controls whether do_jit_call will use specialized trampolines for hot call sites
DEFINE_BOOL(jiterpreter_jit_call_enabled, "jiterpreter-jit-call-enabled", FALSE, "JIT specialized WASM do_jit_call trampolines")
DEFINE_BOOL(jiterpreter_jit_call_enabled, "jiterpreter-jit-call-enabled", TRUE, "JIT specialized WASM do_jit_call trampolines")
#else
// traces_enabled controls whether the jiterpreter will JIT individual interpreter opcode traces
DEFINE_BOOL_READONLY(jiterpreter_traces_enabled, "jiterpreter-traces-enabled", FALSE, "JIT interpreter opcode traces into WASM")
Expand All @@ -101,7 +101,7 @@ DEFINE_BOOL(jiterpreter_call_resume_enabled, "jiterpreter-call-resume-enabled",
// stats for options like estimateHeat, but raises overhead.
DEFINE_BOOL(jiterpreter_disable_heuristic, "jiterpreter-disable-heuristic", FALSE, "Always insert trace entry points for more accurate statistics")
// Automatically prints stats at app exit or when jiterpreter_dump_stats is called
DEFINE_BOOL(jiterpreter_stats_enabled, "jiterpreter-stats-enabled", FALSE, "Automatically print jiterpreter statistics")
DEFINE_BOOL(jiterpreter_stats_enabled, "jiterpreter-stats-enabled", TRUE, "Automatically print jiterpreter statistics")
// Continue counting hits for traces that fail to compile and use it to estimate
// the relative importance of the opcode that caused them to abort
DEFINE_BOOL(jiterpreter_estimate_heat, "jiterpreter-estimate-heat", FALSE, "Maintain accurate hit count for all trace entry points")
Expand Down Expand Up @@ -145,12 +145,12 @@ DEFINE_INT(jiterpreter_jit_call_trampoline_hit_count, "jiterpreter-jit-call-hit-
// After a do_jit_call call site is hit this many times without being jitted, we will flush the JIT queue
DEFINE_INT(jiterpreter_jit_call_queue_flush_threshold, "jiterpreter-jit-call-queue-flush-threshold", 5000, "Flush the do_jit_call JIT queue after an unJITted call site has this many hits")
// After a generic interp_entry wrapper is hit this many times, we will queue it to be jitted
DEFINE_INT(jiterpreter_interp_entry_trampoline_hit_count, "jiterpreter-interp-entry-hit-count", 1000, "Queue specialized interp_entry wrapper for JIT after this many hits")
DEFINE_INT(jiterpreter_interp_entry_trampoline_hit_count, "jiterpreter-interp-entry-hit-count", 1, "Queue specialized interp_entry wrapper for JIT after this many hits")
// After a generic interp_entry wrapper is hit this many times without being jitted, we will flush the JIT queue
DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-entry-queue-flush-threshold", 3000, "Flush the interp_entry JIT queue after an unJITted call site has this many hits")
DEFINE_INT(jiterpreter_interp_entry_queue_flush_threshold, "jiterpreter-interp-entry-queue-flush-threshold", 300, "Flush the interp_entry JIT queue after an unJITted call site has this many hits")
// In degenerate cases the jiterpreter could end up generating lots of WASM, so shut off jitting once it reaches this limit
// Each wasm byte likely maps to multiple bytes of native code, so it's important for this limit not to be too high
DEFINE_INT(jiterpreter_wasm_bytes_limit, "jiterpreter-wasm-bytes-limit", 6 * 1024 * 1024, "Disable jiterpreter code generation once this many bytes of WASM have been generated")
DEFINE_INT(jiterpreter_wasm_bytes_limit, "jiterpreter-wasm-bytes-limit", 16 * 1024 * 1024, "Disable jiterpreter code generation once this many bytes of WASM have been generated")
#endif // HOST_BROWSER

#ifdef TARGET_WASM
Expand Down
2 changes: 2 additions & 0 deletions src/mono/wasm/runtime/cwraps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const fn_signatures: SigLine[] = [
[true, "mono_jiterp_get_opcode_value_table_entry", "number", ["number"]],
[true, "mono_jiterp_get_simd_intrinsic", "number", ["number", "number"]],
[true, "mono_jiterp_get_simd_opcode", "number", ["number", "number"]],
[true, "mono_jiterp_get_arg_offset", "number", ["number", "number", "number"]],
...legacy_interop_cwraps
];

Expand Down Expand Up @@ -250,6 +251,7 @@ export interface t_Cwraps {
mono_jiterp_get_opcode_value_table_entry(opcode: number): number;
mono_jiterp_get_simd_intrinsic(arity: number, index: number): VoidPtr;
mono_jiterp_get_simd_opcode(arity: number, index: number): number;
mono_jiterp_get_arg_offset (imethod: number, sig: number, index: number): number;
}

const wrapped_c_functions: t_Cwraps = <any>{};
Expand Down
42 changes: 20 additions & 22 deletions src/mono/wasm/runtime/jiterpreter-interp-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { mono_assert, MonoMethod, MonoType } from "./types";
import { NativePointer } from "./types/emscripten";
import { Module } from "./globals";
import {
getU32_unaligned, _zero_region
setI32, getU32_unaligned, _zero_region
} from "./memory";
import { WasmOpcode } from "./jiterpreter-opcodes";
import cwraps from "./cwraps";
Expand Down Expand Up @@ -36,6 +36,7 @@ typedef struct {
ThreadContext *context; // 4
gpointer orig_domain; // 8
gpointer attach_cookie; // 12
int params_count; // 16
} JiterpEntryDataHeader;
*/

Expand Down Expand Up @@ -231,7 +232,6 @@ function flush_wasm_entry_trampoline_jit_queue() {
"interp_entry",
{
"pData": WasmValtype.i32,
"sp_args": WasmValtype.i32,
"res": WasmValtype.i32,
},
WasmValtype.void, true
Expand All @@ -243,7 +243,7 @@ function flush_wasm_entry_trampoline_jit_queue() {
"result": WasmValtype.i32,
"value": WasmValtype.i32
},
WasmValtype.i32, true
WasmValtype.void, true
);
} else
builder.clear(constantSlots);
Expand Down Expand Up @@ -411,10 +411,10 @@ function flush_wasm_entry_trampoline_jit_queue() {
}

function append_stackval_from_data(
builder: WasmBuilder, type: MonoType, valueName: string
builder: WasmBuilder, imethod: number, type: MonoType, valueName: string, argIndex: number
) {
const stackvalSize = cwraps.mono_jiterp_get_size_of_stackval();
const rawSize = cwraps.mono_jiterp_type_get_raw_value_size(type);
const offset = cwraps.mono_jiterp_get_arg_offset(imethod, 0, argIndex);

switch (rawSize) {
case 256: {
Expand All @@ -423,10 +423,7 @@ function append_stackval_from_data(
builder.local(valueName);

builder.appendU8(WasmOpcode.i32_store);
builder.appendMemarg(0, 2);

// Fixed stackval size
builder.i32_const(stackvalSize);
builder.appendMemarg(offset, 2);
break;
}

Expand Down Expand Up @@ -465,30 +462,25 @@ function append_stackval_from_data(
}

builder.appendU8(WasmOpcode.i32_store);
builder.appendMemarg(0, 2);

// Fixed stackval size
builder.i32_const(stackvalSize);
builder.appendMemarg(offset, 2);
break;
}

default: {
// Call stackval_from_data to copy the value and get its size
// Call stackval_from_data to copy the value
builder.ptr_const(type);
// result
builder.local("sp_args");
// apply offset
builder.i32_const(offset);
builder.appendU8(WasmOpcode.i32_add);
// value
builder.local(valueName);

builder.callImport("stackval_from_data");
break;
}
}

// Value size is on the stack, add it to sp_args and update it
builder.local("sp_args");
builder.appendU8(WasmOpcode.i32_add);
builder.local("sp_args", WasmOpcode.set_local);
}

function generate_wasm_body(
Expand All @@ -505,6 +497,13 @@ function generate_wasm_body(
const scratchBuffer = <any>Module._malloc(sizeOfJiterpEntryData);
_zero_region(scratchBuffer, sizeOfJiterpEntryData);

// Initialize the parameter count in the data blob. This is used to calculate the new value of sp
// before entering the interpreter
setI32(
scratchBuffer + getMemberOffset(JiterpMember.ParamsCount),
info.paramTypes.length + (info.hasThisReference ? 1 : 0)
);

// the this-reference may be a boxed struct that needs to be unboxed, for example calling
// methods like object.ToString on structs will end up with the unbox flag set
// instead of passing an extra 'unbox' argument to every wrapper, though, the flag is hidden
Expand Down Expand Up @@ -559,7 +558,7 @@ function generate_wasm_body(

if (info.hasThisReference) {
// null type for raw ptr copy
append_stackval_from_data(builder, <any>0, "this_arg");
append_stackval_from_data(builder, info.imethod, <any>0, "this_arg", 0);
}

/*
Expand All @@ -576,11 +575,10 @@ function generate_wasm_body(

for (let i = 0; i < info.paramTypes.length; i++) {
const type = <any>info.paramTypes[i];
append_stackval_from_data(builder, type, `arg${i}`);
append_stackval_from_data(builder, info.imethod, type, `arg${i}`, i + (info.hasThisReference ? 1 : 0));
}

builder.local("scratchBuffer");
builder.local("sp_args");
if (info.hasReturnValue)
builder.local("res");
else
Expand Down
1 change: 1 addition & 0 deletions src/mono/wasm/runtime/jiterpreter-support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,7 @@ export const enum JiterpMember {
BackwardBranchOffsets = 10,
BackwardBranchOffsetsCount = 11,
ClauseDataOffsets = 12,
ParamsCount = 13,
}

const memberOffsets: { [index: number]: number } = {};
Expand Down

0 comments on commit 23e4de7

Please sign in to comment.