summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2021-10-10 08:40:29 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2021-10-14 04:59:22 +0200
commit16c5728f442b51caca42bcd827a2058051ef8733 (patch)
treea773bbc3533b31ce113b9f7eb225ea219fdb1c27
parent2ac5f27a4115b5c0fcad0e6b3029e679e4c00afd (diff)
downloaderlang-16c5728f442b51caca42bcd827a2058051ef8733.tar.gz
Clean up the bs_init* helpers and instructions
Eliminate uncessary gotos. Always test the virtual binary heap when deciding whether a GC is needed (it is currently only done for binaries whose size are given in bytes).
-rw-r--r--erts/emulator/beam/emu/bs_instrs.tab56
-rw-r--r--erts/emulator/beam/jit/beam_jit_common.cpp80
-rw-r--r--erts/emulator/beam/jit/beam_jit_common.hpp4
3 files changed, 68 insertions, 72 deletions
diff --git a/erts/emulator/beam/emu/bs_instrs.tab b/erts/emulator/beam/emu/bs_instrs.tab
index 305b2d6312..a5e6bb46de 100644
--- a/erts/emulator/beam/emu/bs_instrs.tab
+++ b/erts/emulator/beam/emu/bs_instrs.tab
@@ -426,13 +426,14 @@ bs_init.verify(Fail) {
}
bs_init.execute(Live, Dst) {
+ erts_bin_offset = 0;
+ erts_writable_bin = 0;
+
if (BsOp1 <= ERL_ONHEAP_BIN_LIMIT) {
ErlHeapBin* hb;
Uint bin_need;
bin_need = heap_bin_size(BsOp1);
- erts_bin_offset = 0;
- erts_writable_bin = 0;
$GC_TEST(0, bin_need+BsOp2+ERL_SUB_BIN_SIZE, $Live);
hb = (ErlHeapBin *) HTOP;
HTOP += bin_need;
@@ -444,10 +445,7 @@ bs_init.execute(Live, Dst) {
Binary* bptr;
ProcBin* pb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
- $TEST_BIN_VHEAP(BsOp1 / sizeof(Eterm),
- BsOp2 + PROC_BIN_SIZE + ERL_SUB_BIN_SIZE, $Live);
+ $TEST_BIN_VHEAP(BsOp1 / sizeof(Eterm), BsOp2 + PROC_BIN_SIZE, $Live);
/*
* Allocate the binary struct itself.
@@ -539,7 +537,9 @@ bs_init_bits.execute(Live, Dst) {
} else {
alloc += PROC_BIN_SIZE;
}
- $test_heap(alloc, $Live);
+
+ erts_bin_offset = 0;
+ erts_writable_bin = 0;
/* num_bits = Number of bits to build
* num_bytes = Number of bytes to allocate in the binary
@@ -549,38 +549,18 @@ bs_init_bits.execute(Live, Dst) {
if (num_bytes <= ERL_ONHEAP_BIN_LIMIT) {
ErlHeapBin* hb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
+ $test_heap(alloc, $Live);
hb = (ErlHeapBin *) HTOP;
HTOP += heap_bin_size(num_bytes);
hb->thing_word = header_heap_bin(num_bytes);
hb->size = num_bytes;
erts_current_bin = (byte *) hb->data;
new_binary = make_binary(hb);
-
- do_bits_sub_bin:
- if (num_bits & 7) {
- ErlSubBin* sb;
-
- sb = (ErlSubBin *) HTOP;
- HTOP += ERL_SUB_BIN_SIZE;
- sb->thing_word = HEADER_SUB_BIN;
- sb->size = num_bytes - 1;
- sb->bitsize = num_bits & 7;
- sb->offs = 0;
- sb->bitoffs = 0;
- sb->is_writable = 0;
- sb->orig = new_binary;
- new_binary = make_binary(sb);
- }
- HEAP_SPACE_VERIFIED(0);
- $Dst = new_binary;
} else {
Binary* bptr;
ProcBin* pb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
+ $TEST_BIN_VHEAP(num_bytes / sizeof(Eterm), alloc, $Live);
/*
* Allocate the binary struct itself.
@@ -602,8 +582,24 @@ bs_init_bits.execute(Live, Dst) {
pb->flags = 0;
OH_OVERHEAD(&(MSO(c_p)), pb->size / sizeof(Eterm));
new_binary = make_binary(pb);
- goto do_bits_sub_bin;
}
+
+ if (num_bits & 7) {
+ ErlSubBin* sb;
+
+ sb = (ErlSubBin *) HTOP;
+ HTOP += ERL_SUB_BIN_SIZE;
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = num_bytes - 1;
+ sb->bitsize = num_bits & 7;
+ sb->offs = 0;
+ sb->bitoffs = 0;
+ sb->is_writable = 0;
+ sb->orig = new_binary;
+ new_binary = make_binary(sb);
+ }
+ HEAP_SPACE_VERIFIED(0);
+ $Dst = new_binary;
}
bs_add(Fail, Src1, Src2, Unit, Dst) {
diff --git a/erts/emulator/beam/jit/beam_jit_common.cpp b/erts/emulator/beam/jit/beam_jit_common.cpp
index c372bcea2c..b1a43206d8 100644
--- a/erts/emulator/beam/jit/beam_jit_common.cpp
+++ b/erts/emulator/beam/jit/beam_jit_common.cpp
@@ -572,39 +572,37 @@ void beam_jit_bs_add_argument_error(Process *c_p, Eterm A, Eterm B) {
Eterm beam_jit_bs_init(Process *c_p,
Eterm *reg,
ERL_BITS_DECLARE_STATEP,
- Eterm BsOp1,
- Eterm BsOp2,
+ Eterm num_bytes,
+ Uint alloc,
unsigned Live) {
- if (BsOp1 <= ERL_ONHEAP_BIN_LIMIT) {
+ erts_bin_offset = 0;
+ erts_writable_bin = 0;
+ if (num_bytes <= ERL_ONHEAP_BIN_LIMIT) {
ErlHeapBin *hb;
Uint bin_need;
- bin_need = heap_bin_size(BsOp1);
- erts_bin_offset = 0;
- erts_writable_bin = 0;
- gc_test(c_p, reg, 0, bin_need + BsOp2 + ERL_SUB_BIN_SIZE, Live);
+ bin_need = heap_bin_size(num_bytes);
+ gc_test(c_p, reg, 0, bin_need + alloc + ERL_SUB_BIN_SIZE, Live);
hb = (ErlHeapBin *)c_p->htop;
c_p->htop += bin_need;
- hb->thing_word = header_heap_bin(BsOp1);
- hb->size = BsOp1;
+ hb->thing_word = header_heap_bin(num_bytes);
+ hb->size = num_bytes;
erts_current_bin = (byte *)hb->data;
return make_binary(hb);
} else {
Binary *bptr;
ProcBin *pb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
test_bin_vheap(c_p,
reg,
- BsOp1 / sizeof(Eterm),
- BsOp2 + PROC_BIN_SIZE + ERL_SUB_BIN_SIZE,
+ num_bytes / sizeof(Eterm),
+ alloc + PROC_BIN_SIZE,
Live);
/*
* Allocate the binary struct itself.
*/
- bptr = erts_bin_nrml_alloc(BsOp1);
+ bptr = erts_bin_nrml_alloc(num_bytes);
erts_current_bin = (byte *)bptr->orig_bytes;
/*
@@ -613,14 +611,14 @@ Eterm beam_jit_bs_init(Process *c_p,
pb = (ProcBin *)c_p->htop;
c_p->htop += PROC_BIN_SIZE;
pb->thing_word = HEADER_PROC_BIN;
- pb->size = BsOp1;
+ pb->size = num_bytes;
pb->next = MSO(c_p).first;
MSO(c_p).first = (struct erl_off_heap_header *)pb;
pb->val = bptr;
pb->bytes = (byte *)bptr->orig_bytes;
pb->flags = 0;
- OH_OVERHEAD(&(MSO(c_p)), BsOp1 / sizeof(Eterm));
+ OH_OVERHEAD(&(MSO(c_p)), num_bytes / sizeof(Eterm));
return make_binary(pb);
}
@@ -643,7 +641,9 @@ Eterm beam_jit_bs_init_bits(Process *c_p,
} else {
alloc += PROC_BIN_SIZE;
}
- gc_test(c_p, reg, 0, alloc, Live);
+
+ erts_bin_offset = 0;
+ erts_writable_bin = 0;
/* num_bits = Number of bits to build
* num_bytes = Number of bytes to allocate in the binary
@@ -653,38 +653,22 @@ Eterm beam_jit_bs_init_bits(Process *c_p,
if (num_bytes <= ERL_ONHEAP_BIN_LIMIT) {
ErlHeapBin *hb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
+ gc_test(c_p, reg, 0, alloc, Live);
hb = (ErlHeapBin *)c_p->htop;
c_p->htop += heap_bin_size(num_bytes);
hb->thing_word = header_heap_bin(num_bytes);
hb->size = num_bytes;
erts_current_bin = (byte *)hb->data;
new_binary = make_binary(hb);
-
- do_bits_sub_bin:
- if (num_bits & 7) {
- ErlSubBin *sb;
-
- sb = (ErlSubBin *)c_p->htop;
- c_p->htop += ERL_SUB_BIN_SIZE;
- sb->thing_word = HEADER_SUB_BIN;
- sb->size = num_bytes - 1;
- sb->bitsize = num_bits & 7;
- sb->offs = 0;
- sb->bitoffs = 0;
- sb->is_writable = 0;
- sb->orig = new_binary;
- new_binary = make_binary(sb);
- }
- /* HEAP_SPACE_VERIFIED(0); */
- return new_binary;
} else {
Binary *bptr;
ProcBin *pb;
- erts_bin_offset = 0;
- erts_writable_bin = 0;
+ test_bin_vheap(c_p,
+ reg,
+ num_bytes / sizeof(Eterm),
+ alloc,
+ Live);
/*
* Allocate the binary struct itself.
@@ -706,8 +690,24 @@ Eterm beam_jit_bs_init_bits(Process *c_p,
pb->flags = 0;
OH_OVERHEAD(&(MSO(c_p)), pb->size / sizeof(Eterm));
new_binary = make_binary(pb);
- goto do_bits_sub_bin;
}
+
+ if (num_bits & 7) {
+ ErlSubBin *sb;
+
+ sb = (ErlSubBin *)c_p->htop;
+ c_p->htop += ERL_SUB_BIN_SIZE;
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = num_bytes - 1;
+ sb->bitsize = num_bits & 7;
+ sb->offs = 0;
+ sb->bitoffs = 0;
+ sb->is_writable = 0;
+ sb->orig = new_binary;
+ new_binary = make_binary(sb);
+ }
+
+ return new_binary;
}
Eterm beam_jit_bs_get_integer(Process *c_p,
diff --git a/erts/emulator/beam/jit/beam_jit_common.hpp b/erts/emulator/beam/jit/beam_jit_common.hpp
index ca73395006..8db8c95eac 100644
--- a/erts/emulator/beam/jit/beam_jit_common.hpp
+++ b/erts/emulator/beam/jit/beam_jit_common.hpp
@@ -269,8 +269,8 @@ void beam_jit_bs_add_argument_error(Process *c_p, Eterm A, Eterm B);
Eterm beam_jit_bs_init(Process *c_p,
Eterm *reg,
ERL_BITS_DECLARE_STATEP,
- Eterm BsOp1,
- Eterm BsOp2,
+ Eterm num_bytes,
+ Uint alloc,
unsigned Live);
Eterm beam_jit_bs_init_bits(Process *c_p,
Eterm *reg,