From 166032bddf9a14f3ea6252724532039a1113612d Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 11 Jan 2012 21:01:49 +0100 Subject: erts: Refactor Module struct --- erts/emulator/beam/beam_load.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index d54fe603d8..3040a2b7cd 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -972,9 +972,9 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, erts_total_code_size += size; modp = erts_put_module(module); - modp->code = code; - modp->code_length = size; - modp->catches = BEAM_CATCHES_NIL; /* Will be filled in later. */ + modp->curr.code = code; + modp->curr.code_length = size; + modp->curr.catches = BEAM_CATCHES_NIL; /* Will be filled in later. */ /* * Update address table (used for finding a function from a PC value). @@ -4283,7 +4283,7 @@ final_touch(LoaderState* stp) index = next; } modp = erts_put_module(stp->module); - modp->catches = catches; + modp->curr.catches = catches; /* * Export functions. @@ -5092,7 +5092,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */ if (modp == NULL) { return THE_NON_VALUE; } - code = modp->code; + code = modp->curr.code; num_functions = code[MI_NUM_FUNCTIONS]; need = 5*num_functions; hp = HAlloc(p, need); @@ -5147,7 +5147,7 @@ native_addresses(Process* p, Eterm mod) return THE_NON_VALUE; } - code = modp->code; + code = modp->curr.code; num_functions = code[MI_NUM_FUNCTIONS]; need = (6+BIG_UINT_HEAP_SIZE)*num_functions; hp = HAlloc(p, need); @@ -5246,7 +5246,7 @@ attributes_for_module(Process* p, /* Process whose heap to use. */ if (modp == NULL) { return THE_NON_VALUE; } - code = modp->code; + code = modp->curr.code; ext = (byte *) code[MI_ATTR_PTR]; if (ext != NULL) { hp = HAlloc(p, code[MI_ATTR_SIZE_ON_HEAP]); @@ -5286,7 +5286,7 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ if (modp == NULL) { return THE_NON_VALUE; } - code = modp->code; + code = modp->curr.code; ext = (byte *) code[MI_COMPILE_PTR]; if (ext != NULL) { hp = HAlloc(p, code[MI_COMPILE_SIZE_ON_HEAP]); -- cgit v1.2.3 From 9df5bbccee7f50e11969ed41035ee8bc4bf5f42a Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 11 Jan 2012 21:15:39 +0100 Subject: erts: Make use of def_lambdas optimization during loading The default array was defined but not used. --- erts/emulator/beam/beam_load.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 3040a2b7cd..27a5e72113 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -1409,9 +1409,12 @@ read_lambda_table(LoaderState* stp) int i; GetInt(stp, 4, stp->num_lambdas); - stp->lambdas_allocated = stp->num_lambdas; - stp->lambdas = (Lambda *) erts_alloc(ERTS_ALC_T_LOADER_TMP, - stp->num_lambdas * sizeof(Lambda)); + if (stp->num_lambdas > stp->lambdas_allocated) { + ASSERT(stp->lambdas == stp->def_lambdas); + stp->lambdas_allocated = stp->num_lambdas; + stp->lambdas = (Lambda *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->num_lambdas * sizeof(Lambda)); + } for (i = 0; i < stp->num_lambdas; i++) { Uint n; Uint32 Index; -- cgit v1.2.3 From 41cf0cb977472a15527b6ac693883daaa84faa5a Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 17 Jan 2012 11:18:26 +0100 Subject: erts: First stab at code_ix interface and beam_catches using it Code loading still blocking --- erts/emulator/beam/beam_load.c | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 27a5e72113..f7c8395cb6 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -6101,3 +6101,95 @@ static int safe_mul(UWord a, UWord b, UWord* resp) return (res / b) == a; } } + + +/*SVERK Do these deserve a file of their own maybe? */ + +static erts_smp_atomic32_t the_active_code_index; +static erts_smp_atomic32_t the_loader_code_index; + +#ifdef DEBUG +# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_loader_code_ix()) +#else +# define CIX_TRACE(text) +#endif + +void erts_code_ix_init(void) +{ + erts_smp_atomic32_init_nob(&the_active_code_index, 0); + erts_smp_atomic32_init_nob(&the_loader_code_index, 0); + CIX_TRACE("init"); +} +ErtsCodeIndex erts_active_code_ix(void) +{ + return erts_smp_atomic32_read_nob(&the_active_code_index); +} +ErtsCodeIndex erts_loader_code_ix(void) +{ + return erts_smp_atomic32_read_nob(&the_loader_code_index); +} + +/* Lock code_ix (enqueue and suspend until we get it) +*/ +void erts_lock_code_ix(void) +{ +} + +/* Unlock code_ix (resume first waiter) +*/ +void erts_unlock_code_ix(void) +{ +} + +void erts_start_loader_code_ix(void) +{ + beam_catches_start_load(); + /*SVERK and more to come I guess... + : + */ + CIX_TRACE("start"); +} + + +void erts_commit_loader_code_ix(void) +{ + beam_catches_end_load(1); + { + ErtsCodeIndex ix = erts_loader_code_ix(); + erts_smp_atomic32_set_nob(&the_active_code_index, ix); + ix = (ix + 1) % ERTS_NUM_CODE_IX; + erts_smp_atomic32_set_nob(&the_loader_code_index, ix); + } + CIX_TRACE("commit"); +} + +void erts_abort_loader_code_ix(void) +{ + beam_catches_end_load(0); + CIX_TRACE("abort"); +} + +/*SVERK old_code lock should maybe be part of module.c */ +void erts_rwlock_old_code(void) +{ +} +void erts_rwunlock_old_code(void) +{ +} +void erts_rlock_old_code(void) +{ +} +void erts_runlock_old_code(void) +{ +} + +#ifdef ERTS_ENABLE_LOCK_CHECK +int erts_is_old_code_rlocked(void) +{ + return 1; +} +int erts_is_code_ix_locked(void) +{ + return 1; +} +#endif -- cgit v1.2.3 From 90209e4d57dd9b5ff27729b582f02c3d9e383f72 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 17 Jan 2012 12:16:39 +0100 Subject: erts: Multiple export tab's using code_ix Still blocking code loading --- erts/emulator/beam/beam_load.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index f7c8395cb6..7768438dd0 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -812,7 +812,7 @@ erts_finish_loading(LoaderState* stp, Process* c_p, * exported and imported functions. This can't fail. */ - erts_export_consolidate(); + erts_export_consolidate(erts_loader_code_ix()); CHKBLK(ERTS_ALC_T_CODE,stp->code); final_touch(stp); @@ -1294,7 +1294,7 @@ load_import_table(LoaderState* stp) * If the export entry refers to a BIF, get the pointer to * the BIF function. */ - if ((e = erts_find_export_entry(mod, func, arity)) != NULL) { + if ((e = erts_active_export_entry(mod, func, arity)) != NULL) { /*SVERK does it matter which one we use? */ if (e->code[3] == (BeamInstr) em_apply_bif) { stp->import[i].bf = (BifFunction) e->code[4]; if (func == am_load_nif && mod == am_erlang && arity == 2) { @@ -1386,7 +1386,7 @@ read_export_table(LoaderState* stp) static int is_bif(Eterm mod, Eterm func, unsigned arity) { - Export* e = erts_find_export_entry(mod, func, arity); + Export* e = erts_active_export_entry(mod, func, arity); if (e == NULL) { return 0; } @@ -5190,13 +5190,15 @@ exported_from_module(Process* p, /* Process whose heap to use. */ Eterm* hp = NULL; Eterm* hend = NULL; Eterm result = NIL; + ErtsCodeIndex code_ix; if (is_not_atom(mod)) { return THE_NON_VALUE; } - for (i = 0; i < export_list_size(); i++) { - Export* ep = export_list(i); + code_ix = erts_active_code_ix(); + for (i = 0; i < export_list_size(code_ix); i++) { + Export* ep = export_list(i,code_ix); if (ep->code[0] == mod) { Eterm tuple; @@ -6144,6 +6146,7 @@ void erts_unlock_code_ix(void) void erts_start_loader_code_ix(void) { beam_catches_start_load(); + export_start_load(); /*SVERK and more to come I guess... : */ @@ -6154,6 +6157,7 @@ void erts_start_loader_code_ix(void) void erts_commit_loader_code_ix(void) { beam_catches_end_load(1); + export_end_load(1); { ErtsCodeIndex ix = erts_loader_code_ix(); erts_smp_atomic32_set_nob(&the_active_code_index, ix); @@ -6166,6 +6170,7 @@ void erts_commit_loader_code_ix(void) void erts_abort_loader_code_ix(void) { beam_catches_end_load(0); + export_end_load(0); CIX_TRACE("abort"); } -- cgit v1.2.3 From 5ed73504d7409a449ec4e0c0de421a93c4570e3b Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 18 Jan 2012 17:23:52 +0100 Subject: erts: Use several addresses in each Export --- erts/emulator/beam/beam_load.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 7768438dd0..c35841af9d 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -4303,13 +4303,13 @@ final_touch(LoaderState* stp) ep = erts_export_put(stp->module, stp->export[i].function, stp->export[i].arity); if (!on_load) { - ep->address = address; + ep->addressv[erts_loader_code_ix()] = address; } else { /* * Don't make any of the exported functions * callable yet. */ - ep->address = ep->code+3; + ep->addressv[erts_loader_code_ix()] = ep->code+3; ep->code[4] = (BeamInstr) address; } } @@ -5203,7 +5203,7 @@ exported_from_module(Process* p, /* Process whose heap to use. */ if (ep->code[0] == mod) { Eterm tuple; - if (ep->address == ep->code+3 && + if (ep->addressv[code_ix] == ep->code+3 && ep->code[3] == (BeamInstr) em_call_error_handler) { /* There is a call to the function, but it does not exist. */ continue; @@ -5692,7 +5692,7 @@ stub_final_touch(LoaderState* stp, BeamInstr* fp) for (i = 0; i < n; i++) { if (stp->export[i].function == function && stp->export[i].arity == arity) { Export* ep = erts_export_put(mod, function, arity); - ep->address = fp+5; + ep->addressv[erts_loader_code_ix()] = fp+5; return; } } -- cgit v1.2.3 From aac03c5e9ccf9f6066e291a7c87dd58c1181c227 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 19 Jan 2012 12:10:20 +0100 Subject: erts: Multiple module tables using code_ix --- erts/emulator/beam/beam_load.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index c35841af9d..fc3e395e91 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -5027,7 +5027,7 @@ erts_module_info_0(Process* p, Eterm module) return THE_NON_VALUE; } - if (erts_get_module(module) == NULL) { + if (erts_get_module(module, erts_active_code_ix()) == NULL) { return THE_NON_VALUE; } @@ -5091,7 +5091,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */ return THE_NON_VALUE; } - modp = erts_get_module(mod); + modp = erts_get_module(mod, erts_active_code_ix()); if (modp == NULL) { return THE_NON_VALUE; } @@ -5145,7 +5145,7 @@ native_addresses(Process* p, Eterm mod) return THE_NON_VALUE; } - modp = erts_get_module(mod); + modp = erts_get_module(mod, erts_active_code_ix()); if (modp == NULL) { return THE_NON_VALUE; } @@ -5247,7 +5247,7 @@ attributes_for_module(Process* p, /* Process whose heap to use. */ return THE_NON_VALUE; } - modp = erts_get_module(mod); + modp = erts_get_module(mod, erts_active_code_ix()); if (modp == NULL) { return THE_NON_VALUE; } @@ -5287,7 +5287,7 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ return THE_NON_VALUE; } - modp = erts_get_module(mod); + modp = erts_get_module(mod, erts_active_code_ix()); if (modp == NULL) { return THE_NON_VALUE; } @@ -6147,6 +6147,7 @@ void erts_start_loader_code_ix(void) { beam_catches_start_load(); export_start_load(); + module_start_load(); /*SVERK and more to come I guess... : */ @@ -6158,8 +6159,10 @@ void erts_commit_loader_code_ix(void) { beam_catches_end_load(1); export_end_load(1); + module_end_load(1); { - ErtsCodeIndex ix = erts_loader_code_ix(); + ErtsCodeIndex ix; + ix = erts_loader_code_ix(); erts_smp_atomic32_set_nob(&the_active_code_index, ix); ix = (ix + 1) % ERTS_NUM_CODE_IX; erts_smp_atomic32_set_nob(&the_loader_code_index, ix); @@ -6171,20 +6174,21 @@ void erts_abort_loader_code_ix(void) { beam_catches_end_load(0); export_end_load(0); + module_end_load(0); CIX_TRACE("abort"); } /*SVERK old_code lock should maybe be part of module.c */ -void erts_rwlock_old_code(void) +void erts_rwlock_old_code(ErtsCodeIndex code_ix) { } -void erts_rwunlock_old_code(void) +void erts_rwunlock_old_code(ErtsCodeIndex code_ix) { } -void erts_rlock_old_code(void) +void erts_rlock_old_code(ErtsCodeIndex code_ix) { } -void erts_runlock_old_code(void) +void erts_runlock_old_code(ErtsCodeIndex code_ix) { } -- cgit v1.2.3 From dab78e34dac11579cda578ffc6cf9293394456e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 18 Jan 2012 16:44:48 +0100 Subject: BEAM loader: Break out handling of ranges into beam_ranges.c Having the entire implementation of range handling (address table) in one source file will help when we'll need to update the ranges without stopping all schedulers in the next commit. --- erts/emulator/beam/beam_load.c | 167 +---------------------------------------- 1 file changed, 3 insertions(+), 164 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index fc3e395e91..873b94d175 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -352,27 +352,6 @@ typedef struct LoaderState { int loc_size; /* Size of location info in bytes (2/4) */ } LoaderState; -/* - * Layout of the line table. - */ - -#define MI_LINE_FNAME_PTR 0 -#define MI_LINE_LOC_TAB 1 -#define MI_LINE_LOC_SIZE 2 -#define MI_LINE_FUNC_TAB 3 - -#define LINE_INVALID_LOCATION (0) - -/* - * Macros for manipulating locations. - */ - -#define IS_VALID_LOCATION(File, Line) \ - ((unsigned) (File) < 255 && (unsigned) (Line) < ((1 << 24) - 1)) -#define MAKE_LOCATION(File, Line) (((File) << 24) | (Line)) -#define LOC_FILE(Loc) ((Loc) >> 24) -#define LOC_LINE(Loc) ((Loc) & ((1 << 24)-1)) - #define GetTagAndValue(Stp, Tag, Val) \ do { \ BeamInstr __w; \ @@ -549,22 +528,9 @@ static Eterm native_addresses(Process* p, Eterm mod); int patch_funentries(Eterm Patchlist); int patch(Eterm Addresses, Uint fe); static int safe_mul(UWord a, UWord b, UWord* resp); -static void lookup_loc(FunctionInfo* fi, BeamInstr* pc, - BeamInstr* modp, int idx); - static int must_swap_floats; -/* - * The following variables keep a sorted list of address ranges for - * each module. It allows us to quickly find a function given an - * instruction pointer. - */ -Range* modules = NULL; /* Sorted lists of module addresses. */ -int num_loaded_modules; /* Number of loaded modules. */ -int allocated_modules; /* Number of slots allocated. */ -Range* mid_module = NULL; /* Cached search start point */ - Uint erts_total_code_size; /**********************************************************************/ @@ -580,11 +546,7 @@ void init_load(void) f.fd = 1.0; must_swap_floats = (f.fw[0] == 0); - allocated_modules = 128; - modules = (Range *) erts_alloc(ERTS_ALC_T_MODULE_REFS, - allocated_modules*sizeof(Range)); - mid_module = modules; - num_loaded_modules = 0; + erts_init_ranges(); } static void @@ -955,7 +917,6 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, { Module* modp; Eterm retval; - int i; if ((retval = beam_make_current_old(c_p, c_p_locks, module)) != NIL) { erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); @@ -977,25 +938,10 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, modp->curr.catches = BEAM_CATCHES_NIL; /* Will be filled in later. */ /* - * Update address table (used for finding a function from a PC value). + * Update ranges (used for finding a function from a PC value). */ - if (num_loaded_modules == allocated_modules) { - allocated_modules *= 2; - modules = (Range *) erts_realloc(ERTS_ALC_T_MODULE_REFS, - (void *) modules, - allocated_modules * sizeof(Range)); - } - for (i = num_loaded_modules; i > 0; i--) { - if (code > modules[i-1].start) { - break; - } - modules[i] = modules[i-1]; - } - modules[i].start = code; - modules[i].end = (BeamInstr *) (((byte *)code) + size); - num_loaded_modules++; - mid_module = &modules[num_loaded_modules/2]; + erts_update_ranges(code, size); return NIL; } @@ -5305,113 +5251,6 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */ return result; } -/* - * Find a function from the given pc and fill information in - * the FunctionInfo struct. If the full_info is non-zero, fill - * in all available information (including location in the - * source code). If no function is found, the 'current' field - * will be set to NULL. - */ - -void -erts_lookup_function_info(FunctionInfo* fi, BeamInstr* pc, int full_info) -{ - Range* low = modules; - Range* high = low + num_loaded_modules; - Range* mid = mid_module; - - fi->current = NULL; - fi->needed = 5; - fi->loc = LINE_INVALID_LOCATION; - while (low < high) { - if (pc < mid->start) { - high = mid; - } else if (pc > mid->end) { - low = mid + 1; - } else { - BeamInstr** low1 = (BeamInstr **) (mid->start + MI_FUNCTIONS); - BeamInstr** high1 = low1 + mid->start[MI_NUM_FUNCTIONS]; - BeamInstr** mid1; - - while (low1 < high1) { - mid1 = low1 + (high1-low1) / 2; - if (pc < mid1[0]) { - high1 = mid1; - } else if (pc < mid1[1]) { - mid_module = mid; - fi->current = mid1[0]+2; - if (full_info) { - BeamInstr** fp = (BeamInstr **) (mid->start + - MI_FUNCTIONS); - int idx = mid1 - fp; - lookup_loc(fi, pc, mid->start, idx); - } - return; - } else { - low1 = mid1 + 1; - } - } - return; - } - mid = low + (high-low) / 2; - } -} - -static void -lookup_loc(FunctionInfo* fi, BeamInstr* orig_pc, BeamInstr* modp, int idx) -{ - Eterm* line = (Eterm *) modp[MI_LINE_TABLE]; - Eterm* low; - Eterm* high; - Eterm* mid; - Eterm pc; - - if (line == 0) { - return; - } - - pc = (Eterm) (BeamInstr) orig_pc; - fi->fname_ptr = (Eterm *) (BeamInstr) line[MI_LINE_FNAME_PTR]; - low = (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB+idx]; - high = (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB+idx+1]; - while (high > low) { - mid = low + (high-low) / 2; - if (pc < mid[0]) { - high = mid; - } else if (pc < mid[1]) { - int file; - int index = mid - (Eterm *) (BeamInstr) line[MI_LINE_FUNC_TAB]; - - if (line[MI_LINE_LOC_SIZE] == 2) { - Uint16* loc_table = - (Uint16 *) (BeamInstr) line[MI_LINE_LOC_TAB]; - fi->loc = loc_table[index]; - } else { - Uint32* loc_table = - (Uint32 *) (BeamInstr) line[MI_LINE_LOC_TAB]; - ASSERT(line[MI_LINE_LOC_SIZE] == 4); - fi->loc = loc_table[index]; - } - if (fi->loc == LINE_INVALID_LOCATION) { - return; - } - fi->needed += 3+2+3+2; - file = LOC_FILE(fi->loc); - if (file == 0) { - /* Special case: Module name with ".erl" appended */ - Atom* mod_atom = atom_tab(atom_val(fi->current[0])); - fi->needed += 2*(mod_atom->len+4); - } else { - Atom* ap = atom_tab(atom_val((fi->fname_ptr)[file-1])); - fi->needed += 2*ap->len; - } - return; - } else { - low = mid + 1; - } - } -} - /* * Build a single {M,F,A,Loction} item to be part of * a stack trace. -- cgit v1.2.3 From f81dd5da827e86af3bf6fedadeaaeb5fb3347c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 19 Jan 2012 11:00:01 +0100 Subject: beam_ranges: Make ranges safe with multi-scheduling active --- erts/emulator/beam/beam_load.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 873b94d175..6cabc6f558 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -5987,9 +5987,7 @@ void erts_start_loader_code_ix(void) beam_catches_start_load(); export_start_load(); module_start_load(); - /*SVERK and more to come I guess... - : - */ + erts_start_load_ranges(); CIX_TRACE("start"); } @@ -5999,6 +5997,7 @@ void erts_commit_loader_code_ix(void) beam_catches_end_load(1); export_end_load(1); module_end_load(1); + erts_end_load_ranges(1); { ErtsCodeIndex ix; ix = erts_loader_code_ix(); @@ -6014,6 +6013,7 @@ void erts_abort_loader_code_ix(void) beam_catches_end_load(0); export_end_load(0); module_end_load(0); + erts_end_load_ranges(0); CIX_TRACE("abort"); } -- cgit v1.2.3 From dd3036c1a152c66a33b4d298cbbf428c075153b7 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 19 Jan 2012 21:16:29 +0100 Subject: First try at non-blocking code loading! Implemented some code_ix locks and commented calls to erts_smp_thr_progress_block() --- erts/emulator/beam/beam_load.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 6cabc6f558..eaaef472b4 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -753,7 +753,7 @@ erts_finish_loading(LoaderState* stp, Process* c_p, * table which is not protected by any locks. */ - ERTS_SMP_LC_ASSERT(erts_initialized == 0 || + ERTS_SMP_LC_ASSERT(erts_initialized == 0 || erts_is_code_ix_locked() || erts_smp_thr_progress_is_blocking()); /* @@ -5949,6 +5949,9 @@ static int safe_mul(UWord a, UWord b, UWord* resp) static erts_smp_atomic32_t the_active_code_index; static erts_smp_atomic32_t the_loader_code_index; +static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ +static erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; + #ifdef DEBUG # define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_loader_code_ix()) #else @@ -5957,8 +5960,14 @@ static erts_smp_atomic32_t the_loader_code_index; void erts_code_ix_init(void) { + int i; + erts_smp_atomic32_init_nob(&the_active_code_index, 0); erts_smp_atomic32_init_nob(&the_loader_code_index, 0); + erts_smp_mtx_init_x(&sverk_code_ix_lock, "sverk_code_ix_lock", NIL); /*SVERK FIXME */ + for (i=0; i Date: Fri, 20 Jan 2012 17:39:14 +0100 Subject: erts: Call erts_export_consolidate automatically Renamed merge_secondary_table and called by export_start_load --- erts/emulator/beam/beam_load.c | 1 - 1 file changed, 1 deletion(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index eaaef472b4..e2a3914bf7 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -774,7 +774,6 @@ erts_finish_loading(LoaderState* stp, Process* c_p, * exported and imported functions. This can't fail. */ - erts_export_consolidate(erts_loader_code_ix()); CHKBLK(ERTS_ALC_T_CODE,stp->code); final_touch(stp); -- cgit v1.2.3 From 28a1a227f8097c5c593149f66a98a1b1cf796e99 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 20 Jan 2012 17:42:50 +0100 Subject: erts: Rename erts_load_module to erts_preload_module As it can only be used at initialization for preloading --- erts/emulator/beam/beam_load.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index e2a3914bf7..54dc663abe 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -558,7 +558,7 @@ define_file(LoaderState* stp, char* name, int idx) } Eterm -erts_load_module(Process *c_p, +erts_preload_module(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, /* Group leader or NIL if none. */ Eterm* modp, /* @@ -571,6 +571,7 @@ erts_load_module(Process *c_p, LoaderState* stp = erts_alloc_loader_state(); Eterm retval; + ASSERT(!erts_initialized); retval = erts_prepare_loading(stp, c_p, group_leader, modp, code, size); if (retval != NIL) { -- cgit v1.2.3 From a4cb5739b9f3dd88582fdea7a00cbba721fea35d Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 23 Jan 2012 16:48:28 +0100 Subject: erts: Remove secondary_export_table --- erts/emulator/beam/beam_load.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 54dc663abe..cc4bdea20e 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -6018,10 +6018,12 @@ void erts_commit_loader_code_ix(void) erts_end_load_ranges(1); { ErtsCodeIndex ix; + export_write_lock(); ix = erts_loader_code_ix(); erts_smp_atomic32_set_nob(&the_active_code_index, ix); ix = (ix + 1) % ERTS_NUM_CODE_IX; erts_smp_atomic32_set_nob(&the_loader_code_index, ix); + export_write_unlock(); } CIX_TRACE("commit"); } -- cgit v1.2.3 From a23f25a3014dbad01d2016dc4e6d6df9d59ba64c Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 24 Jan 2012 15:42:02 +0100 Subject: erts: Rename "loader" code_ix as "staging" code_ix Staging is a better and more general name as does not necessary need to involve code loading (can be deletion, tracing, etc). --- erts/emulator/beam/beam_load.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index cc4bdea20e..d393ff6a34 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -4249,13 +4249,13 @@ final_touch(LoaderState* stp) ep = erts_export_put(stp->module, stp->export[i].function, stp->export[i].arity); if (!on_load) { - ep->addressv[erts_loader_code_ix()] = address; + ep->addressv[erts_staging_code_ix()] = address; } else { /* * Don't make any of the exported functions * callable yet. */ - ep->addressv[erts_loader_code_ix()] = ep->code+3; + ep->addressv[erts_staging_code_ix()] = ep->code+3; ep->code[4] = (BeamInstr) address; } } @@ -5531,7 +5531,7 @@ stub_final_touch(LoaderState* stp, BeamInstr* fp) for (i = 0; i < n; i++) { if (stp->export[i].function == function && stp->export[i].arity == arity) { Export* ep = erts_export_put(mod, function, arity); - ep->addressv[erts_loader_code_ix()] = fp+5; + ep->addressv[erts_staging_code_ix()] = fp+5; return; } } @@ -5953,7 +5953,7 @@ static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ static erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; #ifdef DEBUG -# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_loader_code_ix()) +# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_staging_code_ix()) #else # define CIX_TRACE(text) #endif @@ -5974,7 +5974,7 @@ ErtsCodeIndex erts_active_code_ix(void) { return erts_smp_atomic32_read_nob(&the_active_code_index); } -ErtsCodeIndex erts_loader_code_ix(void) +ErtsCodeIndex erts_staging_code_ix(void) { return erts_smp_atomic32_read_nob(&the_loader_code_index); } @@ -6000,26 +6000,26 @@ int erts_is_code_ix_locked(void) } #endif -void erts_start_loader_code_ix(void) +void erts_start_staging_code_ix(void) { - beam_catches_start_load(); - export_start_load(); - module_start_load(); - erts_start_load_ranges(); + beam_catches_start_staging(); + export_start_staging(); + module_start_staging(); + erts_start_staging_ranges(); CIX_TRACE("start"); } -void erts_commit_loader_code_ix(void) +void erts_commit_staging_code_ix(void) { - beam_catches_end_load(1); - export_end_load(1); - module_end_load(1); - erts_end_load_ranges(1); + beam_catches_end_staging(1); + export_end_staging(1); + module_end_staging(1); + erts_end_staging_ranges(1); { ErtsCodeIndex ix; export_write_lock(); - ix = erts_loader_code_ix(); + ix = erts_staging_code_ix(); erts_smp_atomic32_set_nob(&the_active_code_index, ix); ix = (ix + 1) % ERTS_NUM_CODE_IX; erts_smp_atomic32_set_nob(&the_loader_code_index, ix); @@ -6028,12 +6028,12 @@ void erts_commit_loader_code_ix(void) CIX_TRACE("commit"); } -void erts_abort_loader_code_ix(void) +void erts_abort_staging_code_ix(void) { - beam_catches_end_load(0); - export_end_load(0); - module_end_load(0); - erts_end_load_ranges(0); + beam_catches_end_staging(0); + export_end_staging(0); + module_end_staging(0); + erts_end_staging_ranges(0); CIX_TRACE("abort"); } -- cgit v1.2.3 From 88c771c1d69c98169ef9bc10c27ed4378854d368 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 24 Jan 2012 17:08:40 +0100 Subject: erts: Cleanup code loading --- erts/emulator/beam/beam_load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index d393ff6a34..4ac426fc9e 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -1240,7 +1240,7 @@ load_import_table(LoaderState* stp) * If the export entry refers to a BIF, get the pointer to * the BIF function. */ - if ((e = erts_active_export_entry(mod, func, arity)) != NULL) { /*SVERK does it matter which one we use? */ + if ((e = erts_active_export_entry(mod, func, arity)) != NULL) { if (e->code[3] == (BeamInstr) em_apply_bif) { stp->import[i].bf = (BifFunction) e->code[4]; if (func == am_load_nif && mod == am_erlang && arity == 2) { @@ -5952,7 +5952,7 @@ static erts_smp_atomic32_t the_loader_code_index; static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ static erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; -#ifdef DEBUG +#if 0 # define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_staging_code_ix()) #else # define CIX_TRACE(text) -- cgit v1.2.3 From e60c9cd4356a91c10657b5de86af8279ccd6eb79 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 26 Jan 2012 16:25:26 +0100 Subject: erts: Move number-of-breakpoint counter from code to Module struct The is a refactoring in preparation to add a counter in Module struct for export entry tracing. It is nicer if the two are kept together. --- erts/emulator/beam/beam_load.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 4ac426fc9e..e966f423ec 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -643,8 +643,6 @@ erts_prepare_loading(LoaderState* stp, Process *c_p, Eterm group_leader, stp->code[MI_COMPILE_PTR] = 0; stp->code[MI_COMPILE_SIZE] = 0; stp->code[MI_COMPILE_SIZE_ON_HEAP] = 0; - stp->code[MI_NUM_BREAKPOINTS] = 0; - /* * Read the atom table. @@ -5811,7 +5809,6 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) code[MI_COMPILE_PTR] = 0; code[MI_COMPILE_SIZE] = 0; code[MI_COMPILE_SIZE_ON_HEAP] = 0; - code[MI_NUM_BREAKPOINTS] = 0; code[MI_LITERALS_START] = 0; code[MI_LITERALS_END] = 0; code[MI_LITERALS_OFF_HEAP] = 0; -- cgit v1.2.3 From 7cb4725bcf18f3158e60750ea658e51ab4586e31 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 31 Jan 2012 14:24:40 +0100 Subject: erts: Refactor code_ix Move implementation from beam_load into new file code_ix.c and module.c and make some function inline. --- erts/emulator/beam/beam_load.c | 119 ----------------------------------------- 1 file changed, 119 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index e966f423ec..7ac2b9f77e 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -5940,122 +5940,3 @@ static int safe_mul(UWord a, UWord b, UWord* resp) } } - -/*SVERK Do these deserve a file of their own maybe? */ - -static erts_smp_atomic32_t the_active_code_index; -static erts_smp_atomic32_t the_loader_code_index; - -static erts_smp_mtx_t sverk_code_ix_lock; /*SVERK FIXME */ -static erts_smp_rwmtx_t the_old_code_rwlocks[ERTS_NUM_CODE_IX]; - -#if 0 -# define CIX_TRACE(text) erts_fprintf(stderr, "CIX_TRACE: " text " act=%u load=%u\r\n", erts_active_code_ix(), erts_staging_code_ix()) -#else -# define CIX_TRACE(text) -#endif - -void erts_code_ix_init(void) -{ - int i; - - erts_smp_atomic32_init_nob(&the_active_code_index, 0); - erts_smp_atomic32_init_nob(&the_loader_code_index, 0); - erts_smp_mtx_init_x(&sverk_code_ix_lock, "sverk_code_ix_lock", NIL); /*SVERK FIXME */ - for (i=0; i Date: Thu, 12 Jan 2012 15:21:18 +0100 Subject: Use magic binaries in erts_prepare_loading() and erts_finish_loading() --- erts/emulator/beam/beam_load.c | 194 ++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 70 deletions(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 7ac2b9f77e..a9246a84c1 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -475,7 +475,8 @@ typedef struct LoaderState { } while (0) -static void free_state(LoaderState* stp); +static void free_loader_state(Binary* magic); +static void loader_state_dtor(Binary* magic); static Eterm insert_new_code(Process *c_p, ErtsProcLocks c_p_locks, Eterm group_leader, Eterm module, BeamInstr* code, Uint size); @@ -568,16 +569,16 @@ erts_preload_module(Process *c_p, byte* code, /* Points to the code to load */ Uint size) /* Size of code to load. */ { - LoaderState* stp = erts_alloc_loader_state(); + Binary* magic = erts_alloc_loader_state(); Eterm retval; ASSERT(!erts_initialized); - retval = erts_prepare_loading(stp, c_p, group_leader, modp, + retval = erts_prepare_loading(magic, c_p, group_leader, modp, code, size); if (retval != NIL) { return retval; } - return erts_finish_loading(stp, c_p, c_p_locks, modp); + return erts_finish_loading(magic, c_p, c_p_locks, modp); } /* #define LOAD_MEMORY_HARD_DEBUG 1*/ @@ -593,11 +594,13 @@ extern void check_allocated_block(Uint type, void *blk); #endif Eterm -erts_prepare_loading(LoaderState* stp, Process *c_p, Eterm group_leader, +erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader, Eterm* modp, byte* code, Uint unloaded_size) { Eterm retval = am_badfile; + LoaderState* stp; + stp = ERTS_MAGIC_BIN_DATA(magic); stp->module = *modp; stp->group_leader = group_leader; @@ -736,16 +739,17 @@ erts_prepare_loading(LoaderState* stp, Process *c_p, Eterm group_leader, load_error: if (retval != NIL) { - free_state(stp); + free_loader_state(magic); } return retval; } Eterm -erts_finish_loading(LoaderState* stp, Process* c_p, +erts_finish_loading(Binary* magic, Process* c_p, ErtsProcLocks c_p_locks, Eterm* modp) { Eterm retval; + LoaderState* stp = ERTS_MAGIC_BIN_DATA(magic); /* * No other process may run since we will update the export @@ -798,16 +802,20 @@ erts_finish_loading(LoaderState* stp, Process* c_p, } load_error: - free_state(stp); + free_loader_state(magic); return retval; } -LoaderState* +Binary* erts_alloc_loader_state(void) { LoaderState* stp; + Binary* magic; - stp = erts_alloc(ERTS_ALC_T_LOADER_TMP, sizeof(LoaderState)); + magic = erts_create_magic_binary(sizeof(LoaderState), + loader_state_dtor); + erts_refc_inc(&magic->refc, 1); + stp = ERTS_MAGIC_BIN_DATA(magic); stp->bin = NULL; stp->function = THE_NON_VALUE; /* Function not known yet */ stp->arity = 0; @@ -836,76 +844,102 @@ erts_alloc_loader_state(void) stp->line_instr = 0; stp->func_line = 0; stp->fname = 0; - return stp; + return magic; +} + +static void +free_loader_state(Binary* magic) +{ + loader_state_dtor(magic); + if (erts_refc_dectest(&magic->refc, 0) == 0) { + erts_bin_free(magic); + } } +/* + * This destructor function can safely be called multiple times. + */ static void -free_state(LoaderState* stp) +loader_state_dtor(Binary* magic) { + LoaderState* stp = ERTS_MAGIC_BIN_DATA(magic); + if (stp->bin != 0) { driver_free_binary(stp->bin); + stp->bin = 0; } if (stp->code != 0) { erts_free(ERTS_ALC_T_CODE, stp->code); + stp->code = 0; } - if (stp->labels != NULL) { - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->labels); + if (stp->labels != 0) { + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->labels); + stp->labels = 0; } - if (stp->atom != NULL) { - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->atom); + if (stp->atom != 0) { + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->atom); + stp->atom = 0; } - if (stp->import != NULL) { - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->import); + if (stp->import != 0) { + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->import); + stp->import = 0; } - if (stp->export != NULL) { - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->export); + if (stp->export != 0) { + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->export); + stp->export = 0; } if (stp->lambdas != stp->def_lambdas) { - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->lambdas); + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->lambdas); + stp->lambdas = stp->def_lambdas; } - if (stp->literals != NULL) { + if (stp->literals != 0) { int i; for (i = 0; i < stp->num_literals; i++) { - if (stp->literals[i].heap != NULL) { - erts_free(ERTS_ALC_T_LOADER_TMP, + if (stp->literals[i].heap != 0) { + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->literals[i].heap); + stp->literals[i].heap = 0; } } - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->literals); + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->literals); + stp->literals = 0; } - while (stp->literal_patches != NULL) { + while (stp->literal_patches != 0) { LiteralPatch* next = stp->literal_patches->next; - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->literal_patches); + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->literal_patches); stp->literal_patches = next; } - while (stp->string_patches != NULL) { + while (stp->string_patches != 0) { StringPatch* next = stp->string_patches->next; - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->string_patches); + erts_free(ERTS_ALC_T_PREPARED_CODE, (void *) stp->string_patches); stp->string_patches = next; } - while (stp->genop_blocks) { - GenOpBlock* next = stp->genop_blocks->next; - erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->genop_blocks); - stp->genop_blocks = next; - } if (stp->line_item != 0) { - erts_free(ERTS_ALC_T_LOADER_TMP, stp->line_item); + erts_free(ERTS_ALC_T_PREPARED_CODE, stp->line_item); + stp->line_item = 0; } if (stp->line_instr != 0) { - erts_free(ERTS_ALC_T_LOADER_TMP, stp->line_instr); + erts_free(ERTS_ALC_T_PREPARED_CODE, stp->line_instr); + stp->line_instr = 0; } if (stp->func_line != 0) { - erts_free(ERTS_ALC_T_LOADER_TMP, stp->func_line); + erts_free(ERTS_ALC_T_PREPARED_CODE, stp->func_line); + stp->func_line = 0; } if (stp->fname != 0) { - erts_free(ERTS_ALC_T_LOADER_TMP, stp->fname); + erts_free(ERTS_ALC_T_PREPARED_CODE, stp->fname); + stp->fname = 0; } - erts_free(ERTS_ALC_T_LOADER_TMP, stp); + /* + * The following data items should have been freed earlier. + */ + + ASSERT(stp->genop_blocks == 0); } static Eterm @@ -1162,7 +1196,7 @@ load_atom_table(LoaderState* stp) GetInt(stp, 4, stp->num_atoms); stp->num_atoms++; - stp->atom = erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->atom = erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_atoms*sizeof(Eterm)); /* @@ -1207,7 +1241,7 @@ load_import_table(LoaderState* stp) int i; GetInt(stp, 4, stp->num_imports); - stp->import = erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->import = erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_imports * sizeof(ImportEntry)); for (i = 0; i < stp->num_imports; i++) { int n; @@ -1266,7 +1300,7 @@ read_export_table(LoaderState* stp) stp->num_exps, stp->num_functions); } stp->export - = (ExportEntry *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + = (ExportEntry *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, (stp->num_exps * sizeof(ExportEntry))); for (i = 0; i < stp->num_exps; i++) { @@ -1356,7 +1390,7 @@ read_lambda_table(LoaderState* stp) if (stp->num_lambdas > stp->lambdas_allocated) { ASSERT(stp->lambdas == stp->def_lambdas); stp->lambdas_allocated = stp->num_lambdas; - stp->lambdas = (Lambda *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->lambdas = (Lambda *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_lambdas * sizeof(Lambda)); } for (i = 0; i < stp->num_lambdas; i++) { @@ -1408,7 +1442,7 @@ read_literal_table(LoaderState* stp) stp->file_p = uncompressed; stp->file_left = (unsigned) uncompressed_sz; GetInt(stp, 4, stp->num_literals); - stp->literals = (Literal *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->literals = (Literal *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_literals * sizeof(Literal)); stp->allocated_literals = stp->num_literals; @@ -1428,7 +1462,7 @@ read_literal_table(LoaderState* stp) if ((heap_size = erts_decode_ext_size(p, sz)) < 0) { LoadError1(stp, "literal %d: bad external format", i); } - hp = stp->literals[i].heap = erts_alloc(ERTS_ALC_T_LOADER_TMP, + hp = stp->literals[i].heap = erts_alloc(ERTS_ALC_T_PREPARED_CODE, heap_size*sizeof(Eterm)); stp->literals[i].off_heap.first = 0; stp->literals[i].off_heap.overhead = 0; @@ -1500,7 +1534,7 @@ read_line_table(LoaderState* stp) */ num_line_items++; - lp = (BeamInstr *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + lp = (BeamInstr *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, num_line_items * sizeof(BeamInstr)); stp->line_item = lp; stp->num_line_items = num_line_items; @@ -1556,7 +1590,7 @@ read_line_table(LoaderState* stp) */ if (stp->num_fnames != 0) { - stp->fname = (Eterm *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->fname = (Eterm *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_fnames * sizeof(Eterm)); for (i = 0; i < stp->num_fnames; i++) { @@ -1572,11 +1606,11 @@ read_line_table(LoaderState* stp) /* * Allocate the arrays to be filled while code is being loaded. */ - stp->line_instr = (LineInstr *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->line_instr = (LineInstr *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_line_instrs * sizeof(LineInstr)); stp->current_li = 0; - stp->func_line = (int *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->func_line = (int *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_functions * sizeof(int)); @@ -1639,7 +1673,7 @@ read_code_header(LoaderState* stp) * Initialize label table. */ - stp->labels = (Label *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->labels = (Label *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_labels * sizeof(Label)); for (i = 0; i < stp->num_labels; i++) { stp->labels[i].value = 0; @@ -1693,6 +1727,7 @@ load_code(LoaderState* stp) GenOp* last_op = NULL; GenOp** last_op_next = NULL; int arity; + int retval = 1; /* * The size of the loaded func_info instruction is needed @@ -2422,7 +2457,8 @@ load_code(LoaderState* stp) stp->function = THE_NON_VALUE; stp->genop = NULL; stp->specific_op = -1; - return 1; + retval = 1; + goto cleanup; } /* @@ -2436,9 +2472,20 @@ load_code(LoaderState* stp) } } - load_error: - return 0; + retval = 0; + + cleanup: + /* + * Clean up everything that is not needed any longer. + */ + + while (stp->genop_blocks) { + GenOpBlock* next = stp->genop_blocks->next; + erts_free(ERTS_ALC_T_LOADER_TMP, (void *) stp->genop_blocks); + stp->genop_blocks = next; + } + return retval; } @@ -4898,7 +4945,7 @@ new_label(LoaderState* stp) int num = stp->num_labels; stp->num_labels++; - stp->labels = (Label *) erts_realloc(ERTS_ALC_T_LOADER_TMP, + stp->labels = (Label *) erts_realloc(ERTS_ALC_T_PREPARED_CODE, (void *) stp->labels, stp->num_labels * sizeof(Label)); stp->labels[num].value = 0; @@ -4909,7 +4956,8 @@ new_label(LoaderState* stp) static void new_literal_patch(LoaderState* stp, int pos) { - LiteralPatch* p = erts_alloc(ERTS_ALC_T_LOADER_TMP, sizeof(LiteralPatch)); + LiteralPatch* p = erts_alloc(ERTS_ALC_T_PREPARED_CODE, + sizeof(LiteralPatch)); p->pos = pos; p->next = stp->literal_patches; stp->literal_patches = p; @@ -4918,7 +4966,7 @@ new_literal_patch(LoaderState* stp, int pos) static void new_string_patch(LoaderState* stp, int pos) { - StringPatch* p = erts_alloc(ERTS_ALC_T_LOADER_TMP, sizeof(StringPatch)); + StringPatch* p = erts_alloc(ERTS_ALC_T_PREPARED_CODE, sizeof(StringPatch)); p->pos = pos; p->next = stp->string_patches; stp->string_patches = p; @@ -4936,14 +4984,14 @@ new_literal(LoaderState* stp, Eterm** hpp, Uint heap_size) ASSERT(stp->num_literals == 0); stp->allocated_literals = 8; need = stp->allocated_literals * sizeof(Literal); - stp->literals = (Literal *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + stp->literals = (Literal *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, need); } else if (stp->allocated_literals <= stp->num_literals) { Uint need; stp->allocated_literals *= 2; need = stp->allocated_literals * sizeof(Literal); - stp->literals = (Literal *) erts_realloc(ERTS_ALC_T_LOADER_TMP, + stp->literals = (Literal *) erts_realloc(ERTS_ALC_T_PREPARED_CODE, (void *) stp->literals, need); } @@ -4952,7 +5000,7 @@ new_literal(LoaderState* stp, Eterm** hpp, Uint heap_size) lit = stp->literals + stp->num_literals; lit->offset = 0; lit->heap_size = heap_size; - lit->heap = erts_alloc(ERTS_ALC_T_LOADER_TMP, heap_size*sizeof(Eterm)); + lit->heap = erts_alloc(ERTS_ALC_T_PREPARED_CODE, heap_size*sizeof(Eterm)); lit->term = make_boxed(lit->heap); lit->off_heap.first = 0; lit->off_heap.overhead = 0; @@ -5329,6 +5377,7 @@ code_get_chunk_2(BIF_ALIST_2) Process* p = BIF_P; Eterm Bin = BIF_ARG_1; Eterm Chunk = BIF_ARG_2; + Binary* magic = 0; LoaderState* stp; Uint chunk = 0; ErlSubBin* sb; @@ -5341,12 +5390,13 @@ code_get_chunk_2(BIF_ALIST_2) Eterm real_bin; byte* temp_alloc = NULL; - stp = erts_alloc_loader_state(); + magic = erts_alloc_loader_state(); + stp = ERTS_MAGIC_BIN_DATA(magic); if ((start = erts_get_aligned_binary_bytes(Bin, &temp_alloc)) == NULL) { error: erts_free_aligned_binary_bytes(temp_alloc); - if (stp) { - free_state(stp); + if (magic) { + free_loader_state(magic); } BIF_ERROR(p, BADARG); } @@ -5391,7 +5441,7 @@ code_get_chunk_2(BIF_ALIST_2) done: erts_free_aligned_binary_bytes(temp_alloc); - free_state(stp); + free_loader_state(magic); return res; } @@ -5404,14 +5454,16 @@ code_module_md5_1(BIF_ALIST_1) { Process* p = BIF_P; Eterm Bin = BIF_ARG_1; + Binary* magic; LoaderState* stp; byte* bytes; byte* temp_alloc = NULL; Eterm res; - stp = erts_alloc_loader_state(); + magic = erts_alloc_loader_state(); + stp = ERTS_MAGIC_BIN_DATA(magic); if ((bytes = erts_get_aligned_binary_bytes(Bin, &temp_alloc)) == NULL) { - free_state(stp); + free_loader_state(magic); BIF_ERROR(p, BADARG); } stp->module = THE_NON_VALUE; /* Suppress diagnostiscs */ @@ -5425,7 +5477,7 @@ code_module_md5_1(BIF_ALIST_1) done: erts_free_aligned_binary_bytes(temp_alloc); - free_state(stp); + free_loader_state(magic); return res; } @@ -5481,7 +5533,7 @@ stub_read_export_table(LoaderState* stp) stp->num_exps, stp->num_functions); } stp->export - = (ExportEntry *) erts_alloc(ERTS_ALC_T_LOADER_TMP, + = (ExportEntry *) erts_alloc(ERTS_ALC_T_PREPARED_CODE, stp->num_exps * sizeof(ExportEntry)); for (i = 0; i < stp->num_exps; i++) { @@ -5708,6 +5760,7 @@ patch_funentries(Eterm Patchlist) Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) { + Binary* magic; LoaderState* stp; BeamInstr Funcs; BeamInstr Patchlist; @@ -5729,7 +5782,8 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) * Must initialize stp->lambdas here because the error handling code * at label 'error' uses it. */ - stp = erts_alloc_loader_state(); + magic = erts_alloc_loader_state(); + stp = ERTS_MAGIC_BIN_DATA(magic); if (is_not_atom(Mod)) { goto error; @@ -5916,13 +5970,13 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info) if (patch_funentries(Patchlist)) { erts_free_aligned_binary_bytes(temp_alloc); - free_state(stp); + free_loader_state(magic); return Mod; } error: erts_free_aligned_binary_bytes(temp_alloc); - free_state(stp); + free_loader_state(magic); BIF_ERROR(p, BADARG); } -- cgit v1.2.3 From 64bcf5db63d73fe09298dac8cf5f6cad33fe7253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 12 Jan 2012 20:12:59 +0100 Subject: Break apart erlang:load_module/2 into two separate BIFs Introduce two new BIFs, erlang:prepare_loading/2 and erlang:finish_loading/1, and re-implement erlang:load_module/2 in Erlang code. We have two reasons for doing this: * To facilitate suspending a process if another process is already doing code loading. * In the future, we can implement parallel and atomic loading of several modules. Atomic loading works except for modules with on_load handlers. Because of that issue, erlang:finish_loading/2 will currently only accept a list with a single magic binary. --- erts/emulator/beam/beam_load.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index a9246a84c1..cc4f5b5893 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -847,6 +847,27 @@ erts_alloc_loader_state(void) return magic; } +/* + * Return the module name (a tagged atom) for the prepared code + * in the magic binary, or NIL if the binary does not contain + * prepared code. + */ +int +erts_module_for_prepared_code(Binary* magic) +{ + LoaderState* stp; + + if (ERTS_MAGIC_BIN_DESTRUCTOR(magic) != loader_state_dtor) { + return NIL; + } + stp = ERTS_MAGIC_BIN_DATA(magic); + if (stp->code != 0) { + return stp->module; + } else { + return NIL; + } +} + static void free_loader_state(Binary* magic) { -- cgit v1.2.3 From 7985815fc4c25c6bfc5d6101cd862138060098b9 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 9 Feb 2012 14:40:12 +0100 Subject: erts: Fix type bug --- erts/emulator/beam/beam_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'erts/emulator/beam/beam_load.c') diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index cc4f5b5893..d3f55a2ba4 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -852,7 +852,7 @@ erts_alloc_loader_state(void) * in the magic binary, or NIL if the binary does not contain * prepared code. */ -int +Eterm erts_module_for_prepared_code(Binary* magic) { LoaderState* stp; -- cgit v1.2.3