summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/beam_load.h
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2020-06-01 13:28:59 +0200
committerLukas Larsson <lukas@erlang.org>2020-09-21 16:40:30 +0200
commite5cd42063d7d3e65ffd4efe0c301171df4400b9f (patch)
treef9143b18129a1c7181231892c8e0142e4f438b4e /erts/emulator/beam/beam_load.h
parente53f65f3474eba59962f02d031bea1d9582ad3cc (diff)
downloaderlang-e5cd42063d7d3e65ffd4efe0c301171df4400b9f.tar.gz
erts: Break out BEAM file handling to its own module
Diffstat (limited to 'erts/emulator/beam/beam_load.h')
-rw-r--r--erts/emulator/beam/beam_load.h270
1 files changed, 72 insertions, 198 deletions
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index eef2a3ad47..7f74aa7755 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -22,12 +22,12 @@
# define _BEAM_LOAD_H
#include "beam_opcodes.h"
+#include "beam_file.h"
+
#include "erl_process.h"
+#include "erl_bif_table.h"
#include "erl_fun.h"
-#define ERTS_BEAM_MAX_OPARGS 8
-#define ERTS_BEAM_NUM_CHUNK_TYPES 11
-
Eterm beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks,
Eterm module);
@@ -42,36 +42,6 @@ typedef struct gen_op_entry {
extern const GenOpEntry gen_opc[];
/*
- * Type for an operand for a generic instruction.
- */
-
-typedef struct {
- unsigned type; /* Type of operand. */
- BeamInstr val; /* Value of operand. */
-} GenOpArg;
-
-/*
- * A generic operation.
- */
-
-typedef struct genop {
- unsigned int op; /* Opcode. */
- int arity; /* Number of arguments. */
- GenOpArg def_args[ERTS_BEAM_MAX_OPARGS]; /* Default buffer for arguments. */
- GenOpArg* a; /* The arguments. */
- struct genop* next; /* Next genop. */
-} GenOp;
-
-/*
- * The allocation unit for generic blocks.
- */
-
-typedef struct genop_block {
- GenOp genop[32];
- struct genop_block* next;
-} GenOpBlock;
-
-/*
* Type for a reference to a label that must be patched.
*/
@@ -86,33 +56,21 @@ typedef struct {
*/
typedef struct {
- Uint value; /* Value of label (0 if not known yet). */
- Uint looprec_targeted; /* Non-zero if this label is the target of a loop_rec
- * instruction.
- */
+ Uint value; /* Value of label (0 if not known yet). */
+ Uint looprec_targeted; /* Non-zero if this label is the target of a
+ * loop_rec instruction.
+ */
LabelPatch* patches; /* Array of label patches. */
Uint num_patches; /* Number of patches in array. */
Uint num_allocated; /* Number of allocated patches. */
} Label;
/*
- * This structure keeps load-time information about a lambda.
- */
-
-typedef struct {
- ErlFunEntry* fe; /* Entry in fun table. */
- unsigned label; /* Label of function entry. */
- Uint32 num_free; /* Number of free variables. */
- Eterm function; /* Name of local function. */
- int arity; /* Arity (including free variables). */
-} Lambda;
-
-/*
* This structure keeps load-time information about a literal.
*/
typedef struct {
- Eterm term; /* The tagged term (in the heap). */
+ Eterm term; /* The tagged term (in the heap). */
ErlHeapFragment* heap_frags;
} Literal;
@@ -122,59 +80,36 @@ typedef struct {
* frozen.
*/
-typedef struct literal_patch LiteralPatch;
-struct literal_patch {
- Uint pos; /* Position in code */
- LiteralPatch* next;
-};
+typedef struct literal_patch {
+ Uint pos; /* Position in code */
+ struct literal_patch *next;
+} LiteralPatch;
/*
* This structure keeps information about an operand that needs to be
* patched to contain the correct address for an address into the string table.
*/
-typedef struct string_patch StringPatch;
-struct string_patch {
- int pos; /* Position in code */
- StringPatch* next;
-};
+typedef struct string_patch {
+ Uint pos; /* Position in code */
+ struct string_patch *next;
+} StringPatch;
+
+typedef struct lambda_patch {
+ Uint pos; /* Position in code */
+ struct lambda_patch *next;
+} LambdaPatch;
/*
* This structure associates a code offset with a source code location.
*/
typedef struct {
- int pos; /* Position in code */
- Uint32 loc; /* Location in source code */
+ int pos; /* Position in code */
+ int loc; /* Location in source code */
} LineInstr;
/*
- * This structure contains information for an imported function or BIF.
- */
-typedef struct {
- Eterm module; /* Tagged atom for module. */
- Eterm function; /* Tagged atom for function. */
- int arity; /* Arity. */
- Uint patches; /* Index to locations in code to
- * eventually patch with a pointer into
- * the export entry.
- */
- Export *bif; /* Pointer to export entry if BIF;
- * NULL otherwise.
- */
-} ImportEntry;
-
-/*
- * This structure contains information for a function exported from a module.
- */
-
-typedef struct {
- Eterm function; /* Tagged atom for function. */
- int arity; /* Arity. */
- BeamInstr* address; /* Address to function in code. */
-} ExportEntry;
-
-/*
* This structure contains all information about the module being loaded.
*/
#define MD5_SIZE 16
@@ -182,137 +117,79 @@ typedef struct LoaderState {
/*
* The current logical file within the binary.
*/
-
- char* file_name; /* Name of file we are reading (usually chunk name). */
- byte* file_p; /* Current pointer within file. */
- unsigned file_left; /* Number of bytes left in file. */
- ErlDrvBinary* bin; /* Binary holding BEAM file (or NULL) */
+ ErlDrvBinary* bin; /* Binary holding BEAM file (or NULL) */
/*
* The following are used mainly for diagnostics.
*/
- Eterm group_leader; /* Group leader (for diagnostics). */
- Eterm module; /* Tagged atom for module name. */
- Eterm function; /* Tagged atom for current function
- * (or 0 if none).
- */
- unsigned arity; /* Arity for current function. */
-
- /*
- * All found chunks.
- */
-
- struct {
- byte* start; /* Start of chunk (in binary). */
- unsigned size; /* Size of chunk. */
- } chunks[ERTS_BEAM_NUM_CHUNK_TYPES];
+ Eterm group_leader; /* Group leader (for diagnostics). */
+ Eterm module; /* Tagged atom for module name. */
+ Eterm function; /* Tagged atom for current function
+ * (or 0 if none).
+ */
+ unsigned arity; /* Arity for current function. */
/*
* Used for code loading (mainly).
*/
- byte* code_start; /* Start of code file. */
- unsigned code_size; /* Size of code file. */
- int specific_op; /* Specific opcode (-1 if not found). */
- unsigned int num_functions; /* Number of functions in module. */
- unsigned int num_labels; /* Number of labels. */
- struct beam_code_header* hdr; /* Loaded code header */
- BeamInstr* codev; /* Loaded code buffer */
- int codev_size; /* Size of code buffer in words. */
- int ci; /* Current index into loaded code buffer. */
- Label* labels;
- StringPatch* string_patches; /* Linked list of position into string table to patch. */
- BeamInstr catches; /* Linked list of catch_yf instructions. */
- unsigned loaded_size; /* Final size of code when loaded. */
- byte mod_md5[MD5_SIZE]; /* MD5 for module code. */
- int may_load_nif; /* true if NIFs may later be loaded for this module */
- int on_load; /* Index in the code for the on_load function
- * (or 0 if there is no on_load function)
- */
- int otp_20_or_higher; /* Compiled with OTP 20 or higher */
- unsigned max_opcode; /* Highest opcode used in module */
-
- /*
- * Atom table.
- */
-
- unsigned int num_atoms; /* Number of atoms in atom table. */
- Eterm* atom; /* Atom table. */
+ int specific_op; /* Specific opcode (-1 if not found). */
+ struct beam_code_header *hdr; /* Loaded code header */
- unsigned int num_exps; /* Number of exports. */
- ExportEntry* export; /* Pointer to export table. */
-
- unsigned int num_imports; /* Number of imports. */
- ImportEntry* import; /* Import entry (translated information). */
+ BeamInstr* codev; /* Loaded code buffer */
+ int codev_size; /* Size of code buffer in words. */
+ int ci; /* Current index into loaded code buffer. */
+ Label* labels;
+ unsigned loaded_size; /* Final size of code when loaded. */
+ int may_load_nif; /* true if NIFs may be loaded for this module */
+ int on_load; /* Index in the code for the on_load function
+ * (or 0 if there is no on_load function)
+ */
+ int otp_20_or_higher; /* Compiled with OTP 20 or higher */
/*
* Generic instructions.
*/
- GenOp* genop; /* The last generic instruction seen. */
- GenOp* free_genop; /* List of free genops. */
- GenOpBlock* genop_blocks; /* List of all block of allocated genops. */
+ BeamOp* genop; /* The last generic instruction seen. */
- /*
- * Lambda table.
- */
+ BifEntry **bif_imports;
- unsigned int num_lambdas; /* Number of lambdas in table. */
- unsigned int lambdas_allocated; /* Size of allocated lambda table. */
- Lambda* lambdas; /* Pointer to lambdas. */
- Lambda def_lambdas[16]; /* Default storage for lambda table. */
- char* lambda_error; /* Delayed missing 'FunT' error. */
-
- /*
- * Literals (constant pool).
- */
+ BeamInstr catches; /* Linked list of catch_yf instructions. */
+ BeamInstr *import_patches; /* Linked lists of import entries. */
- unsigned int num_literals; /* Number of literals in table. */
- unsigned int allocated_literals; /* Number of literal entries allocated. */
- Literal* literals; /* Array of literals. */
+ LambdaPatch* lambda_patches; /* Linked list of position into fun table to patch. */
LiteralPatch* literal_patches; /* Operands that need to be patched. */
- Uint total_literal_size; /* Total heap size for all literals. */
+ StringPatch* string_patches; /* Linked list of position into string table to patch. */
/*
* Line table.
*/
- BeamInstr* line_item; /* Line items from the BEAM file. */
- unsigned int num_line_items;/* Number of line items. */
LineInstr* line_instr; /* Line instructions */
- unsigned int num_line_instrs; /* Maximum number of line instructions */
unsigned int current_li; /* Current line instruction */
unsigned int* func_line; /* Mapping from function to first line instr */
- Eterm* fname; /* List of file names */
- unsigned int num_fnames; /* Number of filenames in fname table */
- int loc_size; /* Size of location info in bytes (2/4) */
+
+ /* !! */
+ BeamOpAllocator op_allocator;
+ BeamFile beam;
} LoaderState;
#ifdef DEBUG
# define GARBAGE 0xCC
-# define DEBUG_INIT_GENOP(Dst) sys_memset(Dst, GARBAGE, sizeof(GenOp))
+# define DEBUG_INIT_GENOP(Dst) sys_memset(Dst, GARBAGE, sizeof(BeamOp))
#else
# define DEBUG_INIT_GENOP(Dst)
#endif
-#define NEW_GENOP(Stp, Dst) \
- do { \
- if ((Stp)->free_genop == NULL) { \
- beam_load_new_genop((Stp)); \
- } \
- Dst = (Stp)->free_genop; \
- (Stp)->free_genop = (Stp)->free_genop->next; \
- DEBUG_INIT_GENOP(Dst); \
- (Dst)->a = (Dst)->def_args; \
- } while (0) \
-
-#define FREE_GENOP(Stp, Genop) \
- do { \
- if ((Genop)->a != (Genop)->def_args) { \
- erts_free(ERTS_ALC_T_LOADER_TMP, (Genop)->a); \
- } \
- (Genop)->next = (Stp)->free_genop; \
- (Stp)->free_genop = (Genop); \
- } while (0)
+#define NEW_GENOP(Stp, Dst) \
+ do { \
+ Dst = beamopallocator_new_op(&(Stp)->op_allocator); \
+ } while (0)
+
+#define FREE_GENOP(Stp, Genop) \
+ do { \
+ beamopallocator_free_op(&(Stp)->op_allocator, (Genop)); \
+ } while (0)
#define GENOP_NAME_ARITY(Genop, Name, Arity) \
do { \
@@ -320,18 +197,15 @@ typedef struct LoaderState {
(Genop)->arity = Arity; \
} while (0)
-#define GENOP_ARITY(Genop, Arity) \
- do { \
- ASSERT((Genop)->a == (Genop)->def_args); \
- (Genop)->arity = (Arity); \
- (Genop)->a = erts_alloc(ERTS_ALC_T_LOADER_TMP, \
- (Genop)->arity * sizeof(GenOpArg)); \
+#define GENOP_ARITY(Genop, Arity) \
+ do { \
+ ASSERT((Genop)->a == (Genop)->def_args); \
+ (Genop)->arity = (Arity); \
+ (Genop)->a = erts_alloc(ERTS_ALC_T_LOADER_TMP, \
+ (Genop)->arity * sizeof(BeamOpArg)); \
} while (0)
-void beam_load_new_genop(LoaderState* stp);
-Uint beam_load_new_literal(LoaderState* stp, Eterm** hpp, Uint heap_size);
int beam_load_new_label(LoaderState* stp);
-int beam_load_find_literal(LoaderState* stp, Eterm needle, Uint *idx);
struct ErtsLiteralArea_;
@@ -400,7 +274,7 @@ typedef struct beam_code_header {
*/
ErtsCodeInfo* functions[1];
-}BeamCodeHeader;
+} BeamCodeHeader;
/*
* The transform engine.
@@ -413,9 +287,9 @@ int erts_transform_engine(LoaderState* st);
#define TE_SHORT_WINDOW (-2)
int erts_beam_eval_predicate(unsigned int op, LoaderState* st,
- GenOpArg var[], GenOpArg* rest_args);
-GenOp* erts_beam_execute_transform(unsigned int op, LoaderState* st,
- GenOpArg var[], GenOpArg* rest_args);
+ BeamOpArg var[], BeamOpArg* rest_args);
+BeamOp* erts_beam_execute_transform(unsigned int op, LoaderState* st,
+ BeamOpArg var[], BeamOpArg* rest_args);