mono_internal_hash_table_apply (&jit_mm->interp_code_hash, invalidate_transform, NULL);
jit_mm_unlock (jit_mm);
}
-
+
g_ptr_array_free (alcs, TRUE);
}
g_free (copy_jit_info_data.jit_info_array);
}
}
-
+
g_ptr_array_free (alcs, TRUE);
}
}
#endif
}
+#define JITERP_OPINFO_TYPE_NAME 0
+#define JITERP_OPINFO_TYPE_LENGTH 1
+#define JITERP_OPINFO_TYPE_SREGS 2
+#define JITERP_OPINFO_TYPE_DREGS 3
+#define JITERP_OPINFO_TYPE_OPARGTYPE 4
+
+EMSCRIPTEN_KEEPALIVE int
+mono_jiterp_get_opcode_info (int opcode, int type)
+{
+ g_assert ((opcode >= 0) && (opcode <= MINT_LASTOP));
+ switch (type) {
+ case JITERP_OPINFO_TYPE_NAME:
+ // We know this conversion is safe because wasm pointers are 32 bits
+ return (int)(void*)(mono_interp_opname (opcode));
+ case JITERP_OPINFO_TYPE_LENGTH:
+ return mono_interp_oplen [opcode];
+ case JITERP_OPINFO_TYPE_SREGS:
+ return mono_interp_op_sregs [opcode];
+ case JITERP_OPINFO_TYPE_DREGS:
+ return mono_interp_op_dregs [opcode];
+ case JITERP_OPINFO_TYPE_OPARGTYPE:
+ return mono_interp_opargtype [opcode];
+ default:
+ g_assert_not_reached();
+ }
+}
+
#endif
[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"]],
+ [true, "mono_jiterp_get_opcode_info", "number", ["number", "number"]],
...legacy_interop_cwraps
];
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;
+ mono_jiterp_get_opcode_info(opcode: number, type: number): number;
}
const wrapped_c_functions: t_Cwraps = <any>{};
getU16, getI16,
getU32_unaligned, getI32_unaligned, getF32_unaligned, getF64_unaligned,
} from "./memory";
-import { WasmOpcode, WasmSimdOpcode } from "./jiterpreter-opcodes";
import {
- MintOpcode, OpcodeInfo, SimdInfo,
+ WasmOpcode, WasmSimdOpcode,
+ getOpcodeName, OpcodeInfoType
+} from "./jiterpreter-opcodes";
+import {
+ MintOpcode, SimdInfo,
SimdIntrinsic2, SimdIntrinsic3, SimdIntrinsic4
} from "./mintops";
import cwraps from "./cwraps";
eraseInferredState();
// Skip over the enter opcode
- ip += <any>(OpcodeInfo[MintOpcode.MINT_TIER_ENTER_JITERPRETER][1] * 2);
+ const enterSizeU16 = cwraps.mono_jiterp_get_opcode_info(MintOpcode.MINT_TIER_ENTER_JITERPRETER, OpcodeInfoType.Length);
+ ip += <any>(enterSizeU16 * 2);
let rip = ip;
builder.cfg.entry(ip);
}
let opcode = getU16(ip);
- const info = OpcodeInfo[opcode];
+ const numSregs = cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Sregs),
+ numDregs = cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Dregs),
+ opLengthU16 = cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Length);
+
const isSimdIntrins = (opcode >= MintOpcode.MINT_SIMD_INTRINS_P_P) &&
(opcode <= MintOpcode.MINT_SIMD_INTRINS_P_PPP);
const simdIntrinsArgCount = isSimdIntrins
? getArgU16(ip, 1 + simdIntrinsArgCount)
: 0;
- mono_assert(info, () => `invalid opcode ${opcode}`);
+ mono_assert((opcode >= 0) && (opcode < MintOpcode.MINT_LASTOP), () => `invalid opcode ${opcode}`);
const opname = isSimdIntrins
? SimdInfo[simdIntrinsArgCount][simdIntrinsIndex]
- : info[0];
+ : getOpcodeName(opcode);
const _ip = ip;
const isBackBranchTarget = builder.options.noExitBackwardBranches &&
is_backward_branch_target(ip, startOfBody, backwardBranchTable),
// This should have already happened, but it's possible there are opcodes where
// our invalidation is incorrect so it's best to do this for safety reasons
const firstDreg = <any>ip + 2;
- for (let r = 0; r < info[2]; r++) {
+ for (let r = 0; r < numDregs; r++) {
const dreg = getU16(firstDreg + (r * 2));
invalidate_local(dreg);
}
if ((trace > 1) || traceOnError || traceOnRuntimeError || mostRecentOptions!.dumpTraces || instrumentedTraceId) {
let stmtText = `${(<any>ip).toString(16)} ${opname} `;
const firstDreg = <any>ip + 2;
- const firstSreg = firstDreg + (info[2] * 2);
+ const firstSreg = firstDreg + (numDregs * 2);
// print sregs
- for (let r = 0; r < info[3]; r++) {
+ for (let r = 0; r < numSregs; r++) {
if (r !== 0)
stmtText += ", ";
stmtText += getU16(firstSreg + (r * 2));
}
// print dregs
- if (info[2] > 0)
+ if (numDregs > 0)
stmtText += " -> ";
- for (let r = 0; r < info[2]; r++) {
+ for (let r = 0; r < numDregs; r++) {
if (r !== 0)
stmtText += ", ";
stmtText += getU16(firstDreg + (r * 2));
// console.log(`JITERP: opcode ${opname} did not abort but had value ${opcodeValue}`);
}
- ip += <any>(info[1] * 2);
+ ip += <any>(opLengthU16 * 2);
if (<any>ip <= (<any>endOfBody))
rip = ip;
// For debugging
builder: WasmBuilder, ip: MintOpcodePtr,
frame: NativePointer, opcode: MintOpcode, displacement?: number
) : boolean {
- const info = OpcodeInfo[opcode];
const isSafepoint = (opcode >= MintOpcode.MINT_BRFALSE_I4_SP) &&
(opcode <= MintOpcode.MINT_BLT_UN_I8_IMM_SP);
eraseInferredState();
} else {
if (destination < builder.cfg.entryIp) {
if ((traceBackBranches > 1) || (builder.cfg.trace > 1))
- console.log(`${info[0]} target 0x${destination.toString(16)} before start of trace`);
+ console.log(`${getOpcodeName(opcode)} target 0x${destination.toString(16)} before start of trace`);
} else if ((traceBackBranches > 0) || (builder.cfg.trace > 0))
- console.log(`0x${(<any>ip).toString(16)} ${info[0]} target 0x${destination.toString(16)} not found in list ` +
+ console.log(`0x${(<any>ip).toString(16)} ${getOpcodeName(opcode)} target 0x${destination.toString(16)} not found in list ` +
builder.backBranchOffsets.map(bbo => "0x" + (<any>bbo).toString(16)).join(", ")
);
// so we don't need to load anything. After the condition was loaded, we
// treat it like a brtrue
if (relopbranchTable[opcode] === undefined)
- throw new Error(`Unsupported relop branch opcode: ${opcode}`);
+ throw new Error(`Unsupported relop branch opcode: ${getOpcodeName(opcode)}`);
- if (info[1] !== 4)
- throw new Error(`Unsupported long branch opcode: ${info[0]}`);
+ if (cwraps.mono_jiterp_get_opcode_info(opcode, OpcodeInfoType.Length) !== 4)
+ throw new Error(`Unsupported long branch opcode: ${getOpcodeName(opcode)}`);
builder.appendU8(WasmOpcode.i32_eqz);
break;
if (!displacement)
throw new Error("Branch had no displacement");
else if (traceBranchDisplacements)
- console.log(`${info[0]} @${ip} displacement=${displacement}`);
+ console.log(`${getOpcodeName(opcode)} @${ip} displacement=${displacement}`);
const destination = <any>ip + (displacement * 2);
} else {
if (destination < builder.cfg.entryIp) {
if ((traceBackBranches > 1) || (builder.cfg.trace > 1))
- console.log(`${info[0]} target 0x${destination.toString(16)} before start of trace`);
+ console.log(`${getOpcodeName(opcode)} target 0x${destination.toString(16)} before start of trace`);
} else if ((traceBackBranches > 0) || (builder.cfg.trace > 0))
- console.log(`0x${(<any>ip).toString(16)} ${info[0]} target 0x${destination.toString(16)} not found in list ` +
+ console.log(`0x${(<any>ip).toString(16)} ${getOpcodeName(opcode)} target 0x${destination.toString(16)} not found in list ` +
builder.backBranchOffsets.map(bbo => "0x" + (<any>bbo).toString(16)).join(", ")
);
// We didn't find a loop to branch to, so bail out
import {
getU16, getU32_unaligned
} from "./memory";
-import { WasmOpcode } from "./jiterpreter-opcodes";
-import { MintOpcode, OpcodeInfo } from "./mintops";
+import { WasmOpcode, getOpcodeName } from "./jiterpreter-opcodes";
+import { MintOpcode } from "./mintops";
import cwraps from "./cwraps";
import {
MintOpcodePtr, WasmValtype, WasmBuilder, addWasmFunctionPointer,
export function record_abort(traceIp: MintOpcodePtr, ip: MintOpcodePtr, traceName: string, reason: string | MintOpcode) {
if (typeof (reason) === "number") {
cwraps.mono_jiterp_adjust_abort_count(reason, 1);
- reason = OpcodeInfo[<any>reason][0];
+ reason = getOpcodeName(reason);
} else {
let abortCount = abortCounts[reason];
if (typeof (abortCount) !== "number")
console.log(`// ${tuples[i][0]}: ${tuples[i][1]}`);
} else {
for (let i = 0; i < MintOpcode.MINT_LASTOP; i++) {
- const opname = OpcodeInfo[<any>i][0];
+ const opname = getOpcodeName(i);
const count = cwraps.mono_jiterp_adjust_abort_count(i, 0);
if (count > 0)
abortCounts[opname] = count;