~rdoering/ubuntu/intrepid/erlang/fix-535090

« back to all changes in this revision

Viewing changes to erts/emulator/beam/beam_bif_load.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2007-05-01 16:57:10 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070501165710-2sapk0hp2gf3o0ip
Tags: 1:11.b.4-2ubuntu1
* Merge with Debian Unstable. Remaining changes:
  - Add -fno-stack-protector to fix broken crypto_drv.
* DebianMaintainerField update.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
static int purge_module(int module);
39
39
static int is_native(Eterm* code);
40
40
#if defined(HEAP_FRAG_ELIM_TEST)
 
41
static int any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
41
42
static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
42
43
#endif
43
44
 
300
301
    Eterm* sp;
301
302
#ifndef HYBRID /* FIND ME! */
302
303
    ErlFunThing* funp;
303
 
#endif
304
304
    int done_gc = 0;
 
305
#endif
305
306
 
306
307
#define INSIDE(a) (start <= (a) && (a) < end)
307
308
    if (modp == NULL) {         /* Doesn't exist. */
400
401
    for (;;) {
401
402
        ErlMessage* mp;
402
403
 
403
 
        if (any_heap_refs(rp->stop, rp->hend, mod_start, mod_size)) {
 
404
        if (any_heap_ref_ptrs(rp->stop, rp->hend, mod_start, mod_size)) {
404
405
            goto need_gc;
405
406
        }
406
407
        if (any_heap_refs(rp->heap, rp->htop, mod_start, mod_size)) {
407
408
            goto need_gc;
408
409
        }
409
410
 
 
411
        if (any_heap_refs(rp->old_heap, rp->old_htop, mod_start, mod_size)) {
 
412
            goto need_gc;
 
413
        }
 
414
 
410
415
        if (rp->dictionary != NULL) {
411
416
            Eterm* start = rp->dictionary->data;
412
417
            Eterm* end = start + rp->dictionary->used;
413
418
 
414
 
            if (any_heap_refs(start, end, mod_start, mod_size)) {
 
419
            if (any_heap_ref_ptrs(start, end, mod_start, mod_size)) {
415
420
                goto need_gc;
416
421
            }
417
422
        }
418
423
 
419
424
        for (mp = rp->msg.first; mp != NULL; mp = mp->next) {
420
 
            if (any_heap_refs(mp->m, mp->m+2, mod_start, mod_size)) {
 
425
            if (any_heap_ref_ptrs(mp->m, mp->m+2, mod_start, mod_size)) {
421
426
                goto need_gc;
422
427
            }
423
428
        }
427
432
        if (done_gc) {
428
433
            return am_true;
429
434
        } else {
 
435
            Eterm* literals;
 
436
            Uint lit_size;
 
437
 
430
438
            /*
431
439
             * Try to get rid of constants by by garbage collecting.
432
440
             * Clear both fvalue and ftrace.
437
445
            done_gc = 1;
438
446
            FLAGS(rp) |= F_NEED_FULLSWEEP;
439
447
            (void) erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity);
 
448
            literals = (Eterm *) modp->old_code[MI_LITERALS_START];
 
449
            lit_size = (Eterm *) modp->old_code[MI_LITERALS_END] - literals;
 
450
            erts_garbage_collect_literals(rp, literals, lit_size);
440
451
        }
441
452
    }
442
453
#endif
445
456
}
446
457
 
447
458
#if defined(HEAP_FRAG_ELIM_TEST)
448
 
static int
449
 
any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
450
 
{
451
459
#define in_area(ptr,start,nbytes) \
452
460
    ((unsigned long)((char*)(ptr) - (char*)(start)) < (nbytes))
453
 
    Eterm* p;
454
 
    Eterm val;
455
 
 
456
 
    for (p = start; p < end; p++) {
457
 
        val = *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)) {
462
 
                return 1;
463
 
            }
464
 
            break;
465
 
        }
466
 
    }
467
 
    return 0;
 
461
 
 
462
static int
 
463
any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
 
464
{
 
465
    Eterm* p;
 
466
    Eterm val;
 
467
 
 
468
    for (p = start; p < end; p++) {
 
469
        val = *p;
 
470
        switch (primary_tag(val)) {
 
471
        case TAG_PRIMARY_BOXED:
 
472
        case TAG_PRIMARY_LIST:
 
473
            if (in_area(val, mod_start, mod_size)) {
 
474
                return 1;
 
475
            }
 
476
            break;
 
477
        }
 
478
    }
 
479
    return 0;
 
480
}
 
481
 
 
482
static int
 
483
any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
 
484
{
 
485
    Eterm* p;
 
486
    Eterm val;
 
487
 
 
488
    for (p = start; p < end; p++) {
 
489
        val = *p;
 
490
        switch (primary_tag(val)) {
 
491
        case TAG_PRIMARY_BOXED:
 
492
        case TAG_PRIMARY_LIST:
 
493
            if (in_area(val, mod_start, mod_size)) {
 
494
                return 1;
 
495
            }
 
496
            break;
 
497
        case TAG_PRIMARY_HEADER: {
 
498
              Uint tari;
 
499
 
 
500
              if (header_is_transparent(val)) {
 
501
                  p++;
 
502
                  continue;
 
503
              }
 
504
              tari = thing_arityval(val);
 
505
              p += tari;
 
506
          }
 
507
        }
 
508
    }
 
509
    return 0;
 
510
}
 
511
 
468
512
#undef in_area
469
 
}
 
513
 
470
514
#endif
471
515
 
472
516
static int