~javier-lopez/ubuntu/vivid/ruby1.9.1/fix-1426828

« back to all changes in this revision

Viewing changes to gc.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-25 09:59:41 UTC
  • mfrom: (21.1.13 sid)
  • Revision ID: package-import@ubuntu.com-20131125095941-aou3ymnwm79em09y
Tags: 1.9.3.448-1ubuntu1
* Merge from Debian. Remaining changes:
  - debian/control: Add ca-certificates to libruby1.9.1 depends so that
    rubygems can perform certificate verification
  - debian/rules: Don't install SSL certificates from upstream sources
  - debian/patches/20120927-rubygems_disable_upstream_certs.patch: Use
    /etc/ssl/certs/ca-certificates.crt for the trusted CA certificates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  gc.c -
4
4
 
5
 
  $Author: naruse $
 
5
  $Author: usa $
6
6
  created at: Tue Oct  5 09:44:46 JST 1993
7
7
 
8
8
  Copyright (C) 1993-2007 Yukihiro Matsumoto
21
21
#include "internal.h"
22
22
#include "gc.h"
23
23
#include "constant.h"
 
24
#include "ruby_atomic.h"
24
25
#include <stdio.h>
25
26
#include <setjmp.h>
26
27
#include <sys/types.h>
 
28
#include <assert.h>
27
29
 
28
30
#ifdef HAVE_SYS_TIME_H
29
31
#include <sys/time.h>
98
100
 
99
101
#define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory]
100
102
 
101
 
#define MARK_STACK_MAX 1024
 
103
#if SIZEOF_LONG == SIZEOF_VOIDP
 
104
# define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG)
 
105
# define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) /* unset FIXNUM_FLAG */
 
106
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
 
107
# define nonspecial_obj_id(obj) LL2NUM((SIGNED_VALUE)(obj) / 2)
 
108
# define obj_id_to_ref(objid) (FIXNUM_P(objid) ? \
 
109
   ((objid) ^ FIXNUM_FLAG) : (NUM2PTR(objid) << 1))
 
110
#else
 
111
# error not supported
 
112
#endif
102
113
 
103
114
int ruby_gc_debug_indent = 0;
104
115
 
319
330
    struct gc_list *next;
320
331
};
321
332
 
 
333
#define STACK_CHUNK_SIZE 500
 
334
 
 
335
typedef struct stack_chunk {
 
336
    VALUE data[STACK_CHUNK_SIZE];
 
337
    struct stack_chunk *next;
 
338
} stack_chunk_t;
 
339
 
 
340
typedef struct mark_stack {
 
341
    stack_chunk_t *chunk;
 
342
    stack_chunk_t *cache;
 
343
    size_t index;
 
344
    size_t limit;
 
345
    size_t cache_size;
 
346
    size_t unused_cache_size;
 
347
} mark_stack_t;
 
348
 
322
349
#define CALC_EXACT_MALLOC_SIZE 0
323
350
 
324
351
typedef struct rb_objspace {
355
382
        st_table *table;
356
383
        RVALUE *deferred;
357
384
    } final;
358
 
    struct {
359
 
        VALUE buffer[MARK_STACK_MAX];
360
 
        VALUE *ptr;
361
 
        int overflow;
362
 
    } markstack;
 
385
    mark_stack_t mark_stack;
363
386
    struct {
364
387
        int run;
365
388
        gc_profile_record *record;
394
417
#define during_gc               objspace->flags.during_gc
395
418
#define finalizer_table         objspace->final.table
396
419
#define deferred_final_list     objspace->final.deferred
397
 
#define mark_stack              objspace->markstack.buffer
398
 
#define mark_stack_ptr          objspace->markstack.ptr
399
 
#define mark_stack_overflow     objspace->markstack.overflow
400
420
#define global_List             objspace->global_list
401
421
#define ruby_gc_stress          objspace->gc_stress
402
422
#define initial_malloc_limit    initial_params.initial_malloc_limit
419
439
#endif
420
440
 
421
441
static void initial_expand_heap(rb_objspace_t *objspace);
 
442
static void init_mark_stack(mark_stack_t *stack);
422
443
 
423
444
void
424
445
rb_gc_set_params(void)
465
486
static void gc_sweep(rb_objspace_t *);
466
487
static void slot_sweep(rb_objspace_t *, struct heaps_slot *);
467
488
static void rest_sweep(rb_objspace_t *);
 
489
static void free_stack_chunks(mark_stack_t *);
468
490
 
469
491
void
470
492
rb_objspace_free(rb_objspace_t *objspace)
491
513
        heaps_used = 0;
492
514
        heaps = 0;
493
515
    }
 
516
    free_stack_chunks(&objspace->mark_stack);
494
517
    free(objspace);
495
518
}
496
519
#endif
616
639
gc_profile_enable_get(VALUE self)
617
640
{
618
641
    rb_objspace_t *objspace = &rb_objspace;
619
 
    return objspace->profile.run;
 
642
    return objspace->profile.run ? Qtrue : Qfalse;
620
643
}
621
644
 
622
645
/*
1100
1123
init_heap(rb_objspace_t *objspace)
1101
1124
{
1102
1125
    add_heap_slots(objspace, HEAP_MIN_SLOTS / HEAP_OBJ_LIMIT);
 
1126
    init_mark_stack(&objspace->mark_stack);
1103
1127
#ifdef USE_SIGALTSTACK
1104
1128
    {
1105
1129
        /* altstack of another threads are allocated in another place */
1296
1320
}
1297
1321
#endif
1298
1322
 
1299
 
#define GC_LEVEL_MAX 250
1300
 
#define STACKFRAME_FOR_GC_MARK (GC_LEVEL_MAX * GC_MARK_STACKFRAME_WORD)
 
1323
/* Marking stack */
 
1324
 
 
1325
static void push_mark_stack(mark_stack_t *, VALUE);
 
1326
static int pop_mark_stack(mark_stack_t *, VALUE *);
 
1327
static void shrink_stack_chunk_cache(mark_stack_t *stack);
 
1328
 
 
1329
static stack_chunk_t *
 
1330
stack_chunk_alloc(void)
 
1331
{
 
1332
    stack_chunk_t *res;
 
1333
 
 
1334
    res = malloc(sizeof(stack_chunk_t));
 
1335
    if (!res)
 
1336
        rb_memerror();
 
1337
 
 
1338
    return res;
 
1339
}
 
1340
 
 
1341
static inline int
 
1342
is_mark_stask_empty(mark_stack_t *stack)
 
1343
{
 
1344
    return stack->chunk == NULL;
 
1345
}
 
1346
 
 
1347
static void
 
1348
add_stack_chunk_cache(mark_stack_t *stack, stack_chunk_t *chunk)
 
1349
{
 
1350
    chunk->next = stack->cache;
 
1351
    stack->cache = chunk;
 
1352
    stack->cache_size++;
 
1353
}
 
1354
 
 
1355
static void
 
1356
shrink_stack_chunk_cache(mark_stack_t *stack)
 
1357
{
 
1358
    stack_chunk_t *chunk;
 
1359
 
 
1360
    if (stack->unused_cache_size > (stack->cache_size/2)) {
 
1361
        chunk = stack->cache;
 
1362
        stack->cache = stack->cache->next;
 
1363
        stack->cache_size--;
 
1364
        free(chunk);
 
1365
    }
 
1366
    stack->unused_cache_size = stack->cache_size;
 
1367
}
 
1368
 
 
1369
static void
 
1370
push_mark_stack_chunk(mark_stack_t *stack)
 
1371
{
 
1372
    stack_chunk_t *next;
 
1373
 
 
1374
    if (stack->cache_size > 0) {
 
1375
        next = stack->cache;
 
1376
        stack->cache = stack->cache->next;
 
1377
        stack->cache_size--;
 
1378
        if (stack->unused_cache_size > stack->cache_size)
 
1379
            stack->unused_cache_size = stack->cache_size;
 
1380
    }
 
1381
    else {
 
1382
        next = stack_chunk_alloc();
 
1383
    }
 
1384
    next->next = stack->chunk;
 
1385
    stack->chunk = next;
 
1386
    stack->index = 0;
 
1387
}
 
1388
 
 
1389
static void
 
1390
pop_mark_stack_chunk(mark_stack_t *stack)
 
1391
{
 
1392
    stack_chunk_t *prev;
 
1393
 
 
1394
    prev = stack->chunk->next;
 
1395
    add_stack_chunk_cache(stack, stack->chunk);
 
1396
    stack->chunk = prev;
 
1397
    stack->index = stack->limit;
 
1398
}
 
1399
 
 
1400
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
 
1401
static void
 
1402
free_stack_chunks(mark_stack_t *stack)
 
1403
{
 
1404
    stack_chunk_t *chunk = stack->chunk;
 
1405
    stack_chunk_t *next = NULL;
 
1406
 
 
1407
    while (chunk != NULL) {
 
1408
        next = chunk->next;
 
1409
        free(chunk);
 
1410
        chunk = next;
 
1411
    }
 
1412
}
 
1413
#endif
 
1414
 
 
1415
static void
 
1416
push_mark_stack(mark_stack_t *stack, VALUE data)
 
1417
{
 
1418
    if (stack->index == stack->limit) {
 
1419
        push_mark_stack_chunk(stack);
 
1420
    }
 
1421
    stack->chunk->data[stack->index++] = data;
 
1422
}
 
1423
 
 
1424
static int
 
1425
pop_mark_stack(mark_stack_t *stack, VALUE *data)
 
1426
{
 
1427
    if (is_mark_stask_empty(stack)) {
 
1428
        return FALSE;
 
1429
    }
 
1430
    if (stack->index == 1) {
 
1431
        *data = stack->chunk->data[--stack->index];
 
1432
        pop_mark_stack_chunk(stack);
 
1433
        return TRUE;
 
1434
    }
 
1435
    *data = stack->chunk->data[--stack->index];
 
1436
    return TRUE;
 
1437
}
 
1438
 
 
1439
static void
 
1440
init_mark_stack(mark_stack_t *stack)
 
1441
{
 
1442
    int i;
 
1443
 
 
1444
    push_mark_stack_chunk(stack);
 
1445
    stack->limit = STACK_CHUNK_SIZE;
 
1446
 
 
1447
    for(i=0; i < 4; i++) {
 
1448
        add_stack_chunk_cache(stack, stack_chunk_alloc());
 
1449
    }
 
1450
    stack->unused_cache_size = stack->cache_size;
 
1451
}
 
1452
 
1301
1453
 
1302
1454
size_t
1303
1455
ruby_stack_length(VALUE **p)
1308
1460
    return STACK_LENGTH;
1309
1461
}
1310
1462
 
 
1463
#if !(defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK))
1311
1464
static int
1312
1465
stack_check(int water_mark)
1313
1466
{
1323
1476
#endif
1324
1477
    return ret;
1325
1478
}
 
1479
#endif
1326
1480
 
1327
1481
#define STACKFRAME_FOR_CALL_CFUNC 512
1328
1482
 
1336
1490
#endif
1337
1491
}
1338
1492
 
1339
 
static void
1340
 
init_mark_stack(rb_objspace_t *objspace)
1341
 
{
1342
 
    mark_stack_overflow = 0;
1343
 
    mark_stack_ptr = mark_stack;
1344
 
}
1345
 
 
1346
1493
#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack)
1347
1494
 
1348
 
static void gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev);
1349
 
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev);
1350
 
 
1351
 
static void
1352
 
gc_mark_all(rb_objspace_t *objspace)
1353
 
{
1354
 
    RVALUE *p, *pend;
1355
 
    size_t i;
1356
 
 
1357
 
    init_mark_stack(objspace);
1358
 
    for (i = 0; i < heaps_used; i++) {
1359
 
        p = objspace->heap.sorted[i].start; pend = objspace->heap.sorted[i].end;
1360
 
        while (p < pend) {
1361
 
            if ((p->as.basic.flags & FL_MARK) &&
1362
 
                (p->as.basic.flags != FL_MARK)) {
1363
 
                gc_mark_children(objspace, (VALUE)p, 0);
1364
 
            }
1365
 
            p++;
1366
 
        }
1367
 
    }
1368
 
}
1369
 
 
1370
 
static void
1371
 
gc_mark_rest(rb_objspace_t *objspace)
1372
 
{
1373
 
    VALUE tmp_arry[MARK_STACK_MAX];
1374
 
    VALUE *p;
1375
 
 
1376
 
    p = (mark_stack_ptr - mark_stack) + tmp_arry;
1377
 
    MEMCPY(tmp_arry, mark_stack, VALUE, p - tmp_arry);
1378
 
 
1379
 
    init_mark_stack(objspace);
1380
 
    while (p != tmp_arry) {
1381
 
        p--;
1382
 
        gc_mark_children(objspace, *p, 0);
1383
 
    }
 
1495
static void gc_mark(rb_objspace_t *objspace, VALUE ptr);
 
1496
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr);
 
1497
 
 
1498
static void
 
1499
gc_mark_stacked_objects(rb_objspace_t *objspace)
 
1500
{
 
1501
    mark_stack_t *mstack = &objspace->mark_stack;
 
1502
    VALUE obj = 0;
 
1503
 
 
1504
    if (!mstack->index) return;
 
1505
    while (pop_mark_stack(mstack, &obj)) {
 
1506
        gc_mark_children(objspace, obj);
 
1507
    }
 
1508
    shrink_stack_chunk_cache(mstack);
1384
1509
}
1385
1510
 
1386
1511
static inline int
1419
1544
        v = *x;
1420
1545
        VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v));
1421
1546
        if (is_pointer_to_heap(objspace, (void *)v)) {
1422
 
            gc_mark(objspace, v, 0);
 
1547
            gc_mark(objspace, v);
1423
1548
        }
1424
1549
        x++;
1425
1550
    }
1445
1570
 
1446
1571
struct mark_tbl_arg {
1447
1572
    rb_objspace_t *objspace;
1448
 
    int lev;
1449
1573
};
1450
1574
 
1451
1575
static int
1452
1576
mark_entry(ID key, VALUE value, st_data_t data)
1453
1577
{
1454
1578
    struct mark_tbl_arg *arg = (void*)data;
1455
 
    gc_mark(arg->objspace, value, arg->lev);
 
1579
    gc_mark(arg->objspace, value);
1456
1580
    return ST_CONTINUE;
1457
1581
}
1458
1582
 
1459
1583
static void
1460
 
mark_tbl(rb_objspace_t *objspace, st_table *tbl, int lev)
 
1584
mark_tbl(rb_objspace_t *objspace, st_table *tbl)
1461
1585
{
1462
1586
    struct mark_tbl_arg arg;
1463
1587
    if (!tbl || tbl->num_entries == 0) return;
1464
1588
    arg.objspace = objspace;
1465
 
    arg.lev = lev;
1466
1589
    st_foreach(tbl, mark_entry, (st_data_t)&arg);
1467
1590
}
1468
1591
 
1470
1593
mark_key(VALUE key, VALUE value, st_data_t data)
1471
1594
{
1472
1595
    struct mark_tbl_arg *arg = (void*)data;
1473
 
    gc_mark(arg->objspace, key, arg->lev);
 
1596
    gc_mark(arg->objspace, key);
1474
1597
    return ST_CONTINUE;
1475
1598
}
1476
1599
 
1477
1600
static void
1478
 
mark_set(rb_objspace_t *objspace, st_table *tbl, int lev)
 
1601
mark_set(rb_objspace_t *objspace, st_table *tbl)
1479
1602
{
1480
1603
    struct mark_tbl_arg arg;
1481
1604
    if (!tbl) return;
1482
1605
    arg.objspace = objspace;
1483
 
    arg.lev = lev;
1484
1606
    st_foreach(tbl, mark_key, (st_data_t)&arg);
1485
1607
}
1486
1608
 
1487
1609
void
1488
1610
rb_mark_set(st_table *tbl)
1489
1611
{
1490
 
    mark_set(&rb_objspace, tbl, 0);
 
1612
    mark_set(&rb_objspace, tbl);
1491
1613
}
1492
1614
 
1493
1615
static int
1494
1616
mark_keyvalue(VALUE key, VALUE value, st_data_t data)
1495
1617
{
1496
1618
    struct mark_tbl_arg *arg = (void*)data;
1497
 
    gc_mark(arg->objspace, key, arg->lev);
1498
 
    gc_mark(arg->objspace, value, arg->lev);
 
1619
    gc_mark(arg->objspace, key);
 
1620
    gc_mark(arg->objspace, value);
1499
1621
    return ST_CONTINUE;
1500
1622
}
1501
1623
 
1502
1624
static void
1503
 
mark_hash(rb_objspace_t *objspace, st_table *tbl, int lev)
 
1625
mark_hash(rb_objspace_t *objspace, st_table *tbl)
1504
1626
{
1505
1627
    struct mark_tbl_arg arg;
1506
1628
    if (!tbl) return;
1507
1629
    arg.objspace = objspace;
1508
 
    arg.lev = lev;
1509
1630
    st_foreach(tbl, mark_keyvalue, (st_data_t)&arg);
1510
1631
}
1511
1632
 
1512
1633
void
1513
1634
rb_mark_hash(st_table *tbl)
1514
1635
{
1515
 
    mark_hash(&rb_objspace, tbl, 0);
 
1636
    mark_hash(&rb_objspace, tbl);
1516
1637
}
1517
1638
 
1518
1639
static void
1519
 
mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me, int lev)
 
1640
mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
1520
1641
{
1521
1642
    const rb_method_definition_t *def = me->def;
1522
1643
 
1523
 
    gc_mark(objspace, me->klass, lev);
 
1644
    gc_mark(objspace, me->klass);
1524
1645
    if (!def) return;
1525
1646
    switch (def->type) {
1526
1647
      case VM_METHOD_TYPE_ISEQ:
1527
 
        gc_mark(objspace, def->body.iseq->self, lev);
 
1648
        gc_mark(objspace, def->body.iseq->self);
1528
1649
        break;
1529
1650
      case VM_METHOD_TYPE_BMETHOD:
1530
 
        gc_mark(objspace, def->body.proc, lev);
 
1651
        gc_mark(objspace, def->body.proc);
1531
1652
        break;
1532
1653
      case VM_METHOD_TYPE_ATTRSET:
1533
1654
      case VM_METHOD_TYPE_IVAR:
1534
 
        gc_mark(objspace, def->body.attr.location, lev);
 
1655
        gc_mark(objspace, def->body.attr.location);
1535
1656
        break;
1536
1657
      default:
1537
1658
        break; /* ignore */
1541
1662
void
1542
1663
rb_mark_method_entry(const rb_method_entry_t *me)
1543
1664
{
1544
 
    mark_method_entry(&rb_objspace, me, 0);
 
1665
    mark_method_entry(&rb_objspace, me);
1545
1666
}
1546
1667
 
1547
1668
static int
1548
1669
mark_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t data)
1549
1670
{
1550
1671
    struct mark_tbl_arg *arg = (void*)data;
1551
 
    mark_method_entry(arg->objspace, me, arg->lev);
 
1672
    mark_method_entry(arg->objspace, me);
1552
1673
    return ST_CONTINUE;
1553
1674
}
1554
1675
 
1555
1676
static void
1556
 
mark_m_tbl(rb_objspace_t *objspace, st_table *tbl, int lev)
 
1677
mark_m_tbl(rb_objspace_t *objspace, st_table *tbl)
1557
1678
{
1558
1679
    struct mark_tbl_arg arg;
1559
1680
    if (!tbl) return;
1560
1681
    arg.objspace = objspace;
1561
 
    arg.lev = lev;
1562
1682
    st_foreach(tbl, mark_method_entry_i, (st_data_t)&arg);
1563
1683
}
1564
1684
 
1565
1685
static int
1566
1686
free_method_entry_i(ID key, rb_method_entry_t *me, st_data_t data)
1567
1687
{
1568
 
    rb_free_method_entry(me);
 
1688
    if (!me->mark) {
 
1689
        rb_free_method_entry(me);
 
1690
    }
1569
1691
    return ST_CONTINUE;
1570
1692
}
1571
1693
 
1580
1702
mark_const_entry_i(ID key, const rb_const_entry_t *ce, st_data_t data)
1581
1703
{
1582
1704
    struct mark_tbl_arg *arg = (void*)data;
1583
 
    gc_mark(arg->objspace, ce->value, arg->lev);
 
1705
    gc_mark(arg->objspace, ce->value);
1584
1706
    return ST_CONTINUE;
1585
1707
}
1586
1708
 
1587
1709
static void
1588
 
mark_const_tbl(rb_objspace_t *objspace, st_table *tbl, int lev)
 
1710
mark_const_tbl(rb_objspace_t *objspace, st_table *tbl)
1589
1711
{
1590
1712
    struct mark_tbl_arg arg;
1591
1713
    if (!tbl) return;
1592
1714
    arg.objspace = objspace;
1593
 
    arg.lev = lev;
1594
1715
    st_foreach(tbl, mark_const_entry_i, (st_data_t)&arg);
1595
1716
}
1596
1717
 
1611
1732
void
1612
1733
rb_mark_tbl(st_table *tbl)
1613
1734
{
1614
 
    mark_tbl(&rb_objspace, tbl, 0);
 
1735
    mark_tbl(&rb_objspace, tbl);
1615
1736
}
1616
1737
 
1617
1738
void
1618
1739
rb_gc_mark_maybe(VALUE obj)
1619
1740
{
1620
1741
    if (is_pointer_to_heap(&rb_objspace, (void *)obj)) {
1621
 
        gc_mark(&rb_objspace, obj, 0);
 
1742
        gc_mark(&rb_objspace, obj);
1622
1743
    }
1623
1744
}
1624
1745
 
1625
1746
static void
1626
 
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
 
1747
gc_mark(rb_objspace_t *objspace, VALUE ptr)
1627
1748
{
1628
1749
    register RVALUE *obj;
1629
1750
 
1634
1755
    obj->as.basic.flags |= FL_MARK;
1635
1756
    objspace->heap.live_num++;
1636
1757
 
1637
 
    if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check(STACKFRAME_FOR_GC_MARK))) {
1638
 
        if (!mark_stack_overflow) {
1639
 
            if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
1640
 
                *mark_stack_ptr = ptr;
1641
 
                mark_stack_ptr++;
1642
 
            }
1643
 
            else {
1644
 
                mark_stack_overflow = 1;
1645
 
            }
1646
 
        }
1647
 
        return;
1648
 
    }
1649
 
    gc_mark_children(objspace, ptr, lev+1);
 
1758
    push_mark_stack(&objspace->mark_stack, ptr);
1650
1759
}
1651
1760
 
1652
1761
void
1653
1762
rb_gc_mark(VALUE ptr)
1654
1763
{
1655
 
    gc_mark(&rb_objspace, ptr, 0);
 
1764
    gc_mark(&rb_objspace, ptr);
1656
1765
}
1657
1766
 
1658
1767
static void
1659
 
gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
 
1768
gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
1660
1769
{
1661
1770
    register RVALUE *obj = RANY(ptr);
1662
1771
 
1692
1801
          case NODE_RESBODY:
1693
1802
          case NODE_CLASS:
1694
1803
          case NODE_BLOCK_PASS:
1695
 
            gc_mark(objspace, (VALUE)obj->as.node.u2.node, lev);
 
1804
            gc_mark(objspace, (VALUE)obj->as.node.u2.node);
1696
1805
            /* fall through */
1697
1806
          case NODE_BLOCK:      /* 1,3 */
1698
1807
          case NODE_OPTBLOCK:
1706
1815
          case NODE_DEFS:
1707
1816
          case NODE_OP_ASGN1:
1708
1817
          case NODE_ARGS:
1709
 
            gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
 
1818
            gc_mark(objspace, (VALUE)obj->as.node.u1.node);
1710
1819
            /* fall through */
1711
1820
          case NODE_SUPER:      /* 3 */
1712
1821
          case NODE_FCALL:
1733
1842
          case NODE_ALIAS:
1734
1843
          case NODE_VALIAS:
1735
1844
          case NODE_ARGSCAT:
1736
 
            gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
 
1845
            gc_mark(objspace, (VALUE)obj->as.node.u1.node);
1737
1846
            /* fall through */
1738
1847
          case NODE_GASGN:      /* 2 */
1739
1848
          case NODE_LASGN:
1769
1878
          case NODE_SCOPE:      /* 2,3 */
1770
1879
          case NODE_CDECL:
1771
1880
          case NODE_OPT_ARG:
1772
 
            gc_mark(objspace, (VALUE)obj->as.node.u3.node, lev);
 
1881
            gc_mark(objspace, (VALUE)obj->as.node.u3.node);
1773
1882
            ptr = (VALUE)obj->as.node.u2.node;
1774
1883
            goto again;
1775
1884
 
1801
1910
 
1802
1911
          default:              /* unlisted NODE */
1803
1912
            if (is_pointer_to_heap(objspace, obj->as.node.u1.node)) {
1804
 
                gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
 
1913
                gc_mark(objspace, (VALUE)obj->as.node.u1.node);
1805
1914
            }
1806
1915
            if (is_pointer_to_heap(objspace, obj->as.node.u2.node)) {
1807
 
                gc_mark(objspace, (VALUE)obj->as.node.u2.node, lev);
 
1916
                gc_mark(objspace, (VALUE)obj->as.node.u2.node);
1808
1917
            }
1809
1918
            if (is_pointer_to_heap(objspace, obj->as.node.u3.node)) {
1810
 
                gc_mark(objspace, (VALUE)obj->as.node.u3.node, lev);
 
1919
                gc_mark(objspace, (VALUE)obj->as.node.u3.node);
1811
1920
            }
1812
1921
        }
1813
1922
        return;                 /* no need to mark class. */
1814
1923
    }
1815
1924
 
1816
 
    gc_mark(objspace, obj->as.basic.klass, lev);
 
1925
    gc_mark(objspace, obj->as.basic.klass);
1817
1926
    switch (BUILTIN_TYPE(obj)) {
1818
1927
      case T_ICLASS:
1819
1928
      case T_CLASS:
1820
1929
      case T_MODULE:
1821
 
        mark_m_tbl(objspace, RCLASS_M_TBL(obj), lev);
1822
 
        mark_tbl(objspace, RCLASS_IV_TBL(obj), lev);
1823
 
        mark_const_tbl(objspace, RCLASS_CONST_TBL(obj), lev);
 
1930
        mark_m_tbl(objspace, RCLASS_M_TBL(obj));
 
1931
        mark_tbl(objspace, RCLASS_IV_TBL(obj));
 
1932
        mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
1824
1933
        ptr = RCLASS_SUPER(obj);
1825
1934
        goto again;
1826
1935
 
1833
1942
            long i, len = RARRAY_LEN(obj);
1834
1943
            VALUE *ptr = RARRAY_PTR(obj);
1835
1944
            for (i=0; i < len; i++) {
1836
 
                gc_mark(objspace, *ptr++, lev);
 
1945
                gc_mark(objspace, *ptr++);
1837
1946
            }
1838
1947
        }
1839
1948
        break;
1840
1949
 
1841
1950
      case T_HASH:
1842
 
        mark_hash(objspace, obj->as.hash.ntbl, lev);
 
1951
        mark_hash(objspace, obj->as.hash.ntbl);
1843
1952
        ptr = obj->as.hash.ifnone;
1844
1953
        goto again;
1845
1954
 
1866
1975
            long i, len = ROBJECT_NUMIV(obj);
1867
1976
            VALUE *ptr = ROBJECT_IVPTR(obj);
1868
1977
            for (i  = 0; i < len; i++) {
1869
 
                gc_mark(objspace, *ptr++, lev);
 
1978
                gc_mark(objspace, *ptr++);
1870
1979
            }
1871
1980
        }
1872
1981
        break;
1873
1982
 
1874
1983
      case T_FILE:
1875
1984
        if (obj->as.file.fptr) {
1876
 
            gc_mark(objspace, obj->as.file.fptr->pathv, lev);
1877
 
            gc_mark(objspace, obj->as.file.fptr->tied_io_for_writing, lev);
1878
 
            gc_mark(objspace, obj->as.file.fptr->writeconv_asciicompat, lev);
1879
 
            gc_mark(objspace, obj->as.file.fptr->writeconv_pre_ecopts, lev);
1880
 
            gc_mark(objspace, obj->as.file.fptr->encs.ecopts, lev);
1881
 
            gc_mark(objspace, obj->as.file.fptr->write_lock, lev);
 
1985
            gc_mark(objspace, obj->as.file.fptr->pathv);
 
1986
            gc_mark(objspace, obj->as.file.fptr->tied_io_for_writing);
 
1987
            gc_mark(objspace, obj->as.file.fptr->writeconv_asciicompat);
 
1988
            gc_mark(objspace, obj->as.file.fptr->writeconv_pre_ecopts);
 
1989
            gc_mark(objspace, obj->as.file.fptr->encs.ecopts);
 
1990
            gc_mark(objspace, obj->as.file.fptr->write_lock);
1882
1991
        }
1883
1992
        break;
1884
1993
 
1885
1994
      case T_REGEXP:
1886
 
        gc_mark(objspace, obj->as.regexp.src, lev);
1887
 
        break;
 
1995
        ptr = obj->as.regexp.src;
 
1996
        goto again;
1888
1997
 
1889
1998
      case T_FLOAT:
1890
1999
      case T_BIGNUM:
1892
2001
        break;
1893
2002
 
1894
2003
      case T_MATCH:
1895
 
        gc_mark(objspace, obj->as.match.regexp, lev);
 
2004
        gc_mark(objspace, obj->as.match.regexp);
1896
2005
        if (obj->as.match.str) {
1897
2006
            ptr = obj->as.match.str;
1898
2007
            goto again;
1900
2009
        break;
1901
2010
 
1902
2011
      case T_RATIONAL:
1903
 
        gc_mark(objspace, obj->as.rational.num, lev);
1904
 
        gc_mark(objspace, obj->as.rational.den, lev);
1905
 
        break;
 
2012
        gc_mark(objspace, obj->as.rational.num);
 
2013
        ptr = obj->as.rational.den;
 
2014
        goto again;
1906
2015
 
1907
2016
      case T_COMPLEX:
1908
 
        gc_mark(objspace, obj->as.complex.real, lev);
1909
 
        gc_mark(objspace, obj->as.complex.imag, lev);
1910
 
        break;
 
2017
        gc_mark(objspace, obj->as.complex.real);
 
2018
        ptr = obj->as.complex.imag;
 
2019
        goto again;
1911
2020
 
1912
2021
      case T_STRUCT:
1913
2022
        {
1915
2024
            VALUE *ptr = RSTRUCT_PTR(obj);
1916
2025
 
1917
2026
            while (len--) {
1918
 
                gc_mark(objspace, *ptr++, lev);
 
2027
                gc_mark(objspace, *ptr++);
1919
2028
            }
1920
2029
        }
1921
2030
        break;
2441
2550
 
2442
2551
    SET_STACK_END;
2443
2552
 
2444
 
    init_mark_stack(objspace);
2445
 
 
2446
2553
    th->vm->self ? rb_gc_mark(th->vm->self) : rb_vm_mark(th->vm);
2447
2554
 
2448
 
    mark_tbl(objspace, finalizer_table, 0);
 
2555
    mark_tbl(objspace, finalizer_table);
2449
2556
    mark_current_machine_context(objspace, th);
2450
2557
 
2451
2558
    rb_gc_mark_symbols();
2458
2565
    rb_mark_end_proc();
2459
2566
    rb_gc_mark_global_tbl();
2460
2567
 
2461
 
    mark_tbl(objspace, rb_class_tbl, 0);
 
2568
    mark_tbl(objspace, rb_class_tbl);
2462
2569
 
2463
2570
    /* mark generic instance variables for special constants */
2464
2571
    rb_mark_generic_ivar_tbl();
2467
2574
 
2468
2575
    rb_gc_mark_unlinked_live_method_entries(th->vm);
2469
2576
 
2470
 
    /* gc_mark objects whose marking are not completed*/
2471
 
    while (!MARK_STACK_EMPTY) {
2472
 
        if (mark_stack_overflow) {
2473
 
            gc_mark_all(objspace);
2474
 
        }
2475
 
        else {
2476
 
            gc_mark_rest(objspace);
2477
 
        }
2478
 
    }
 
2577
    /* marking-loop */
 
2578
    gc_mark_stacked_objects(objspace);
 
2579
 
2479
2580
    GC_PROF_MARK_TIMER_STOP;
2480
2581
}
2481
2582
 
2955
3056
    finalize_deferred(&rb_objspace);
2956
3057
}
2957
3058
 
2958
 
static int
2959
 
chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
2960
 
{
2961
 
    RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
2962
 
    if ((p->as.basic.flags & (FL_FINALIZE|FL_MARK)) == FL_FINALIZE) {
2963
 
        if (BUILTIN_TYPE(p) != T_ZOMBIE) {
2964
 
            p->as.free.flags = FL_MARK | T_ZOMBIE; /* remain marked */
2965
 
            RDATA(p)->dfree = 0;
2966
 
        }
2967
 
        p->as.free.next = *final_list;
2968
 
        *final_list = p;
2969
 
    }
2970
 
    return ST_CONTINUE;
2971
 
}
2972
 
 
2973
3059
struct force_finalize_list {
2974
3060
    VALUE obj;
2975
3061
    VALUE table;
3001
3087
    RVALUE *final_list = 0;
3002
3088
    size_t i;
3003
3089
 
 
3090
    rest_sweep(objspace);
 
3091
 
3004
3092
    /* run finalizers */
3005
 
    rest_sweep(objspace);
 
3093
    finalize_deferred(objspace);
 
3094
    assert(deferred_final_list == 0);
3006
3095
 
3007
 
    do {
3008
 
        /* XXX: this loop will make no sense */
3009
 
        /* because mark will not be removed */
3010
 
        finalize_deferred(objspace);
3011
 
        mark_tbl(objspace, finalizer_table, 0);
3012
 
        st_foreach(finalizer_table, chain_finalized_object,
3013
 
                   (st_data_t)&deferred_final_list);
3014
 
    } while (deferred_final_list);
3015
3096
    /* force to run finalizer */
3016
3097
    while (finalizer_table->num_entries) {
3017
3098
        struct force_finalize_list *list = 0;
3110
3191
    if (ptr == Qfalse) return Qfalse;
3111
3192
    if (ptr == Qnil) return Qnil;
3112
3193
    if (FIXNUM_P(ptr)) return (VALUE)ptr;
3113
 
    ptr = objid ^ FIXNUM_FLAG;  /* unset FIXNUM_FLAG */
 
3194
    ptr = obj_id_to_ref(objid);
3114
3195
 
3115
3196
    if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
3116
3197
        ID symid = ptr / sizeof(RVALUE);
3193
3274
    if (SPECIAL_CONST_P(obj)) {
3194
3275
        return LONG2NUM((SIGNED_VALUE)obj);
3195
3276
    }
3196
 
    return (VALUE)((SIGNED_VALUE)obj|FIXNUM_FLAG);
 
3277
    return nonspecial_obj_id(obj);
3197
3278
}
3198
3279
 
3199
3280
static int