diff options
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/beam_bif_load.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.h | 3 | ||||
-rw-r--r-- | erts/emulator/beam/erl_fun.c | 1 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.c | 4 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_mode_switch.h | 6 | ||||
-rw-r--r-- | erts/emulator/test/port_SUITE.erl | 25 |
7 files changed, 29 insertions, 16 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 5969197168..8af7703f51 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -1623,10 +1623,10 @@ erts_purge_state_add_fun(ErlFunEntry *fe) } Export * -erts_suspend_process_on_pending_purge_lambda(Process *c_p) +erts_suspend_process_on_pending_purge_lambda(Process *c_p, ErlFunEntry* fe) { erts_smp_mtx_lock(&purge_state.mtx); - if (is_value(purge_state.module)) { + if (purge_state.module == fe->module) { /* * The process c_p is about to call a fun in the code * that we are trying to purge. Suspend it and call diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index ef4cdf9d5a..3be5c0d24c 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -6555,7 +6555,7 @@ call_fun(Process* p, /* Current process. */ * and let it try again when the purge operation is * done (may succeed or not). */ - ep = erts_suspend_process_on_pending_purge_lambda(p); + ep = erts_suspend_process_on_pending_purge_lambda(p, fe); ASSERT(ep); } else { diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h index 1200bb9c6f..9be5e14e40 100644 --- a/erts/emulator/beam/beam_load.h +++ b/erts/emulator/beam/beam_load.h @@ -124,7 +124,8 @@ int erts_is_module_native(BeamCodeHeader* code); void erts_beam_bif_load_init(void); struct erl_fun_entry; void erts_purge_state_add_fun(struct erl_fun_entry *fe); -Export *erts_suspend_process_on_pending_purge_lambda(Process *c_p); +Export *erts_suspend_process_on_pending_purge_lambda(Process *c_p, + struct erl_fun_entry*); /* * Layout of the line table. diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c index c639ba623f..5258d83a18 100644 --- a/erts/emulator/beam/erl_fun.c +++ b/erts/emulator/beam/erl_fun.c @@ -236,7 +236,6 @@ erts_fun_purge_abort_prepare(ErlFunEntry **funs, Uint no) ErlFunEntry *fe = funs[ix]; if (fe->address == unloaded_fun) fe->address = fe->pend_purge_address; - fe->pend_purge_address = NULL; } } diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index 3336fded7a..dcb6c35bfa 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -1476,6 +1476,10 @@ int hipe_find_mfa_from_ra(const void *ra, Eterm *m, Eterm *f, unsigned int *a) struct hipe_mfa_info **bucket; unsigned int i, nrbuckets; + if (hipe_is_ra_mode_switch(ra)) { + return 0; + } + /* Note about locking: the table is only updated from the loader, which runs with the rest of the system suspended. */ /* XXX: alas not true; see comment at hipe_mfa_info_table.lock */ diff --git a/erts/emulator/hipe/hipe_mode_switch.h b/erts/emulator/hipe/hipe_mode_switch.h index c40077d558..e54b81cf78 100644 --- a/erts/emulator/hipe/hipe_mode_switch.h +++ b/erts/emulator/hipe/hipe_mode_switch.h @@ -64,6 +64,7 @@ Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s); ERTS_GLB_INLINE void hipe_reserve_beam_trap_frame(Process*, Eterm reg[], unsigned arity); ERTS_GLB_INLINE void hipe_unreserve_beam_trap_frame(Process*); +ERTS_GLB_INLINE int hipe_is_ra_mode_switch(const void* ra); extern Uint hipe_beam_pc_return[]; extern Uint hipe_beam_pc_throw[]; @@ -112,6 +113,11 @@ ERTS_GLB_INLINE void hipe_unreserve_beam_trap_frame(Process *p) p->stop += 2; } +ERTS_GLB_INLINE int hipe_is_ra_mode_switch(const void* ra) +{ + return ra == nbif_return; +} + #endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ #endif /* ASM */ diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index 4323849465..d4e77d634a 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -976,21 +976,21 @@ try_bad_env(Env) -> %% Test that we can handle a very very large environment gracefully. huge_env(Config) when is_list(Config) -> ct:timetrap({minutes, 2}), - Vars = case os:type() of - {win32,_} -> 500; - _ -> - %% We create a huge environment, - %% 20000 variables is about 25MB - %% which seems to be the limit on Linux. - 20000 - end, + {Vars, Cmd} = case os:type() of + {win32,_} -> {500, "cmd /q /c ls"}; + _ -> + %% We create a huge environment, + %% 20000 variables is about 25MB + %% which seems to be the limit on Linux. + {20000, "ls"} + end, Env = [{[$a + I div (25*25*25*25) rem 25, $a + I div (25*25*25) rem 25, $a + I div (25*25) rem 25, $a+I div 25 rem 25, $a+I rem 25], lists:duplicate(100,$a+I rem 25)} || I <- lists:seq(1,Vars)], - try erlang:open_port({spawn,"ls"},[exit_status, {env, Env}]) of + try erlang:open_port({spawn,Cmd},[exit_status, {env, Env}]) of P -> receive {P, {exit_status,N}} = M -> @@ -1009,7 +1009,10 @@ huge_env(Config) when is_list(Config) -> %% Test to spawn program with command payload buffer %% just around pipe capacity (9f779819f6bda734c5953468f7798) pipe_limit_env(Config) when is_list(Config) -> - Cmd = "true", + Cmd = case os:type() of + {win32,_} -> "cmd /q /c true"; + _ -> "true" + end, CmdSize = command_payload_size(Cmd), Limits = [4096, 16384, 65536], % Try a couple of common pipe buffer sizes @@ -1026,7 +1029,7 @@ pipe_limit_env_do(Bytes, Cmd, CmdSize) -> try erlang:open_port({spawn,Cmd},[exit_status, {env, Env}]) of P -> receive - {P, {exit_status,N}} = M -> + {P, {exit_status,N}} -> %% Bug caused exit_status 150 (EINVAL+128) 0 = N end |