summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2022-02-22 19:11:54 +0100
committerJohn Högberg <john@erlang.org>2022-02-23 11:59:00 +0100
commit4fcc888356136c457063f48255281fab43d57bbf (patch)
tree9fd502276c2c635b49255161669eb696c293a4cb
parenta891d232053953284c8fbba5e8914f410fbd5389 (diff)
downloaderlang-4fcc888356136c457063f48255281fab43d57bbf.tar.gz
erts: Minor loader optimizations and cleanup
This commit moves some validation from being done once per operation (in all builds) to being done once on startup in debug mode. We also take the opportunity to remove some ancient cruft like special error handling on unicode character operands, which we planned on having at some point but never added.
-rw-r--r--erts/emulator/beam/beam_file.c15
-rw-r--r--erts/emulator/beam/beam_load.c31
2 files changed, 21 insertions, 25 deletions
diff --git a/erts/emulator/beam/beam_file.c b/erts/emulator/beam/beam_file.c
index 3caece384a..2329b200ae 100644
--- a/erts/emulator/beam/beam_file.c
+++ b/erts/emulator/beam/beam_file.c
@@ -1485,8 +1485,7 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) {
reader = &code_reader->reader;
LoadAssert(beamreader_read_u8(reader, &opcode));
- LoadAssert(opcode <= MAX_GENERIC_OPCODE);
- LoadAssert(gen_opc[opcode].name[0] != '\0');
+ LoadAssert(opcode > 0 && opcode <= MAX_GENERIC_OPCODE);
arity = gen_opc[opcode].arity;
ASSERT(arity <= ERTS_BEAM_MAX_OPARGS);
@@ -1526,12 +1525,6 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) {
case TAG_i:
LoadAssert(marshal_integer(code_reader, &raw_arg));
break;
- case TAG_h:
- /* Character, must be a valid unicode code point. */
- LoadAssert(raw_arg.word_value <= 0x10FFFF &&
- (raw_arg.word_value < 0xD800 ||
- raw_arg.word_value > 0xDFFFUL));
- break;
case TAG_x:
case TAG_y:
LoadAssert(raw_arg.word_value < MAX_REG);
@@ -1629,8 +1622,10 @@ static int beamcodereader_read_next(BeamCodeReader *code_reader, BeamOp **out) {
LoadAssert(index.tag == TAG_u);
types = &(code_reader->file)->types;
- /* If we use the fallback, then there was not type chunk
- and thus we should not load any type information */
+
+ /* We may land here without a table if it was stripped
+ * after compilation, in which case we want to treat these
+ * as ordinary registers. */
if (!types->fallback) {
LoadAssert(index.word_value < types->count);
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index dd7422b6cd..9b7a229d1c 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -56,6 +56,20 @@ void init_load(void)
erts_total_code_size = 0;
beam_catches_init();
erts_init_ranges();
+
+#ifdef DEBUG
+ {
+ int i;
+
+ for (i = 1; i < num_instructions; i++) {
+ const GenOpEntry *op = &gen_opc[i];
+
+ ASSERT(op->name && op->name[0] != '\0');
+ ASSERT(op->arity <= ERTS_BEAM_MAX_OPARGS);
+ ASSERT(op->num_specific <= 1 || op->arity <= 6);
+ }
+ }
+#endif
}
Binary *erts_alloc_loader_state(void) {
@@ -459,14 +473,10 @@ static int load_code(LoaderState* stp)
* the possible specific instructions associated with this
* specific instruction.
*/
- Uint32 mask[3] = {0, 0, 0};
-
int specific, arity, arg, i;
+ Uint32 mask[3] = {0, 0, 0};
arity = gen_opc[tmp_op->op].arity;
- if (arity > 6) {
- BeamLoadError0(stp, "no specific operation found (arity > 6)");
- }
for (arg = 0; arg < arity; arg++) {
int type = tmp_op->a[arg].type;
@@ -530,17 +540,8 @@ static int load_code(LoaderState* stp)
/*
* No specific operation found.
*/
- if (i == num_specific) {
+ if (ERTS_UNLIKELY(i == num_specific)) {
stp->specific_op = -1;
- for (arg = 0; arg < tmp_op->arity; arg++) {
- /*
- * We'll give the error message here (instead of earlier)
- * to get a printout of the offending operation.
- */
- if (tmp_op->a[arg].type == TAG_h) {
- BeamLoadError0(stp, "the character data type is not supported");
- }
- }
/*
* No specific operations and no transformations means that