diff options
Diffstat (limited to 'erts/emulator/beam/module.c')
-rw-r--r-- | erts/emulator/beam/module.c | 109 |
1 files changed, 94 insertions, 15 deletions
diff --git a/erts/emulator/beam/module.c b/erts/emulator/beam/module.c index 39baabdf54..1c629cd614 100644 --- a/erts/emulator/beam/module.c +++ b/erts/emulator/beam/module.c @@ -26,10 +26,16 @@ #include "global.h" #include "module.h" +#ifdef DEBUG +# define IF_DEBUG(x) x +#else +# define IF_DEBUG(x) +#endif + #define MODULE_SIZE 50 #define MODULE_LIMIT (64*1024) -static IndexTable module_table; +static IndexTable module_tables[ERTS_NUM_CODE_IX]; /* * SMP note: We don't need to look accesses to the module table because @@ -40,7 +46,7 @@ static IndexTable module_table; void module_info(int to, void *to_arg) { - index_info(to, to_arg, &module_table); + index_info(to, to_arg, &module_tables[erts_active_code_ix()]); } @@ -71,33 +77,44 @@ static Module* module_alloc(Module* tmpl) return obj; } +static void module_free(Module* mod) +{ + erts_free(ERTS_ALC_T_MODULE, mod); +} void init_module_table(void) { HashFunctions f; + int i; f.hash = (H_FUN) module_hash; f.cmp = (HCMP_FUN) module_cmp; f.alloc = (HALLOC_FUN) module_alloc; - f.free = 0; + f.free = (HFREE_FUN) module_free; - erts_index_init(ERTS_ALC_T_MODULE_TABLE, &module_table, "module_code", - MODULE_SIZE, MODULE_LIMIT, f); + for (i = 0; i < ERTS_NUM_CODE_IX; i++) { + erts_index_init(ERTS_ALC_T_MODULE_TABLE, &module_tables[i], "module_code", + MODULE_SIZE, MODULE_LIMIT, f); + } } Module* -erts_get_module(Eterm mod) +erts_get_module(Eterm mod, ErtsCodeIndex code_ix) { Module e; int index; + IndexTable* mod_tab; ASSERT(is_atom(mod)); + + mod_tab = &module_tables[code_ix]; + e.module = atom_val(mod); - index = index_get(&module_table, (void*) &e); + index = index_get(mod_tab, (void*) &e); if (index == -1) { return NULL; } else { - return (Module*) erts_index_lookup(&module_table, index); + return (Module*) erts_index_lookup(mod_tab, index); } } @@ -106,26 +123,88 @@ erts_put_module(Eterm mod) { Module e; int index; + IndexTable* mod_tab; ASSERT(is_atom(mod)); ERTS_SMP_LC_ASSERT(erts_initialized == 0 || erts_smp_thr_progress_is_blocking()); + + mod_tab = &module_tables[erts_loader_code_ix()]; e.module = atom_val(mod); - index = index_put(&module_table, (void*) &e); - return (Module*) erts_index_lookup(&module_table, index); + index = index_put(mod_tab, (void*) &e); + return (Module*) erts_index_lookup(mod_tab, index); } -Module *module_code(int i) +Module *module_code(int i, ErtsCodeIndex code_ix) { - return (Module*) erts_index_lookup(&module_table, i); + return (Module*) erts_index_lookup(&module_tables[code_ix], i); } -int module_code_size(void) +int module_code_size(ErtsCodeIndex code_ix) { - return module_table.entries; + return module_tables[code_ix].entries; } int module_table_sz(void) { - return index_table_sz(&module_table); + return index_table_sz(&module_tables[erts_active_code_ix()]); +} + +#ifdef DEBUG +static ErtsCodeIndex dbg_load_code_ix = 0; +#endif + +static int entries_at_start_load = 0; + +void module_start_load(void) +{ + IndexTable* src = &module_tables[erts_active_code_ix()]; + IndexTable* dst = &module_tables[erts_loader_code_ix()]; + Module* src_mod; + Module* dst_mod; + int i; + + ASSERT(dbg_load_code_ix == -1); + ASSERT(dst->entries <= src->entries); + + /* + * Make sure our existing modules are up-to-date + */ + for (i = 0; i < dst->entries; i++) { + src_mod = (Module*) erts_index_lookup(src, i); + dst_mod = (Module*) erts_index_lookup(dst, i); + ASSERT(src_mod->module == dst_mod->module); + + dst_mod->curr = src_mod->curr; + dst_mod->old = src_mod->old; + } + + /* + * Copy all new modules from active table + */ + for (i = dst->entries; i < src->entries; i++) { + src_mod = (Module*) erts_index_lookup(src, i); + dst_mod = (Module*) erts_index_lookup(dst, index_put(dst, src_mod)); + ASSERT(dst_mod != src_mod); + + dst_mod->curr = src_mod->curr; + dst_mod->old = src_mod->old; + } + entries_at_start_load = dst->entries; + + IF_DEBUG(dbg_load_code_ix = erts_loader_code_ix()); +} + +void module_end_load(int commit) +{ + ASSERT(dbg_load_code_ix == erts_loader_code_ix()); + + if (!commit) { /* abort */ + IndexTable* tab = &module_tables[erts_loader_code_ix()]; + + ASSERT(entries_at_start_load <= tab->entries); + index_erase_latest_from(tab, entries_at_start_load); + } + + IF_DEBUG(dbg_load_code_ix = -1); } |