diff options
-rw-r--r-- | erts/emulator/beam/beam_debug.c | 26 | ||||
-rw-r--r-- | erts/emulator/beam/copy.c | 12 | ||||
-rw-r--r-- | erts/emulator/beam/global.h | 2 | ||||
-rw-r--r-- | lib/kernel/src/erts_debug.erl | 8 |
4 files changed, 47 insertions, 1 deletions
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c index 40e3f4db4e..36f3cfabbc 100644 --- a/erts/emulator/beam/beam_debug.c +++ b/erts/emulator/beam/beam_debug.c @@ -89,6 +89,32 @@ erts_debug_size_shared_1(BIF_ALIST_1) } BIF_RETTYPE +erts_debug_copy_shared_1(BIF_ALIST_1) +{ + Process* p = BIF_P; + Eterm term = BIF_ARG_1; + Uint size; + Eterm* hp; + Eterm copy; + shcopy_info info; +#ifdef SHCOPY_DISABLE + extern int disable_copy_shared; +#endif + INITIALIZE_INFO(info); + + size = copy_shared_calculate(term, &info, 0); + if (size > 0) { + hp = HAlloc(p, size); + } + copy = copy_shared_perform(term, size, &info, &hp, &p->off_heap, 0); + DESTROY_INFO(info); +#ifdef SHCOPY_DISABLE + disable_copy_shared = 0; +#endif + BIF_RET(copy); +} + +BIF_RETTYPE erts_debug_breakpoint_2(BIF_ALIST_2) { Process* p = BIF_P; diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c index b31e043f08..2566707717 100644 --- a/erts/emulator/beam/copy.c +++ b/erts/emulator/beam/copy.c @@ -901,6 +901,10 @@ Eterm copy_struct(Eterm obj, Uint sz, Eterm** hpp, ErlOffHeap* off_heap) * Using an ESTACK but not very transparently; consider refactoring */ +#ifdef SHCOPY_DISABLE +int disable_copy_shared = ERTS_SHCOPY_FLG_NONE; +#endif + #define DECLARE_SHTABLE(s) \ DECLARE_ESTACK(s); \ Uint ESTK_CONCAT(s,_offset) = 0 @@ -1028,6 +1032,10 @@ Uint copy_shared_calculate(Eterm obj, shcopy_info *info, unsigned flags) if (IS_CONST(obj)) return 0; +#ifdef SHCOPY_DISABLE + flags |= disable_copy_shared; +#endif + myself = erts_get_current_process(); if (myself == NULL || (flags & ERTS_SHCOPY_FLG_NONE)) return size_object(obj); @@ -1276,6 +1284,10 @@ Uint copy_shared_perform(Eterm obj, Uint size, shcopy_info *info, Eterm** hpp, E if (IS_CONST(obj)) return obj; +#ifdef SHCOPY_DISABLE + flags |= disable_copy_shared; +#endif + myself = erts_get_current_process(); if (myself == NULL || (flags & ERTS_SHCOPY_FLG_NONE)) return copy_struct(obj, size, hpp, off_heap); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index a5e6ff6f1c..3e1f3664bc 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -1044,6 +1044,8 @@ void erl_error(char*, va_list); #if defined(SHCOPY_SEND) \ || defined(SHCOPY_SPAWN) #define SHCOPY +/* Use this if you want sharing-preserving copy to be initially disabled */ +#undef SHCOPY_DISABLE /* Use this with care, it is *very* verbose! */ #undef SHCOPY_DEBUG #endif diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl index 5e1cc09e7d..87f001fdf4 100644 --- a/lib/kernel/src/erts_debug.erl +++ b/lib/kernel/src/erts_debug.erl @@ -35,7 +35,7 @@ dump_monitors/1, dump_links/1, flat_size/1, get_internal_state/1, instructions/0, lock_counters/1, map_info/1, same/2, set_internal_state/2, - size_shared/1]). + size_shared/1, copy_shared/1]). -spec breakpoint(MFA, Flag) -> non_neg_integer() when MFA :: {Module :: module(), @@ -93,6 +93,12 @@ flat_size(_) -> size_shared(_) -> erlang:nif_error(undef). +-spec copy_shared(Term) -> term() when + Term :: term(). + +copy_shared(_) -> + erlang:nif_error(undef). + -spec get_internal_state(W) -> term() when W :: reds_left | node_and_dist_references | monitoring_nodes | next_pid | 'DbTable_words' | check_io_debug |