summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/jit/x86/instr_fun.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/jit/x86/instr_fun.cpp')
-rw-r--r--erts/emulator/beam/jit/x86/instr_fun.cpp56
1 files changed, 30 insertions, 26 deletions
diff --git a/erts/emulator/beam/jit/x86/instr_fun.cpp b/erts/emulator/beam/jit/x86/instr_fun.cpp
index 1ae19aaaba..903ecef49b 100644
--- a/erts/emulator/beam/jit/x86/instr_fun.cpp
+++ b/erts/emulator/beam/jit/x86/instr_fun.cpp
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2021-2022. All Rights Reserved.
+ * Copyright Ericsson AB 2021-2023. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,14 +32,14 @@ void BeamGlobalAssembler::emit_unloaded_fun() {
a.mov(TMP_MEM1q, ARG5);
- emit_enter_runtime<Update::eHeap | Update::eStack | Update::eReductions>();
+ emit_enter_runtime<Update::eHeapAlloc | Update::eReductions>();
a.mov(ARG1, c_p);
load_x_reg_array(ARG2);
/* ARG3 and ARG4 have already been set. */
runtime_call<4>(beam_jit_handle_unloaded_fun);
- emit_leave_runtime<Update::eHeap | Update::eStack | Update::eReductions |
+ emit_leave_runtime<Update::eHeapAlloc | Update::eReductions |
Update::eCodeIndex>();
a.test(RET, RET);
@@ -93,14 +93,14 @@ void BeamGlobalAssembler::emit_handle_call_fun_error() {
a.mov(TMP_MEM1q, ARG4);
a.mov(TMP_MEM2q, ARG5);
- emit_enter_runtime<Update::eHeap | Update::eStack>();
+ emit_enter_runtime<Update::eHeapAlloc>();
a.mov(ARG1, c_p);
load_x_reg_array(ARG2);
/* ARG3 is already set. */
runtime_call<3>(beam_jit_build_argument_list);
- emit_leave_runtime<Update::eHeap | Update::eStack>();
+ emit_leave_runtime<Update::eHeapAlloc>();
a.mov(ARG1, TMP_MEM1q);
a.mov(getXRef(0), ARG1);
@@ -143,6 +143,19 @@ void BeamGlobalAssembler::emit_handle_call_fun_error() {
}
}
+/* Handles save_calls for local funs, which is a side-effect of our calling
+ * convention. Fun entry is in RET.
+ *
+ * When the active code index is ERTS_SAVE_CALLS_CODE_IX, all local fun calls
+ * will land here. */
+void BeamGlobalAssembler::emit_dispatch_save_calls_fun() {
+ /* Keep going with the actual code index. */
+ a.mov(ARG1, imm(&the_active_code_index));
+ a.mov(ARG1d, x86::dword_ptr(ARG1));
+
+ a.jmp(emit_setup_dispatchable_call(RET, ARG1));
+}
+
/* `call_fun` instructions land here to set up their environment before jumping
* to the actual implementation.
*
@@ -156,26 +169,17 @@ void BeamModuleAssembler::emit_i_lambda_trampoline(const ArgLambda &Lambda,
const ArgWord &NumFree) {
const ssize_t effective_arity = Arity.get() - NumFree.get();
const ssize_t num_free = NumFree.get();
- ssize_t i;
const auto &lambda = lambdas[Lambda.get()];
a.bind(lambda.trampoline);
emit_ptr_val(ARG4, ARG4);
- for (i = 0; i < num_free - 1; i += 2) {
- size_t offset = offsetof(ErlFunThing, env) + i * sizeof(Eterm);
-
- a.movups(x86::xmm0, emit_boxed_val(ARG4, offset, sizeof(Eterm[2])));
- a.movups(getXRef(i + effective_arity, sizeof(Eterm[2])), x86::xmm0);
- }
-
- if (i < num_free) {
- size_t offset = offsetof(ErlFunThing, env) + i * sizeof(Eterm);
-
- a.mov(RET, emit_boxed_val(ARG4, offset));
- a.mov(getXRef(i + effective_arity), RET);
- }
+ ASSERT(num_free > 0);
+ emit_copy_words(emit_boxed_val(ARG4, offsetof(ErlFunThing, env)),
+ getXRef(effective_arity),
+ num_free,
+ RET);
a.jmp(resolve_beam_label(Lbl));
}
@@ -193,12 +197,12 @@ void BeamModuleAssembler::emit_i_make_fun3(const ArgLambda &Lambda,
mov_arg(ARG3, Arity);
mov_arg(ARG4, NumFree);
- emit_enter_runtime<Update::eHeap>();
+ emit_enter_runtime<Update::eHeapOnlyAlloc>();
a.mov(ARG1, c_p);
runtime_call<4>(erts_new_local_fun_thing);
- emit_leave_runtime<Update::eHeap>();
+ emit_leave_runtime<Update::eHeapOnlyAlloc>();
comment("Move fun environment");
for (unsigned i = 0; i < num_free; i++) {
@@ -242,7 +246,7 @@ void BeamGlobalAssembler::emit_apply_fun_shared() {
a.cmp(ARG1d, imm(NIL));
a.short_().je(finished);
- a.test(ARG1d, imm(_TAG_PRIMARY_MASK - TAG_PRIMARY_LIST));
+ a.test(ARG1.r8(), imm(_TAG_PRIMARY_MASK - TAG_PRIMARY_LIST));
a.short_().jne(malformed_list);
emit_ptr_val(ARG1, ARG1);
@@ -376,8 +380,8 @@ void BeamModuleAssembler::emit_i_call_fun2(const ArgVal &Tag,
mov_imm(ARG3, Arity.get());
auto target = emit_call_fun(
- always_one_of(Func, BEAM_TYPE_MASK_ALWAYS_BOXED),
- masked_types(Func, BEAM_TYPE_MASK_BOXED) == BEAM_TYPE_FUN,
+ always_one_of<BeamTypeId::AlwaysBoxed>(Func),
+ masked_types<BeamTypeId::MaybeBoxed>(Func) == BeamTypeId::Fun,
Tag.as<ArgImmed>().get() == am_safe);
erlang_call(target, ARG6);
@@ -397,8 +401,8 @@ void BeamModuleAssembler::emit_i_call_fun2_last(const ArgVal &Tag,
mov_imm(ARG3, Arity.get());
auto target = emit_call_fun(
- always_one_of(Func, BEAM_TYPE_MASK_ALWAYS_BOXED),
- masked_types(Func, BEAM_TYPE_MASK_BOXED) == BEAM_TYPE_FUN,
+ always_one_of<BeamTypeId::AlwaysBoxed>(Func),
+ masked_types<BeamTypeId::MaybeBoxed>(Func) == BeamTypeId::Fun,
Tag.as<ArgImmed>().get() == am_safe);
emit_deallocate(Deallocate);