aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif.c
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-11-23 14:15:55 +0100
committerRickard Green <[email protected]>2016-11-23 14:15:55 +0100
commit2b663d3ff96c74fa87be1120f3cd8960318080a1 (patch)
tree24eb224fe6335671596d7c490bd2255863035393 /erts/emulator/beam/erl_nif.c
parent9cac4f15d84a7682f17dee01c0ce4a12bac5d9ff (diff)
parentad94a4bdb24c93d3cafc7351c4c98f346a5f53cc (diff)
downloadotp-2b663d3ff96c74fa87be1120f3cd8960318080a1.tar.gz
otp-2b663d3ff96c74fa87be1120f3cd8960318080a1.tar.bz2
otp-2b663d3ff96c74fa87be1120f3cd8960318080a1.zip
Merge branch 'rickard/nif-scheduling-fixes' into maint
* rickard/nif-scheduling-fixes: Fix check_process_code() when NifExport is in use - OTP-14048 Fix GC when NifExport is in use - OTP-14049 Fix saving of original arguments when rescheduling via NifExport - OTP-14050
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r--erts/emulator/beam/erl_nif.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 3fe8bdb491..6b265a8b80 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -2309,6 +2309,17 @@ erts_setup_nif_gc(Process* proc, Eterm** objv, int* nobj)
return gc;
}
+int
+erts_check_nif_export_in_area(Process *p, char *start, Uint size)
+{
+ NifExport *nep = ERTS_PROC_GET_NIF_TRAP_EXPORT(p);
+ if (!nep || !nep->saved_current)
+ return 0;
+ if (ErtsInArea(nep->saved_current, start, size))
+ return 1;
+ return 0;
+}
+
/*
* Allocate a NifExport and set it in proc specific data
*/
@@ -2360,6 +2371,7 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
Eterm* reg;
NifExport* ep;
int i, scheduler;
+ int orig_argc;
execution_state(env, &proc, &scheduler);
@@ -2370,11 +2382,14 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
reg = erts_proc_sched_data(proc)->x_reg_array;
+ ASSERT(!need_save || proc->current);
+ orig_argc = need_save ? (int) proc->current[2] : 0;
+
ep = (NifExport*) ERTS_PROC_GET_NIF_TRAP_EXPORT(proc);
if (!ep)
- ep = allocate_nif_sched_data(proc, argc);
- else if (need_save && ep->rootset_extra < argc) {
- NifExport* new_ep = allocate_nif_sched_data(proc, argc);
+ ep = allocate_nif_sched_data(proc, orig_argc);
+ else if (need_save && ep->rootset_extra < orig_argc) {
+ NifExport* new_ep = allocate_nif_sched_data(proc, orig_argc);
destroy_nif_export(ep);
ep = new_ep;
}
@@ -2387,16 +2402,14 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
}
if (scheduler > 0)
ERTS_VBUMP_ALL_REDS(proc);
- for (i = 0; i < argc; i++) {
- if (need_save)
- ep->rootset[i+1] = reg[i];
- reg[i] = (Eterm) argv[i];
- }
if (need_save) {
- ASSERT(proc->current);
ep->saved_current = proc->current;
- ep->saved_argc = argc;
+ ep->saved_argc = orig_argc;
+ for (i = 0; i < orig_argc; i++)
+ ep->rootset[i+1] = reg[i];
}
+ for (i = 0; i < argc; i++)
+ reg[i] = (Eterm) argv[i];
proc->i = (BeamInstr*) ep->exp.addressv[0];
ep->exp.code[0] = (BeamInstr) proc->current[0];
ep->exp.code[1] = (BeamInstr) proc->current[1];