~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to gc.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2008-01-24 11:42:29 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20080124114229-jw2f87rdxlq6gp11
Tags: 1.9.0.0-2ubuntu1
* Merge from debian unstable, remaining changes:
  - Robustify check for target_os, fixing build failure on lpia.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
  gc.c -
4
4
 
5
5
  $Author: akr $
6
 
  $Date: 2007-08-30 08:12:21 +0900 (木, 30  8月 2007) $
 
6
  $Date: 2007-12-21 15:16:56 +0900 (Fri, 21 Dec 2007) $
7
7
  created at: Tue Oct  5 09:44:46 JST 1993
8
8
 
9
9
  Copyright (C) 1993-2007 Yukihiro Matsumoto
17
17
#include "ruby/st.h"
18
18
#include "ruby/node.h"
19
19
#include "ruby/re.h"
 
20
#include "ruby/io.h"
20
21
#include "vm_core.h"
21
22
#include "gc.h"
22
23
#include <stdio.h>
170
171
#endif
171
172
 
172
173
#if defined(DJGPP) || defined(_WIN32_WCE)
173
 
static unsigned int STACK_LEVEL_MAX = 65535;
174
 
#elif defined(__human68k__)
175
 
unsigned int _stacksize = 262144;
176
 
# define STACK_LEVEL_MAX (_stacksize - 4096)
177
 
# undef HAVE_GETRLIMIT
178
 
#elif defined(HAVE_GETRLIMIT) || defined(_WIN32)
179
 
static unsigned int STACK_LEVEL_MAX = 655300;
 
174
size_t rb_gc_stack_maxsize = 65535*sizeof(VALUE);
180
175
#else
181
 
# define STACK_LEVEL_MAX 655300
 
176
size_t rb_gc_stack_maxsize = 655300*sizeof(VALUE);
182
177
#endif
183
178
 
184
179
 
578
573
 
579
574
#define STACK_START (th->machine_stack_start)
580
575
#define STACK_END (th->machine_stack_end)
 
576
#define STACK_LEVEL_MAX (th->machine_stack_maxsize/sizeof(VALUE))
581
577
 
582
578
#if defined(sparc) || defined(__sparc__)
583
579
# define STACK_LENGTH  (STACK_START - STACK_END + 0x80)
610
606
 
611
607
#define GC_WATER_MARK 512
612
608
 
613
 
#define CHECK_STACK(ret) do {\
614
 
    SET_STACK_END;\
615
 
    (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\
616
 
} while (0)
617
 
 
618
609
int
619
610
ruby_stack_length(VALUE **p)
620
611
{
627
618
int
628
619
ruby_stack_check(void)
629
620
{
630
 
  int ret;
631
 
  rb_thread_t *th = GET_THREAD();
632
 
  CHECK_STACK(ret);
633
 
  return ret;
 
621
    int ret;
 
622
    rb_thread_t *th = GET_THREAD();
 
623
    SET_STACK_END;
 
624
    ret = STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK;
 
625
#ifdef __ia64
 
626
    if (!ret) {
 
627
        ret = (VALUE*)rb_ia64_bsp() - th->machine_register_stack_start >
 
628
              th->machine_register_stack_maxsize/sizeof(VALUE) + GC_WATER_MARK;
 
629
    }
 
630
#endif
 
631
    return ret;
634
632
}
635
633
 
636
634
static void
712
710
    VALUE *p;
713
711
 
714
712
    p = (mark_stack_ptr - mark_stack) + tmp_arry;
715
 
    MEMCPY(tmp_arry, mark_stack, VALUE, MARK_STACK_MAX);
 
713
    MEMCPY(tmp_arry, mark_stack, VALUE, p - tmp_arry);
716
714
 
717
715
    init_mark_stack();
718
 
    while(p != tmp_arry){
 
716
    while (p != tmp_arry) {
719
717
        p--;
720
718
        gc_mark_children(*p, 0);
721
719
    }
784
782
}
785
783
 
786
784
static int
 
785
mark_key(VALUE key, VALUE value, int lev)
 
786
{
 
787
    gc_mark(key, lev);
 
788
    return ST_CONTINUE;
 
789
}
 
790
 
 
791
static void
 
792
mark_set(st_table *tbl, int lev)
 
793
{
 
794
    if (!tbl) return;
 
795
    st_foreach(tbl, mark_key, lev);
 
796
}
 
797
 
 
798
void
 
799
rb_mark_set(st_table *tbl)
 
800
{
 
801
    mark_set(tbl, 0);
 
802
}
 
803
 
 
804
static int
787
805
mark_keyvalue(VALUE key, VALUE value, int lev)
788
806
{
789
807
    gc_mark(key, lev);
924
942
          case NODE_MODULE:
925
943
          case NODE_ALIAS:
926
944
          case NODE_VALIAS:
 
945
          case NODE_ARGSCAT:
927
946
            gc_mark((VALUE)obj->as.node.u1.node, lev);
928
947
            /* fall through */
929
948
          case NODE_FBODY:      /* 2 */
930
 
          case NODE_NOT:
931
949
          case NODE_GASGN:
932
950
          case NODE_LASGN:
933
951
          case NODE_DASGN:
1012
1030
      case T_ICLASS:
1013
1031
      case T_CLASS:
1014
1032
      case T_MODULE:
1015
 
        mark_tbl(obj->as.klass.m_tbl, lev);
1016
 
        mark_tbl(obj->as.klass.iv_tbl, lev);
1017
 
        ptr = obj->as.klass.super;
 
1033
        mark_tbl(RCLASS_M_TBL(obj), lev);
 
1034
        mark_tbl(RCLASS_IV_TBL(obj), lev);
 
1035
        ptr = RCLASS_SUPER(obj);
1018
1036
        goto again;
1019
1037
 
1020
1038
      case T_ARRAY:
1049
1067
        break;
1050
1068
 
1051
1069
      case T_OBJECT:
1052
 
        mark_tbl(obj->as.object.iv_tbl, lev);
 
1070
        {
 
1071
            long i, len = ROBJECT_LEN(obj);
 
1072
            VALUE *ptr = ROBJECT_PTR(obj);
 
1073
            for (i  = 0; i < len; i++) {
 
1074
                gc_mark(*ptr++, lev);
 
1075
            }
 
1076
        }
1053
1077
        break;
1054
1078
 
1055
1079
      case T_FILE:
 
1080
        if (obj->as.file.fptr)
 
1081
            gc_mark(obj->as.file.fptr->tied_io_for_writing, lev);
 
1082
        break;
 
1083
 
1056
1084
      case T_REGEXP:
1057
1085
      case T_FLOAT:
1058
1086
      case T_BIGNUM:
1248
1276
 
1249
1277
    switch (RANY(obj)->as.basic.flags & T_MASK) {
1250
1278
      case T_OBJECT:
1251
 
        if (RANY(obj)->as.object.iv_tbl) {
1252
 
            st_free_table(RANY(obj)->as.object.iv_tbl);
 
1279
        if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
 
1280
            RANY(obj)->as.object.as.heap.ptr) {
 
1281
            RUBY_CRITICAL(free(RANY(obj)->as.object.as.heap.ptr));
1253
1282
        }
1254
1283
        break;
1255
1284
      case T_MODULE:
1256
1285
      case T_CLASS:
1257
1286
        rb_clear_cache_by_class((VALUE)obj);
1258
 
        st_free_table(RANY(obj)->as.klass.m_tbl);
1259
 
        if (RANY(obj)->as.object.iv_tbl) {
1260
 
            st_free_table(RANY(obj)->as.object.iv_tbl);
1261
 
        }
 
1287
        st_free_table(RCLASS_M_TBL(obj));
 
1288
        if (RCLASS_IV_TBL(obj)) {
 
1289
            st_free_table(RCLASS_IV_TBL(obj));
 
1290
        }
 
1291
        if (RCLASS_IV_INDEX_TBL(obj)) {
 
1292
            st_free_table(RCLASS_IV_INDEX_TBL(obj));
 
1293
        }
 
1294
        RUBY_CRITICAL(free(RANY(obj)->as.klass.ptr));
1262
1295
        break;
1263
1296
      case T_STRING:
1264
1297
        rb_str_free(obj);
1311
1344
        break;
1312
1345
 
1313
1346
      case T_BIGNUM:
1314
 
        if (RANY(obj)->as.bignum.digits) {
1315
 
            RUBY_CRITICAL(free(RANY(obj)->as.bignum.digits));
 
1347
        if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
 
1348
            RUBY_CRITICAL(free(RBIGNUM_DIGITS(obj)));
1316
1349
        }
1317
1350
        break;
1318
1351
      case T_NODE:
1424
1457
#endif
1425
1458
}
1426
1459
 
 
1460
void rb_gc_mark_encodings(void);
 
1461
 
1427
1462
static int
1428
1463
garbage_collect(void)
1429
1464
{
1458
1493
 
1459
1494
    rb_gc_mark_threads();
1460
1495
    rb_gc_mark_symbols();
 
1496
    rb_gc_mark_encodings();
1461
1497
 
1462
1498
    /* mark protected global variables */
1463
1499
    for (list = global_List; list; list = list->next) {
1489
1525
    return Qtrue;
1490
1526
}
1491
1527
 
 
1528
int
 
1529
rb_garbage_collect(void)
 
1530
{
 
1531
    return garbage_collect();
 
1532
}
 
1533
 
1492
1534
void
1493
1535
rb_gc_mark_machine_stack(rb_thread_t *th)
1494
1536
{
1537
1579
void
1538
1580
ruby_set_stack_size(size_t size)
1539
1581
{
1540
 
#ifndef STACK_LEVEL_MAX
1541
 
    STACK_LEVEL_MAX = size/sizeof(VALUE);
1542
 
#endif
 
1582
    rb_gc_stack_maxsize = size;
1543
1583
}
1544
1584
 
1545
1585
void
1599
1639
            unsigned int space = rlim.rlim_cur/5;
1600
1640
 
1601
1641
            if (space > 1024*1024) space = 1024*1024;
1602
 
            STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE);
 
1642
            rb_gc_stack_maxsize = rlim.rlim_cur - space;
1603
1643
        }
1604
1644
    }
1605
1645
#endif
1631
1671
            unsigned int space = rlim.rlim_cur/5;
1632
1672
 
1633
1673
            if (space > 1024*1024) space = 1024*1024;
1634
 
            STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE);
 
1674
            rb_gc_stack_maxsize = rlim.rlim_cur - space;
1635
1675
        }
1636
1676
    }
1637
1677
#elif defined _WIN32
1644
1684
            size = (char *)mi.BaseAddress - (char *)mi.AllocationBase;
1645
1685
            space = size / 5;
1646
1686
            if (space > 1024*1024) space = 1024*1024;
1647
 
            STACK_LEVEL_MAX = (size - space) / sizeof(VALUE);
 
1687
            rb_gc_stack_maxsize = size - space;
1648
1688
        }
1649
1689
    }
1650
1690
#endif
1691
1731
}
1692
1732
 
1693
1733
static VALUE
1694
 
os_live_obj(void)
 
1734
os_obj_of(VALUE of)
1695
1735
{
1696
1736
    int i;
1697
1737
    int n = 0;
1702
1742
        p = heaps[i].slot; pend = p + heaps[i].limit;
1703
1743
        for (;p < pend; p++) {
1704
1744
            if (p->as.basic.flags) {
1705
 
                switch (TYPE(p)) {
 
1745
                switch (BUILTIN_TYPE(p)) {
 
1746
                  case T_NONE:
1706
1747
                  case T_ICLASS:
1707
1748
                  case T_NODE:
1708
1749
                  case T_VALUES:
1711
1752
                    if (FL_TEST(p, FL_SINGLETON)) continue;
1712
1753
                  default:
1713
1754
                    if (!p->as.basic.klass) continue;
1714
 
                    rb_yield((VALUE)p);
1715
 
                    n++;
1716
 
                }
1717
 
            }
1718
 
        }
1719
 
    }
1720
 
 
1721
 
    return INT2FIX(n);
1722
 
}
1723
 
 
1724
 
static VALUE
1725
 
os_obj_of(VALUE of)
1726
 
{
1727
 
    int i;
1728
 
    int n = 0;
1729
 
 
1730
 
    for (i = 0; i < heaps_used; i++) {
1731
 
        RVALUE *p, *pend;
1732
 
 
1733
 
        p = heaps[i].slot; pend = p + heaps[i].limit;
1734
 
        for (;p < pend; p++) {
1735
 
            if (p->as.basic.flags) {
1736
 
                switch (TYPE(p)) {
1737
 
                  case T_ICLASS:
1738
 
                  case T_NODE:
1739
 
                    continue;
1740
 
                  case T_CLASS:
1741
 
                    if (FL_TEST(p, FL_SINGLETON)) continue;
1742
 
                  default:
1743
 
                    if (!p->as.basic.klass) continue;
1744
 
                    if (rb_obj_is_kind_of((VALUE)p, of)) {
 
1755
                    if (!of || rb_obj_is_kind_of((VALUE)p, of)) {
1745
1756
                        rb_yield((VALUE)p);
1746
1757
                        n++;
1747
1758
                    }
1793
1804
 
1794
1805
    rb_secure(4);
1795
1806
    if (rb_scan_args(argc, argv, "01", &of) == 0) {
1796
 
        return os_live_obj();
1797
 
    }
1798
 
    else {
1799
 
        return os_obj_of(of);
1800
 
    }
 
1807
        of = 0;
 
1808
    }
 
1809
    return os_obj_of(of);
1801
1810
}
1802
1811
 
1803
1812
static VALUE finalizers;
1921
1930
}
1922
1931
 
1923
1932
static VALUE
1924
 
run_single_final(VALUE *args)
 
1933
run_single_final(VALUE arg)
1925
1934
{
 
1935
    VALUE *args = (VALUE *)arg;
1926
1936
    rb_eval_cmd(args[0], args[1], (int)args[2]);
1927
1937
    return Qnil;
1928
1938
}
1937
1947
    objid = rb_obj_id(obj);     /* make obj into id */
1938
1948
    rb_thread_critical = Qtrue;
1939
1949
    args[1] = 0;
 
1950
    if (RARRAY_LEN(finalizers) > 0) {
 
1951
        args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
 
1952
    }
1940
1953
    args[2] = (VALUE)rb_safe_level();
1941
1954
    for (i=0; i<RARRAY_LEN(finalizers); i++) {
1942
1955
        args[0] = RARRAY_PTR(finalizers)[i];
1943
 
        if (!args[1]) args[1] = rb_ary_new3(1, objid);
1944
 
        rb_protect((VALUE(*)(VALUE))run_single_final, (VALUE)args, &status);
 
1956
        rb_protect(run_single_final, (VALUE)args, &status);
1945
1957
    }
1946
1958
    if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {
 
1959
        if (!args[1] && RARRAY_LEN(table) > 0) {
 
1960
            args[1] = rb_obj_freeze(rb_ary_new3(1, objid));
 
1961
        }
1947
1962
        for (i=0; i<RARRAY_LEN(table); i++) {
1948
1963
            VALUE final = RARRAY_PTR(table)[i];
1949
1964
            args[0] = RARRAY_PTR(final)[1];
1950
 
            if (!args[1]) args[1] = rb_ary_new3(1, objid);
1951
1965
            args[2] = FIX2INT(RARRAY_PTR(final)[0]);
1952
 
            rb_protect((VALUE(*)(VALUE))run_single_final, (VALUE)args, &status);
 
1966
            rb_protect(run_single_final, (VALUE)args, &status);
1953
1967
        }
1954
1968
    }
1955
1969
    rb_thread_critical = critical_save;
2063
2077
        return ID2SYM(symid);
2064
2078
    }
2065
2079
 
2066
 
    if (!is_pointer_to_heap((void *)ptr)|| BUILTIN_TYPE(ptr) >= T_BLOCK) {
 
2080
    if (!is_pointer_to_heap((void *)ptr) ||
 
2081
        BUILTIN_TYPE(ptr) >= T_VALUES || BUILTIN_TYPE(ptr) == T_ICLASS) {
2067
2082
        rb_raise(rb_eRangeError, "%p is not id value", p0);
2068
2083
    }
2069
2084
    if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) {
2140
2155
}
2141
2156
 
2142
2157
/*
 
2158
 *  call-seq:
 
2159
 *     ObjectSpace.count_objects([result_hash]) -> hash
 
2160
 *
 
2161
 *  Counts objects for each type.
 
2162
 *
 
2163
 *  It returns a hash as:
 
2164
 *  {:TOTAL=>10000, :FREE=>3011, :T_OBJECT=>6, :T_CLASS=>404, ...}
 
2165
 *
 
2166
 *  If the optional argument, result_hash, is given,
 
2167
 *  it is overwritten and returned.
 
2168
 *  This is intended to avoid probe effect.
 
2169
 *
 
2170
 *  The contents of the returned hash is implementation defined.
 
2171
 *  It may be changed in future.
 
2172
 *
 
2173
 *  This method is not expected to work except C Ruby.
 
2174
 *
 
2175
 */
 
2176
 
 
2177
static VALUE
 
2178
count_objects(int argc, VALUE *argv, VALUE os)
 
2179
{
 
2180
    long counts[T_MASK+1];
 
2181
    long freed = 0;
 
2182
    long total = 0;
 
2183
    int i;
 
2184
    VALUE hash;
 
2185
 
 
2186
    if (rb_scan_args(argc, argv, "01", &hash) == 1) {
 
2187
        if (TYPE(hash) != T_HASH)
 
2188
            rb_raise(rb_eTypeError, "non-hash given");
 
2189
    }
 
2190
 
 
2191
    for (i = 0; i <= T_MASK; i++) {
 
2192
        counts[i] = 0;
 
2193
    }
 
2194
 
 
2195
    for (i = 0; i < heaps_used; i++) {
 
2196
        RVALUE *p, *pend;
 
2197
 
 
2198
        p = heaps[i].slot; pend = p + heaps[i].limit;
 
2199
        for (;p < pend; p++) {
 
2200
            if (p->as.basic.flags) {
 
2201
                counts[BUILTIN_TYPE(p)]++;
 
2202
            }
 
2203
            else {
 
2204
                freed++;
 
2205
            }
 
2206
        }
 
2207
        total += heaps[i].limit;
 
2208
    }
 
2209
 
 
2210
    if (hash == Qnil)
 
2211
        hash = rb_hash_new();
 
2212
    rb_hash_aset(hash, ID2SYM(rb_intern("TOTAL")), LONG2NUM(total));
 
2213
    rb_hash_aset(hash, ID2SYM(rb_intern("FREE")), LONG2NUM(freed));
 
2214
    for (i = 0; i <= T_MASK; i++) {
 
2215
        VALUE type;
 
2216
        switch (i) {
 
2217
          case T_NONE:          type = ID2SYM(rb_intern("T_NONE")); break;
 
2218
          case T_NIL:           type = ID2SYM(rb_intern("T_NIL")); break;
 
2219
          case T_OBJECT:        type = ID2SYM(rb_intern("T_OBJECT")); break;
 
2220
          case T_CLASS:         type = ID2SYM(rb_intern("T_CLASS")); break;
 
2221
          case T_ICLASS:        type = ID2SYM(rb_intern("T_ICLASS")); break;
 
2222
          case T_MODULE:        type = ID2SYM(rb_intern("T_MODULE")); break;
 
2223
          case T_FLOAT:         type = ID2SYM(rb_intern("T_FLOAT")); break;
 
2224
          case T_STRING:        type = ID2SYM(rb_intern("T_STRING")); break;
 
2225
          case T_REGEXP:        type = ID2SYM(rb_intern("T_REGEXP")); break;
 
2226
          case T_ARRAY:         type = ID2SYM(rb_intern("T_ARRAY")); break;
 
2227
          case T_FIXNUM:        type = ID2SYM(rb_intern("T_FIXNUM")); break;
 
2228
          case T_HASH:          type = ID2SYM(rb_intern("T_HASH")); break;
 
2229
          case T_STRUCT:        type = ID2SYM(rb_intern("T_STRUCT")); break;
 
2230
          case T_BIGNUM:        type = ID2SYM(rb_intern("T_BIGNUM")); break;
 
2231
          case T_FILE:          type = ID2SYM(rb_intern("T_FILE")); break;
 
2232
          case T_TRUE:          type = ID2SYM(rb_intern("T_TRUE")); break;
 
2233
          case T_FALSE:         type = ID2SYM(rb_intern("T_FALSE")); break;
 
2234
          case T_DATA:          type = ID2SYM(rb_intern("T_DATA")); break;
 
2235
          case T_MATCH:         type = ID2SYM(rb_intern("T_MATCH")); break;
 
2236
          case T_SYMBOL:        type = ID2SYM(rb_intern("T_SYMBOL")); break;
 
2237
          case T_VALUES:        type = ID2SYM(rb_intern("T_VALUES")); break;
 
2238
          case T_BLOCK:         type = ID2SYM(rb_intern("T_BLOCK")); break;
 
2239
          case T_UNDEF:         type = ID2SYM(rb_intern("T_UNDEF")); break;
 
2240
          case T_NODE:          type = ID2SYM(rb_intern("T_NODE")); break;
 
2241
          default:              type = INT2NUM(i); break;
 
2242
        }
 
2243
        if (counts[i])
 
2244
            rb_hash_aset(hash, type, LONG2NUM(counts[i]));
 
2245
    }
 
2246
 
 
2247
    return hash;
 
2248
}
 
2249
 
 
2250
/*
2143
2251
 *  The <code>GC</code> module provides an interface to Ruby's mark and
2144
2252
 *  sweep garbage collection mechanism. Some of the underlying methods
2145
2253
 *  are also available via the <code>ObjectSpace</code> module.
2184
2292
    rb_define_method(rb_mKernel, "hash", rb_obj_id, 0);
2185
2293
    rb_define_method(rb_mKernel, "__id__", rb_obj_id, 0);
2186
2294
    rb_define_method(rb_mKernel, "object_id", rb_obj_id, 0);
 
2295
 
 
2296
    rb_define_module_function(rb_mObSpace, "count_objects", count_objects, -1);
2187
2297
}