6
$Date: 2007-05-30 00:49:30 +0900 (水, 30 5月 2007) $
6
$Date: 2007-08-30 08:12:21 +0900 (木, 30 8月 2007) $
7
7
created at: Tue Oct 5 09:44:46 JST 1993
9
Copyright (C) 1993-2003 Yukihiro Matsumoto
9
Copyright (C) 1993-2007 Yukihiro Matsumoto
10
10
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
11
11
Copyright (C) 2000 Information-technology Promotion Agency, Japan
13
13
**********************************************************************/
15
#include "ruby/ruby.h"
16
#include "ruby/signal.h"
18
#include "ruby/node.h"
23
23
#include <setjmp.h>
35
35
#include <windows.h>
38
#ifdef HAVE_VALGRIND_MEMCHECK_H
39
# include <valgrind/memcheck.h>
40
# ifndef VALGRIND_MAKE_MEM_DEFINED
41
# define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE(p, n)
43
# ifndef VALGRIND_MAKE_MEM_UNDEFINED
44
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE(p, n)
47
# define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
48
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) /* empty */
38
51
int rb_io_fptr_finalize(struct rb_io_t*);
40
53
#if !defined(setjmp) && defined(HAVE__SETJMP)
281
296
if (!ptr) return ruby_xmalloc(size);
282
297
if (size == 0) size = 1;
283
298
malloc_increase += size;
284
if (gc_stress) garbage_collect();
299
if (ruby_gc_stress) garbage_collect();
285
300
RUBY_CRITICAL(mem = realloc(ptr, size));
287
302
if (garbage_collect()) {
438
453
heaps[heaps_used].membase = p;
439
454
if ((VALUE)p % sizeof(RVALUE) == 0)
442
p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE)));
457
p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE)));
443
458
heaps[heaps_used].slot = p;
444
459
heaps[heaps_used].limit = heap_slots;
476
491
MEMZERO((void*)obj, RVALUE, 1);
478
RANY(obj)->file = ruby_sourcefile;
479
RANY(obj)->line = ruby_sourceline;
493
RANY(obj)->file = rb_sourcefile();
494
RANY(obj)->line = rb_sourceline();
546
rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
548
NODE *n = (NODE*)rb_newobj();
551
nd_set_type(n, type);
531
561
rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
540
570
return (VALUE)data;
543
#define SET_STACK_END rb_gc_set_stack_end(&th->machine_stack_end)
574
#define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine_stack_end), th->machine_register_stack_end = rb_ia64_bsp())
576
#define SET_STACK_END SET_MACHINE_STACK_END(&th->machine_stack_end)
544
579
#define STACK_START (th->machine_stack_start)
545
580
#define STACK_END (th->machine_stack_end)
1068
1103
RVALUE *tmp = p->as.free.next;
1069
1104
run_final((VALUE)p);
1070
1105
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
1106
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
1071
1107
p->as.free.flags = 0;
1072
1108
p->as.free.next = freelist;
1106
1142
unsigned long live = 0;
1108
mark_source_filename(ruby_sourcefile);
1143
unsigned long free_min = 0;
1145
for (i = 0; i < heaps_used; i++) {
1146
free_min += heaps[i].limit;
1148
free_min = free_min * 0.2;
1149
if (free_min < FREE_MIN)
1150
free_min = FREE_MIN;
1109
1152
if (source_filenames) {
1110
1153
st_foreach(source_filenames, sweep_source_filename, 0);
1181
1225
rb_gc_force_recycle(VALUE p)
1227
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
1183
1228
RANY(p)->as.free.flags = 0;
1184
1229
RANY(p)->as.free.next = freelist;
1185
1230
freelist = RANY(p);
1339
1384
void rb_vm_mark(void *ptr);
1387
mark_current_machine_context(rb_thread_t *th)
1389
jmp_buf save_regs_gc_mark;
1390
VALUE *stack_start, *stack_end;
1393
#if STACK_GROW_DIRECTION < 0
1394
stack_start = th->machine_stack_end;
1395
stack_end = th->machine_stack_start;
1396
#elif STACK_GROW_DIRECTION > 0
1397
stack_start = th->machine_stack_start;
1398
stack_end = th->machine_stack_end + 1;
1400
if (th->machine_stack_end < th->machine_stack_start) {
1401
stack_start = th->machine_stack_end;
1402
stack_end = th->machine_stack_start;
1405
stack_start = th->machine_stack_start;
1406
stack_end = th->machine_stack_end + 1;
1410
FLUSH_REGISTER_WINDOWS;
1411
/* This assumes that all registers are saved into the jmp_buf (and stack) */
1412
setjmp(save_regs_gc_mark);
1413
mark_locations_array((VALUE*)save_regs_gc_mark,
1414
sizeof(save_regs_gc_mark) / sizeof(VALUE));
1416
mark_locations_array(stack_start, stack_end - stack_start);
1418
mark_locations_array(th->machine_register_stack_start,
1419
th->machine_register_stack_end - th->machine_register_stack_start);
1421
#if defined(__human68k__) || defined(__mc68000__)
1422
mark_locations_array((VALUE*)((char*)STACK_END + 2),
1423
(STACK_START - STACK_END));
1342
1428
garbage_collect(void)
1344
1430
struct gc_list *list;
1345
jmp_buf save_regs_gc_mark;
1346
1431
rb_thread_t *th = GET_THREAD();
1348
1433
if (GC_NOTIFY) printf("start garbage_collect()\n");
1369
1454
mark_tbl(finalizer_table, 0);
1372
FLUSH_REGISTER_WINDOWS;
1373
/* This assumes that all registers are saved into the jmp_buf (and stack) */
1374
setjmp(save_regs_gc_mark);
1375
mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
1377
#if STACK_GROW_DIRECTION < 0
1378
rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
1379
#elif STACK_GROW_DIRECTION > 0
1380
rb_gc_mark_locations(th->machine_stack_start, th->machine_stack_end + 1);
1382
if (th->machine_stack_end < th->machine_stack_start)
1383
rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
1385
rb_gc_mark_locations(th->machine_stack_start, th->machine_stack_end + 1);
1388
/* mark backing store (flushed register window on the stack) */
1389
/* the basic idea from guile GC code */
1393
#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF)
1394
_Unwind_Context *unwctx = _UNW_createContextForSelf();
1398
mark_locations_array((VALUE*)&ctx.uc_mcontext,
1399
((size_t)(sizeof(VALUE)-1 + sizeof ctx.uc_mcontext)/sizeof(VALUE)));
1400
#if defined(HAVE_UNWIND_H) && defined(HAVE__UNW_CREATECONTEXTFORSELF)
1401
_UNW_currentContext(unwctx);
1402
bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP);
1403
top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE);
1404
_UNW_destroyContext(unwctx);
1406
bot = (VALUE*)__libc_ia64_register_backing_store_base;
1407
top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE;
1409
rb_gc_mark_locations(bot, top);
1412
#if defined(__human68k__) || defined(__mc68000__)
1413
rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
1414
(VALUE*)((char*)STACK_START + 2));
1457
mark_current_machine_context(th);
1416
1459
rb_gc_mark_threads();
1417
1460
rb_gc_mark_symbols();
1432
1475
rb_gc_mark_parser();
1434
1477
/* gc_mark objects whose marking are not completed*/
1435
while (!MARK_STACK_EMPTY){
1436
if (mark_stack_overflow){
1478
while (!MARK_STACK_EMPTY) {
1479
if (mark_stack_overflow) {
1450
yarv_machine_stack_mark(rb_thread_t *th)
1493
rb_gc_mark_machine_stack(rb_thread_t *th)
1452
1495
#if STACK_GROW_DIRECTION < 0
1453
1496
rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
1961
2008
else if (RANY(p)->as.data.dfree) {
1962
2009
(*RANY(p)->as.data.dfree)(DATA_PTR(p));
2011
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
1965
2013
else if (BUILTIN_TYPE(p) == T_FILE) {
1966
2014
if (rb_io_fptr_finalize(RANY(p)->as.file.fptr)) {
1967
2015
p->as.free.flags = 0;
2016
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
2010
2059
if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
2011
2060
ID symid = ptr / sizeof(RVALUE);
2012
2061
if (rb_id2name(symid) == 0)
2013
rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
2062
rb_raise(rb_eRangeError, "%p is not symbol id value", p0);
2014
2063
return ID2SYM(symid);
2061
2110
* nil 00000000000000000000000000000100
2062
2111
* undef 00000000000000000000000000000110
2063
2112
* symbol ssssssssssssssssssssssss00001110
2064
* object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE)
2113
* object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE))
2065
2114
* fixnum fffffffffffffffffffffffffffffff1
2067
2116
* object_id space
2070
2119
* true 00000000000000000000000000000010
2071
2120
* nil 00000000000000000000000000000100
2072
2121
* undef 00000000000000000000000000000110
2073
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S =
2122
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
2074
2123
* object oooooooooooooooooooooooooooooo0 o...o % A = 0
2075
2124
* fixnum fffffffffffffffffffffffffffffff1 bignum if required
2085
2134
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
2087
2136
if (SPECIAL_CONST_P(obj)) {
2088
return LONG2NUM((long)obj);
2137
return LONG2NUM((SIGNED_VALUE)obj);
2090
return (VALUE)((long)obj|FIXNUM_FLAG);
2139
return (VALUE)((SIGNED_VALUE)obj|FIXNUM_FLAG);