From b00b2d70155d39d0b421b095b1ea5fb6ef79af69 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Mon, 17 Apr 2023 14:33:17 -0400 Subject: [PATCH 1/3] Add interpreter transition event In debug(opt) mode, register a bpftrace event that fires when the assembly interpreter switches to the C++ interpreter. This also includes opcodes that have no assembly implementation (and therefore always switch to C++). --- runtime/interpreter-gen-x64.cpp | 8 ++++++++ util/probes/asm2cpp.bt | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 util/probes/asm2cpp.bt diff --git a/runtime/interpreter-gen-x64.cpp b/runtime/interpreter-gen-x64.cpp index d6f925708..7ebe66b29 100644 --- a/runtime/interpreter-gen-x64.cpp +++ b/runtime/interpreter-gen-x64.cpp @@ -118,7 +118,15 @@ const word kHandlerSizeShift = 8; const word kHandlerSize = 1 << kHandlerSizeShift; const Interpreter::OpcodeHandler kCppHandlers[] = { +#if DCHECK_IS_ON() +#define OP(name, id, handler) \ + [](Thread* thread, word arg) { \ + EVENT(InterpreterDeopt_##name); \ + return Interpreter::handler(thread, arg); \ + }, +#else #define OP(name, id, handler) Interpreter::handler, +#endif FOREACH_BYTECODE(OP) #undef OP }; diff --git a/util/probes/asm2cpp.bt b/util/probes/asm2cpp.bt new file mode 100644 index 000000000..a5aad1a12 --- /dev/null +++ b/util/probes/asm2cpp.bt @@ -0,0 +1,4 @@ +usdt:./build/bin/python:python:InterpreterDeopt_* { + @interpreter_deopt[probe]++; +} + From b010b3bd2e97bfb7f83de4f6647bb5ab96132f94 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Mon, 17 Apr 2023 14:53:37 -0400 Subject: [PATCH 2/3] Add asm interpreter implementation of LOAD_ATTR_INSTANCE_SLOT_DESCR For richards.py this occurs 25330 times, according to the bpftrace script. It is not the hottest, but it is easy to implement. (smaller) ... @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_COMPARE_IN_MONOMORPHIC]: 14073 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_COMPARE_EQ_STR]: 17581 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_LOAD_ATTR_INSTANCE_TYPE]: 19845 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_LOAD_ATTR_INSTANCE_SLOT_DESCR]: 25330 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_BUILD_TUPLE]: 27540 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_GET_ITER]: 44881 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_INPLACE_OP_MONOMORPHIC]: 56030 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_BINARY_FLOORDIV_SMALLINT]: 57701 @interpreter_deopt[usdt:./build/bin/python:python:InterpreterDeopt_BINARY_OP_MONOMORPHIC]: 58618 (higher) --- runtime/interpreter-gen-x64.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/runtime/interpreter-gen-x64.cpp b/runtime/interpreter-gen-x64.cpp index 7ebe66b29..a45497eb4 100644 --- a/runtime/interpreter-gen-x64.cpp +++ b/runtime/interpreter-gen-x64.cpp @@ -1227,6 +1227,35 @@ void emitHandler(EmitEnv* env) { emitJumpToGenericHandler(env); } +template <> +void emitHandler(EmitEnv* env) { + ScratchReg r_base(env); + ScratchReg r_layout_id(env); + ScratchReg r_offset(env); + ScratchReg r_caches(env); + ScratchReg r_result(env); + Label slow_path; + __ popq(r_base); + emitGetLayoutId(env, r_layout_id, r_base); + __ movq(r_caches, Address(env->frame, Frame::kCachesOffset)); + emitIcLookupMonomorphic(env, &slow_path, r_offset, r_layout_id, r_caches); + + emitConvertFromSmallInt(env, r_offset); + __ movq(r_result, Address(r_base, r_offset, TIMES_1, heapObjectDisp(0))); + __ cmpl(r_result, Immediate(Unbound::object().raw())); + __ jcc(EQUAL, &slow_path, Assembler::kNearJump); + __ pushq(r_result); + emitNextOpcode(env); + + __ bind(&slow_path); + __ pushq(r_base); + if (env->in_jit) { + emitJumpToDeopt(env); + return; + } + emitJumpToGenericHandler(env); +} + template <> void emitHandler(EmitEnv* env) { ScratchReg r_base(env); From 4b916d303f3d31810806bd478544a99a94d7b0af Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Mon, 17 Apr 2023 15:23:17 -0400 Subject: [PATCH 3/3] Add asm interpreter implementation of LOAD_ATTR_INSTANCE_TYPE This brings it down from 19727 to 4101 transitions from asm to C++. --- runtime/interpreter-gen-x64.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/runtime/interpreter-gen-x64.cpp b/runtime/interpreter-gen-x64.cpp index a45497eb4..2bfc329d5 100644 --- a/runtime/interpreter-gen-x64.cpp +++ b/runtime/interpreter-gen-x64.cpp @@ -1256,6 +1256,29 @@ void emitHandler(EmitEnv* env) { emitJumpToGenericHandler(env); } +template <> +void emitHandler(EmitEnv* env) { + ScratchReg r_base(env); + ScratchReg r_layout_id(env); + ScratchReg r_cached(env); + ScratchReg r_caches(env); + Label slow_path; + __ popq(r_base); + emitGetLayoutId(env, r_layout_id, r_base); + __ movq(r_caches, Address(env->frame, Frame::kCachesOffset)); + emitIcLookupMonomorphic(env, &slow_path, r_cached, r_layout_id, r_caches); + __ pushq(r_cached); + emitNextOpcode(env); + + __ bind(&slow_path); + __ pushq(r_base); + if (env->in_jit) { + emitJumpToDeopt(env); + return; + } + emitJumpToGenericHandler(env); +} + template <> void emitHandler(EmitEnv* env) { ScratchReg r_base(env);