Skip to content

Commit 9410528

Browse files
committed
perf: otp: pack wasm failure labels with registers
1 parent 35e7083 commit 9410528

1 file changed

Lines changed: 212 additions & 0 deletions

File tree

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
2+
index 6424077b835bf62cff12b671d8200d764a67890e..2174829a6caae0ab6ad1300362e3684af03c95d0 100644
3+
--- a/erts/emulator/Makefile.in
4+
+++ b/erts/emulator/Makefile.in
5+
@@ -613,6 +613,7 @@ $(TTF_DIR)/OPCODES-GENERATED: $(OPCODE_TABLES) utils/beam_makeops
6+
-code-model @CODE_MODEL@ \
7+
-outdir $(TTF_DIR) \
8+
-jit $(if $(filter jit,$(FLAVOR)),yes,no) \
9+
+ -DWASM32=$(if $(filter wasm32-unknown-emscripten,$(TARGET)),1,0) \
10+
-DUSE_VM_PROBES=$(if $(USE_VM_PROBES),1,0) \
11+
-emulator $(OPCODE_TABLES) && echo $? >$(TTF_DIR)/OPCODES-GENERATED
12+
GENERATE += $(TTF_DIR)/OPCODES-GENERATED
13+
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
14+
index 9a3dcd29cef282dce3b36e851ca1ae765bf6e565..a0e7bc0d1b1ef29440a995495f80c0d9aefc7cc7 100644
15+
--- a/erts/emulator/beam/beam_debug.c
16+
+++ b/erts/emulator/beam/beam_debug.c
17+
@@ -647,6 +647,15 @@ print_op(fmtfn_t to, void *to_arg, int op, int size, BeamInstr* addr)
18+
*ap++ = packed & BEAM_LOOSE_MASK;
19+
packed >>= BEAM_LOOSE_SHIFT;
20+
break;
21+
+#ifdef BEAM_COMPACT_LABEL_MASK
22+
+ case '5':
23+
+ *ap++ = (BeamInstr)((Sint32)packed >>
24+
+ BEAM_COMPACT_LABEL_SHIFT);
25+
+ break;
26+
+ case '6':
27+
+ *ap++ = (packed & BEAM_TIGHTEST_MASK) << 2;
28+
+ break;
29+
+#endif
30+
#ifdef ARCH_64
31+
case '4': /* Shift 32 steps */
32+
*ap++ = packed & BEAM_WIDE_MASK;
33+
diff --git a/erts/emulator/beam/emu/beam_emu.c b/erts/emulator/beam/emu/beam_emu.c
34+
index a473b89fbd3bc313a7d235b9925bbd7993217207..7b1b3e7b0051fb17b13bb05d66536445d9d36eb2 100644
35+
--- a/erts/emulator/beam/emu/beam_emu.c
36+
+++ b/erts/emulator/beam/emu/beam_emu.c
37+
@@ -162,6 +162,7 @@ void** beam_ops;
38+
39+
#define db(N) (N)
40+
#define fb(N) ((Sint)(Sint32)(N))
41+
+#define fcb(N) ((Sint)((Sint32)((Uint32)(N) << 10) >> 10))
42+
#define jb(N) ((Sint)(Sint32)(N))
43+
#define tb(N) (N)
44+
#define xb(N) (*ADD_BYTE_OFFSET(reg, N))
45+
diff --git a/erts/emulator/beam/emu/emu_load.c b/erts/emulator/beam/emu/emu_load.c
46+
index e5eb108ed0331273823cefd93074704d507eccd6..7f11c01db95b8b5a69afeadd86f498a72e8ecb52 100644
47+
--- a/erts/emulator/beam/emu/emu_load.c
48+
+++ b/erts/emulator/beam/emu/emu_load.c
49+
@@ -535,6 +535,17 @@ int beam_load_finish_emit(LoaderState *stp) {
50+
codev[pos] = ((Uint)rel << BEAM_WIDE_SHIFT) |
51+
(codev[pos] & BEAM_WIDE_MASK);
52+
break;
53+
+#endif
54+
+#ifdef BEAM_COMPACT_LABEL_MASK
55+
+ case 3:
56+
+ ASSERT(rel >= -(1 << 21) && rel < (1 << 21));
57+
+ codev[pos] =
58+
+ (codev[pos] &
59+
+ ~((BeamInstr)BEAM_COMPACT_LABEL_MASK <<
60+
+ BEAM_COMPACT_LABEL_SHIFT)) |
61+
+ (((BeamInstr)rel & BEAM_COMPACT_LABEL_MASK) <<
62+
+ BEAM_COMPACT_LABEL_SHIFT);
63+
+ break;
64+
#endif
65+
default:
66+
ASSERT(0);
67+
@@ -1182,6 +1193,34 @@ int beam_load_emit_op(LoaderState *stp, BeamOp *tmp_op) {
68+
packed_label->packed++;
69+
}
70+
break;
71+
+#ifdef BEAM_COMPACT_LABEL_MASK
72+
+ case '5':
73+
+ {
74+
+ Uint w = code[--ci];
75+
+ LabelPatch* lp;
76+
+ int patch;
77+
+
78+
+ if (w != 0) {
79+
+ lp = stp->labels[w].patches;
80+
+ for (patch = stp->labels[w].num_patches - 1;
81+
+ patch >= 0;
82+
+ patch--) {
83+
+ if (lp[patch].pos == ci) {
84+
+ lp[patch].packed = 3;
85+
+ packed_label = &lp[patch];
86+
+ break;
87+
+ }
88+
+ }
89+
+ ASSERT(packed_label);
90+
+ }
91+
+ }
92+
+ break;
93+
+ case '6':
94+
+ ci--;
95+
+ ASSERT((code[ci] & 3) == 0);
96+
+ packed = code[ci] >> 2;
97+
+ break;
98+
+#endif
99+
#ifdef ARCH_64
100+
case '4': /* Wide shift (32 bits) */
101+
{
102+
diff --git a/erts/emulator/beam/emu/load.h b/erts/emulator/beam/emu/load.h
103+
index 5906abaf8e7a1f33ef695f670135b66427c34280..cde51aa1bb9afcf3ee4ee5bee2f6094a7809e276 100644
104+
--- a/erts/emulator/beam/emu/load.h
105+
+++ b/erts/emulator/beam/emu/load.h
106+
@@ -31,7 +31,7 @@
107+
typedef struct {
108+
Uint pos; /* Position of label reference to patch. */
109+
Uint offset; /* Offset from patch location. */
110+
- int packed; /* 0 (not packed), 1 (lsw), 2 (msw) */
111+
+ int packed; /* 0 (not packed), 1/2 (wide), 3 (compact) */
112+
} LabelPatch;
113+
114+
/*
115+
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
116+
index a1c45a887820d949f2a1fd0811894024cb4f5c4c..240cd13619a31738f4d08ed116cd9d82134a4e8e 100755
117+
--- a/erts/emulator/utils/beam_makeops
118+
+++ b/erts/emulator/utils/beam_makeops
119+
@@ -37,6 +37,8 @@ use constant PACK_CMD_TIGHTEST => '1';
120+
use constant PACK_CMD_TIGHT => '2';
121+
use constant PACK_CMD_LOOSE => '3';
122+
use constant PACK_CMD_WIDE => '4';
123+
+use constant PACK_CMD_COMPACT_LABEL => '5';
124+
+use constant PACK_CMD_COMPACT_REG => '6';
125+
126+
$BEAM_FORMAT_NUMBER = undef;
127+
$GC_REGEXP = undef;
128+
@@ -379,6 +381,8 @@ while (@ARGV && $ARGV[0] =~ /^-(.*)/) {
129+
if ($wordsize == 32) {
130+
$defs{'ARCH_32'} = 1;
131+
$defs{'ARCH_64'} = 0;
132+
+ @basic_pack_options = (0,PACK_JUMP) if $defs{'WASM32'};
133+
+ @extended_pack_options = @basic_pack_options;
134+
} elsif ($wordsize == 64) {
135+
$defs{'ARCH_32'} = 0;
136+
$defs{'ARCH_64'} = 1;
137+
@@ -1032,6 +1036,11 @@ sub emulator_output {
138+
print "#define BEAM_TIGHT_MASK 0xFFC\n";
139+
print "#define BEAM_LOOSE_SHIFT 16\n";
140+
print "#define BEAM_TIGHT_SHIFT 10\n";
141+
+ if ($defs{'WASM32'}) {
142+
+ print "#define BEAM_TIGHTEST_MASK 0x3FF\n";
143+
+ print "#define BEAM_COMPACT_LABEL_MASK 0x3FFFFF\n";
144+
+ print "#define BEAM_COMPACT_LABEL_SHIFT 10\n";
145+
+ }
146+
} elsif ($wordsize == 64) {
147+
print "#if !defined(ARCH_64)\n";
148+
print qq[ #error "64-bit architecture assumed, but ARCH_64 not defined"\n];
149+
@@ -2064,6 +2073,11 @@ sub do_pack_one {
150+
my @bits_needed; # Bits needed for each argument.
151+
my $pack_in_iw = $options & PACK_IN_INSTR_WORD;
152+
153+
+ if ($defs{'WASM32'} && ($options & PACK_JUMP) &&
154+
+ !(@args >= 2 && $args[0] eq 'f' && $args[1] =~ /^[xy]$/)) {
155+
+ return (0, []);
156+
+ }
157+
+
158+
#
159+
# Define the minimum number of bits needed for the packable argument types.
160+
#
161+
@@ -2080,6 +2094,8 @@ sub do_pack_one {
162+
$bits_needed{'f'} = 32;
163+
$bits_needed{'j'} = 32;
164+
}
165+
+ } elsif ($defs{'WASM32'} && ($options & PACK_JUMP)) {
166+
+ $bits_needed{'f'} = 22;
167+
}
168+
169+
#
170+
@@ -2270,9 +2286,12 @@ sub do_pack_one {
171+
my $args_per_word = $args_per_word[$word];
172+
my $pack_word_size = ($pack_in_iw && $word == 0) ? 32 : $wordsize;
173+
174+
+ my $compact_label = $defs{'WASM32'} && ($options & PACK_JUMP) &&
175+
+ $args_per_word == 2 &&
176+
+ $args[$arg_num] eq 'f' && $args[$arg_num+1] =~ /^[xy]$/;
177+
my($shref,$mref,$iref,$unpack_suffix) =
178+
get_pack_parameters($name, $args_per_word, $pack_word_size,
179+
- $need_wide_mask[$word]);
180+
+ $need_wide_mask[$word], $compact_label);
181+
my @shift = @$shref;
182+
my @mask = @$mref;
183+
my @instr = @$iref;
184+
@@ -2306,7 +2325,8 @@ sub do_pack_one {
185+
186+
$down = "$instr[$ap]$down";
187+
my $unpack = make_unpack($packed_var, $shift[$ap], $mask[$ap]);
188+
- my $macro = "$reg$unpack_suffix";
189+
+ my $macro = $compact_label && $reg eq 'f' ? 'fcb' :
190+
+ "$reg$unpack_suffix";
191+
$args[$arg_num] = "packed:$reg:$this_size:$macro($unpack)";
192+
193+
$ap++;
194+
@@ -2335,11 +2355,16 @@ sub do_pack_one {
195+
}
196+
197+
sub get_pack_parameters {
198+
- my($name,$args_per_word,$pack_word_size,$wide_mask) = @_;
199+
+ my($name,$args_per_word,$pack_word_size,$wide_mask,$compact_label) = @_;
200+
my(@shift,@mask,@instr);
201+
my $unpack_suffix = 'b';
202+
203+
- if ($wide_mask and $args_per_word > 1) {
204+
+ if ($compact_label) {
205+
+ @shift = ('BEAM_COMPACT_LABEL_SHIFT', '0');
206+
+ @mask = ($WHOLE_WORD, 'BEAM_TIGHTEST_MASK');
207+
+ @instr = (PACK_CMD_COMPACT_LABEL, PACK_CMD_COMPACT_REG);
208+
+ $unpack_suffix = '';
209+
+ } elsif ($wide_mask and $args_per_word > 1) {
210+
@shift = ('0', 'BEAM_WIDE_SHIFT');
211+
@mask = ('BEAM_WIDE_MASK', $WHOLE_WORD);
212+
@instr = (PACK_CMD_WIDE) x 2;

0 commit comments

Comments
 (0)