33
33
#include "erl_binary.h"
35
35
static Eterm check_process_code(Process* rp, Module* modp);
36
static void delete_code(Module* modp);
36
static void delete_code(Process *c_p, Uint32 c_p_locks, Module* modp);
37
37
static void delete_export_references(Eterm module);
38
38
static int purge_module(int module);
39
39
static int is_native(Eterm* code);
40
#if defined(HEAP_FRAG_ELIM_TEST)
41
static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
42
45
load_module_2(BIF_ALIST_2)
50
if (is_not_atom(BIF_ARG_1) || is_not_binary(BIF_ARG_2)) {
52
int trace_pattern_is_on;
54
Binary *meta_match_spec;
55
struct trace_pattern_flags trace_pattern_flags;
56
Eterm meta_tracer_pid;
58
byte* temp_alloc = NULL;
60
if (is_not_atom(BIF_ARG_1)) {
62
erts_free_aligned_binary_bytes(temp_alloc);
51
63
BIF_ERROR(BIF_P, BADARG);
65
if ((code = erts_get_aligned_binary_bytes(BIF_ARG_2, &temp_alloc)) == NULL) {
68
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
69
erts_smp_block_system(0);
71
erts_export_consolidate();
54
73
hp = HAlloc(BIF_P, 3);
55
GET_BINARY_BYTES(BIF_ARG_2, code);
56
74
sz = binary_size(BIF_ARG_2);
57
if ((i = erts_load_module(BIF_P->group_leader, &BIF_ARG_1, code, sz)) < 0) {
75
if ((i = erts_load_module(BIF_P, 0,
76
BIF_P->group_leader, &BIF_ARG_1, code, sz)) < 0) {
59
78
case -1: reason = am_badfile; break;
60
79
case -2: reason = am_nofile; break;
65
84
default: reason = am_badfile; break;
67
BIF_RET(TUPLE2(hp, am_error, reason));
86
res = TUPLE2(hp, am_error, reason);
69
if (erts_default_trace_pattern_is_on) {
90
erts_get_default_trace_pattern(&trace_pattern_is_on,
95
if (trace_pattern_is_on) {
71
97
mfa[0] = BIF_ARG_1;
72
98
(void) erts_set_trace_pattern(mfa, 1,
73
erts_default_match_spec,
74
erts_default_meta_match_spec,
75
1, erts_default_trace_pattern_flags,
76
erts_default_meta_tracer_pid);
101
1, trace_pattern_flags,
78
BIF_RET(TUPLE2(hp, am_module, BIF_ARG_1));
105
res = TUPLE2(hp, am_module, BIF_ARG_1);
108
erts_free_aligned_binary_bytes(temp_alloc);
109
erts_smp_release_system();
110
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
81
115
BIF_RETTYPE purge_module_1(BIF_ALIST_1)
83
119
if (is_not_atom(BIF_ARG_1)) {
84
120
BIF_ERROR(BIF_P, BADARG);
86
if (purge_module(atom_val(BIF_ARG_1)) < 0) {
123
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
124
erts_smp_block_system(0);
126
erts_export_consolidate();
127
purge_res = purge_module(atom_val(BIF_ARG_1));
129
erts_smp_release_system();
130
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
87
133
BIF_ERROR(BIF_P, BADARG);
104
150
am_true : am_false;
153
BIF_RETTYPE code_make_stub_module_3(BIF_ALIST_3)
157
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
158
erts_smp_block_system(0);
160
erts_export_consolidate();
161
res = erts_make_stub_module(BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
163
erts_smp_release_system();
164
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
108
169
check_process_code_2(BIF_ALIST_2)
116
177
if (is_internal_pid(BIF_ARG_1)) {
117
179
if (internal_pid_index(BIF_ARG_1) >= erts_max_processes)
119
rp = process_tab[internal_pid_index(BIF_ARG_1)];
120
if (INVALID_PID(rp, BIF_ARG_1)) {
181
rp = erts_pid2proc_not_running(BIF_P, ERTS_PROC_LOCK_MAIN,
182
BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
184
ERTS_BIF_CHK_EXITED(BIF_P);
185
ERTS_SMP_BIF_CHK_RESCHEDULE(BIF_P);
121
186
BIF_RET(am_false);
123
188
modp = erts_get_module(BIF_ARG_2);
124
BIF_RET(check_process_code(rp, modp));
189
res = check_process_code(rp, modp);
192
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
126
196
else if (is_external_pid(BIF_ARG_1)
127
197
&& external_pid_dist_entry(BIF_ARG_1) == erts_this_dist_entry) {
136
206
BIF_RETTYPE delete_module_1(BIF_ALIST_1)
140
if (is_not_atom(BIF_ARG_1)) {
210
if (is_not_atom(BIF_ARG_1))
213
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
214
erts_smp_block_system(0);
217
Module *modp = erts_get_module(BIF_ARG_1);
221
else if (modp->old_code != 0) {
222
erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf();
223
erts_dsprintf(dsbufp, "Module %T must be purged before loading\n",
225
erts_send_error_to_logger(BIF_P->group_leader, dsbufp);
229
delete_export_references(BIF_ARG_1);
230
delete_code(BIF_P, 0, modp);
235
erts_smp_release_system();
236
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
238
if (res == am_badarg) {
142
240
BIF_ERROR(BIF_P, BADARG);
144
modp = erts_get_module(BIF_ARG_1);
148
if (modp->old_code != 0) {
150
erl_printf(CBUF, "Module ");
151
print_atom(atom_val(BIF_ARG_1), CBUF);
152
erl_printf(CBUF, " must be purged before loading\n");
153
send_error_to_logger(BIF_P->group_leader);
157
delete_export_references(BIF_ARG_1);
162
245
BIF_RETTYPE module_loaded_1(BIF_ALIST_1)
187
for (i = 0; i < module_code_size; i++) {
270
for (i = 0; i < module_code_size(); i++) {
188
271
if (module_code(i) != NULL &&
189
272
((module_code(i)->code_length != 0) ||
190
273
(module_code(i)->old_code_length != 0))) {
195
278
hp = HAlloc(BIF_P, j*2);
197
for (i = 0; i < module_code_size; i++) {
280
for (i = 0; i < module_code_size(); i++) {
198
281
if (module_code(i) != NULL &&
199
282
((module_code(i)->code_length != 0) ||
200
283
(module_code(i)->old_code_length != 0))) {
211
294
check_process_code(Process* rp, Module* modp)
301
#ifndef HYBRID /* FIND ME! */
217
302
ErlFunThing* funp;
221
306
#define INSIDE(a) (start <= (a) && (a) < end)
222
307
if (modp == NULL) { /* Doesn't exist. */
338
* Check all continuation pointers stored in stackdump
339
* and clear exception stackdump if there is a pointer
342
if (rp->ftrace != NIL) {
343
struct StackTrace *s;
344
ASSERT(is_list(rp->ftrace));
345
s = (struct StackTrace *) big_val(CDR(list_val(rp->ftrace)));
346
if ((s->pc && INSIDE(s->pc)) ||
347
(s->current && INSIDE(s->current))) {
348
rp->freason = EXC_NULL;
353
for (i = 0; i < s->depth; i++) {
354
if (INSIDE(s->trace[i])) {
355
rp->freason = EXC_NULL;
251
365
* See if there are funs that refer to the old version of the module.
368
#ifndef HYBRID /* FIND ME! */
256
370
for (funp = MSO(rp).funs; funp; funp = funp->next) {
266
380
* Try to get rid of this fun by garbage collecting.
381
* Clear both fvalue and ftrace to make sure they
382
* don't hold any funs.
384
rp->freason = EXC_NULL;
269
388
FLAGS(rp) |= F_NEED_FULLSWEEP;
270
389
(void) erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity);
396
#if defined(HEAP_FRAG_ELIM_TEST)
398
* See if there are constants inside the module referenced by the process.
403
if (any_heap_refs(rp->stop, rp->hend, mod_start, mod_size)) {
406
if (any_heap_refs(rp->heap, rp->htop, mod_start, mod_size)) {
410
if (rp->dictionary != NULL) {
411
Eterm* start = rp->dictionary->data;
412
Eterm* end = start + rp->dictionary->used;
414
if (any_heap_refs(start, end, mod_start, mod_size)) {
419
for (mp = rp->msg.first; mp != NULL; mp = mp->next) {
420
if (any_heap_refs(mp->m, mp->m+2, mod_start, mod_size)) {
431
* Try to get rid of constants by by garbage collecting.
432
* Clear both fvalue and ftrace.
434
rp->freason = EXC_NULL;
438
FLAGS(rp) |= F_NEED_FULLSWEEP;
439
(void) erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity);
447
#if defined(HEAP_FRAG_ELIM_TEST)
449
any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
451
#define in_area(ptr,start,nbytes) \
452
((unsigned long)((char*)(ptr) - (char*)(start)) < (nbytes))
456
for (p = start; p < end; p++) {
458
switch (primary_tag(val)) {
459
case TAG_PRIMARY_BOXED:
460
case TAG_PRIMARY_LIST:
461
if (in_area(val, mod_start, mod_size)) {
282
473
purge_module(int module)
300
491
if (modp->old_code == 0) {
301
492
if (display_loads) {
302
erl_printf(COUT,"No code to purge for ");
303
print_atom(module, COUT);
304
erl_printf(COUT,"\n");
493
erts_printf("No code to purge for %T\n", make_atom(module));
349
delete_code(Module* modp)
538
delete_code(Process *c_p, Uint32 c_p_locks, Module* modp)
540
#ifdef ERTS_ENABLE_LOCK_CHECK
542
if (c_p && c_p_locks)
543
erts_proc_lc_chk_only_proc_main(c_p);
546
erts_lc_check_exact(NULL, 0);
352
550
* Clear breakpoints if any
354
552
if (modp->code != NULL && modp->code[MI_NUM_BREAKPOINTS] > 0) {
553
if (c_p && c_p_locks)
554
erts_smp_proc_unlock(c_p, ERTS_PROC_LOCK_MAIN);
555
erts_smp_block_system(0);
355
556
erts_clear_module_break(modp);
356
557
modp->code[MI_NUM_BREAKPOINTS] = 0;
558
erts_smp_release_system();
559
if (c_p && c_p_locks)
560
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
358
562
modp->old_code = modp->code;
359
563
modp->old_code_length = modp->code_length;
375
579
ASSERT(is_atom(module));
377
for (i = 0; i < export_list_size; i++) {
378
if (export_list(i) != NULL && (export_list(i)->code[0] == module)) {
379
if (export_list(i)->address == beam_debug_apply+5) {
382
if (export_list(i)->address == export_list(i)->code+3 &&
383
(export_list(i)->code[3] == (Eterm) em_apply_bif)) {
386
export_list(i)->address = export_list(i)->code+3;
387
export_list(i)->code[3] = (Uint) em_call_error_handler;
388
export_list(i)->code[4] = 0;
389
MatchSetUnref(export_list(i)->match_prog_set);
390
export_list(i)->match_prog_set = NULL;
581
for (i = 0; i < export_list_size(); i++) {
582
Export *ep = export_list(i);
583
if (ep != NULL && (ep->code[0] == module)) {
584
if (ep->address == ep->code+3 &&
585
(ep->code[3] == (Eterm) em_apply_bif)) {
588
ep->address = ep->code+3;
589
ep->code[3] = (Uint) em_call_error_handler;
591
MatchSetUnref(ep->match_prog_set);
592
ep->match_prog_set = NULL;
396
beam_make_current_old(Eterm module)
599
beam_make_current_old(Process *c_p, Uint32 c_p_locks, Eterm module)
398
601
Module* modp = erts_put_module(module);
407
610
} else if (modp->old_code == NULL) { /* Make the current version old. */
408
611
if (display_loads) {
409
erl_printf(COUT, "saving old code\n");
612
erts_printf("saving old code\n");
614
delete_code(c_p, c_p_locks, modp);
412
615
delete_export_references(module);