Skip to content

Commit

Permalink
Optimize creation of binary segments
Browse files Browse the repository at this point in the history
Slightly optimize creation of binary segments when it's known
that units are compatible.
  • Loading branch information
bjorng committed Jun 28, 2024
1 parent 2892d0d commit 67a8124
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
20 changes: 15 additions & 5 deletions erts/emulator/beam/jit/arm/instr_bs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2173,24 +2173,34 @@ void BeamModuleAssembler::emit_i_bs_create_bin(const ArgLabel &Fail,
seg.size.as<ArgAtom>().get() == am_all) {
/* Include the entire binary/bitstring in the
* resulting binary. */

can_fail =
!(exact_type<BeamTypeId::Bitstring>(seg.src) &&
std::gcd(seg.unit, getSizeUnit(seg.src)) == seg.unit);

load_erl_bits_state(ARG1);
a.mov(ARG2, c_p);
mov_arg(ARG3, seg.src);
mov_imm(ARG4, seg.unit);

if (can_fail) {
mov_imm(ARG4, seg.unit);
}

emit_enter_runtime<Update::eReductions>(Live.get());
runtime_call<4>(erts_bs_put_binary_all);
if (can_fail) {
runtime_call<4>(erts_bs_put_binary_all);
} else {
runtime_call<3>(beam_jit_bs_put_binary_all);
}
emit_leave_runtime<Update::eReductions>(Live.get());

error_info = beam_jit_update_bsc_reason_info(seg.error_info,
BSC_REASON_BADARG,
BSC_INFO_UNIT,
BSC_VALUE_FVALUE);
if (exact_type<BeamTypeId::Bitstring>(seg.src) &&
std::gcd(seg.unit, getSizeUnit(seg.src)) == seg.unit) {
if (!can_fail) {
comment("skipped test for success because units are "
"compatible");
can_fail = false;
}
} else {
/* The size is a variable. We have verified that
Expand Down
17 changes: 17 additions & 0 deletions erts/emulator/beam/jit/beam_jit_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,23 @@ Eterm beam_jit_int128_to_big(Process *p, Uint sign, Uint low, Uint high) {
return make_big(hp);
}

void beam_jit_bs_put_binary_all(ErlBitsState *EBS, Process *c_p, Eterm arg) {
Uint offset, size;
byte *base;

/* This instruction is always preceded by a size calculation that
* guarantees that 'arg' is a bitstring. */
ASSERT(is_bitstring(arg));

ERTS_GET_BITSTRING(arg, base, offset, size);

copy_binary_to_buffer(EBS->erts_current_bin, EBS->erts_bin_offset,
base, offset, size);
EBS->erts_bin_offset += size;

BUMP_REDS(c_p, size / ERL_BITS_PER_REDUCTION);
}

ErtsMessage *beam_jit_decode_dist(Process *c_p, ErtsMessage *msgp) {
if (!erts_proc_sig_decode_dist(c_p, ERTS_PROC_LOCK_MAIN, msgp, 0)) {
/*
Expand Down
1 change: 1 addition & 0 deletions erts/emulator/beam/jit/beam_jit_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ void beam_jit_bs_construct_fail_info(Process *c_p,
Eterm arg3,
Eterm arg1);
Sint beam_jit_bs_bit_size(Eterm term);
void beam_jit_bs_put_binary_all(ErlBitsState *EBS, Process *c_p, Eterm arg);

Eterm beam_jit_int128_to_big(Process *p, Uint sign, Uint low, Uint high);

Expand Down

0 comments on commit 67a8124

Please sign in to comment.