1
1
// This file is a part of Julia. License is MIT: http://julialang.org/license
2
2
3
+ #include "gc.h"
4
+ #include <inttypes.h>
5
+ #include <stdio.h>
6
+
7
+ #ifdef __cplusplus
8
+ extern "C" {
9
+ #endif
10
+
3
11
// Useful function in debugger to find page/region metadata
4
12
jl_gc_pagemeta_t * jl_gc_page_metadata (void * data )
5
13
{
@@ -45,19 +53,14 @@ JL_DLLEXPORT jl_taggedvalue_t *jl_gc_find_taggedvalue_pool(char *p, size_t *osiz
45
53
return (jl_taggedvalue_t * )tag ;
46
54
}
47
55
48
- #ifdef GC_DEBUG_ENV
49
- #include <inttypes.h>
50
- #include <stdio.h>
51
- #endif
52
-
53
56
// mark verification
54
57
#ifdef GC_VERIFY
55
- static jl_value_t * lostval = 0 ;
58
+ jl_value_t * lostval = NULL ;
56
59
static arraylist_t lostval_parents ;
57
60
static arraylist_t lostval_parents_done ;
58
- static int verifying ;
61
+ int gc_verifying ;
59
62
60
- static void add_lostval_parent (jl_value_t * parent )
63
+ void add_lostval_parent (jl_value_t * parent )
61
64
{
62
65
for (int i = 0 ; i < lostval_parents_done .len ; i ++ ) {
63
66
if ((jl_value_t * )lostval_parents_done .items [i ] == parent )
@@ -70,35 +73,6 @@ static void add_lostval_parent(jl_value_t *parent)
70
73
arraylist_push (& lostval_parents , parent );
71
74
}
72
75
73
- #define verify_val (v ) do { \
74
- if (lostval == (jl_value_t*)(v) && (v) != 0) { \
75
- jl_printf(JL_STDOUT, \
76
- "Found lostval %p at %s:%d oftype: ", \
77
- (void*)(lostval), __FILE__, __LINE__); \
78
- jl_static_show(JL_STDOUT, jl_typeof(v)); \
79
- jl_printf(JL_STDOUT, "\n"); \
80
- } \
81
- } while(0);
82
-
83
-
84
- #define verify_parent (ty , obj , slot , args ...) do { \
85
- if (*(jl_value_t**)(slot) == lostval && \
86
- (jl_value_t*)(obj) != lostval) { \
87
- jl_printf(JL_STDOUT, "Found parent %p %p at %s:%d\n", \
88
- (void*)(ty), (void*)(obj), __FILE__, __LINE__); \
89
- jl_printf(JL_STDOUT, "\tloc %p : ", (void*)(slot)); \
90
- jl_printf(JL_STDOUT, args); \
91
- jl_printf(JL_STDOUT, "\n"); \
92
- jl_printf(JL_STDOUT, "\ttype: "); \
93
- jl_static_show(JL_STDOUT, jl_typeof(obj)); \
94
- jl_printf(JL_STDOUT, "\n"); \
95
- add_lostval_parent((jl_value_t*)(obj)); \
96
- } \
97
- } while(0);
98
-
99
- #define verify_parent1 (ty ,obj ,slot ,arg1 ) verify_parent(ty,obj,slot,arg1)
100
- #define verify_parent2 (ty ,obj ,slot ,arg1 ,arg2 ) verify_parent(ty,obj,slot,arg1,arg2)
101
-
102
76
/*
103
77
How to debug a missing write barrier :
104
78
(or rather how I do it, if you know of a better way update this)
@@ -131,7 +105,7 @@ static arraylist_t bits_save[4];
131
105
static void clear_mark (int bits )
132
106
{
133
107
gcval_t * pv ;
134
- if (!verifying ) {
108
+ if (!gc_verifying ) {
135
109
for (int i = 0 ; i < 4 ; i ++ ) {
136
110
bits_save [i ].len = 0 ;
137
111
}
@@ -141,7 +115,7 @@ static void clear_mark(int bits)
141
115
v = current_heap -> big_objects ;
142
116
while (v != NULL ) {
143
117
void * gcv = & v -> header ;
144
- if (!verifying ) arraylist_push (& bits_save [gc_bits (gcv )], gcv );
118
+ if (!gc_verifying ) arraylist_push (& bits_save [gc_bits (gcv )], gcv );
145
119
gc_bits (gcv ) = bits ;
146
120
v = v -> next ;
147
121
}
@@ -150,7 +124,7 @@ static void clear_mark(int bits)
150
124
v = big_objects_marked ;
151
125
while (v != NULL ) {
152
126
void * gcv = & v -> header ;
153
- if (!verifying ) arraylist_push (& bits_save [gc_bits (gcv )], gcv );
127
+ if (!gc_verifying ) arraylist_push (& bits_save [gc_bits (gcv )], gcv );
154
128
gc_bits (gcv ) = bits ;
155
129
v = v -> next ;
156
130
}
@@ -170,7 +144,7 @@ static void clear_mark(int bits)
170
144
pv = (gcval_t * )(pg -> data + GC_PAGE_OFFSET );
171
145
char * lim = (char * )pv + GC_PAGE_SZ - GC_PAGE_OFFSET - pool -> osize ;
172
146
while ((char * )pv <= lim ) {
173
- if (!verifying ) arraylist_push (& bits_save [gc_bits (pv )], pv );
147
+ if (!gc_verifying ) arraylist_push (& bits_save [gc_bits (pv )], pv );
174
148
gc_bits (pv ) = bits ;
175
149
pv = (gcval_t * )((char * )pv + pool -> osize );
176
150
}
@@ -230,13 +204,13 @@ static void gc_verify_track(void)
230
204
} while (lostval != NULL );
231
205
}
232
206
233
- static void gc_verify (void )
207
+ void gc_verify (void )
234
208
{
235
209
lostval = NULL ;
236
210
lostval_parents .len = 0 ;
237
211
lostval_parents_done .len = 0 ;
238
212
clear_mark (GC_CLEAN );
239
- verifying = 1 ;
213
+ gc_verifying = 1 ;
240
214
pre_mark ();
241
215
post_mark (& finalizer_list , 1 );
242
216
post_mark (& finalizer_list_marked , 1 );
@@ -254,7 +228,7 @@ static void gc_verify(void)
254
228
}
255
229
}
256
230
if (lostval == NULL ) {
257
- verifying = 0 ;
231
+ gc_verifying = 0 ;
258
232
restore (); // we did not miss anything
259
233
return ;
260
234
}
@@ -264,41 +238,17 @@ static void gc_verify(void)
264
238
gc_debug_critical_error ();
265
239
abort ();
266
240
}
267
-
268
- #else
269
- #define gc_verify ()
270
- #define verify_val (v )
271
- #define verify_parent1 (ty ,obj ,slot ,arg1 )
272
- #define verify_parent2 (ty ,obj ,slot ,arg1 ,arg2 )
273
241
#endif
274
242
275
243
#ifdef GC_DEBUG_ENV
276
-
277
- typedef struct {
278
- uint64_t num ;
279
- uint64_t next ;
280
-
281
- uint64_t min ;
282
- uint64_t interv ;
283
- uint64_t max ;
284
- unsigned short random [3 ];
285
- } jl_alloc_num_t ;
286
-
287
- typedef struct {
288
- int sweep_mask ;
289
- int wait_for_debugger ;
290
- jl_alloc_num_t pool ;
291
- jl_alloc_num_t other ;
292
- jl_alloc_num_t print ;
293
- } jl_gc_debug_env_t ;
294
-
295
244
JL_DLLEXPORT jl_gc_debug_env_t jl_gc_debug_env = {
296
245
GC_MARKED_NOESC ,
297
246
0 ,
298
247
{0 , UINT64_MAX , 0 , 0 , 0 , {0 , 0 , 0 }},
299
248
{0 , UINT64_MAX , 0 , 0 , 0 , {0 , 0 , 0 }},
300
249
{0 , UINT64_MAX , 0 , 0 , 0 , {0 , 0 , 0 }}
301
250
};
251
+ static char * gc_stack_lo ;
302
252
303
253
static void gc_debug_alloc_setnext (jl_alloc_num_t * num )
304
254
{
@@ -349,26 +299,12 @@ static int gc_debug_alloc_check(jl_alloc_num_t *num)
349
299
return 1 ;
350
300
}
351
301
352
- static char * gc_stack_lo ;
353
- static void gc_debug_init (void )
354
- {
355
- gc_stack_lo = (char * )gc_get_stack_ptr ();
356
- char * env = getenv ("JULIA_GC_NO_GENERATIONAL" );
357
- if (env && strcmp (env , "0" ) != 0 )
358
- jl_gc_debug_env .sweep_mask = GC_MARKED ;
359
- env = getenv ("JULIA_GC_WAIT_FOR_DEBUGGER" );
360
- jl_gc_debug_env .wait_for_debugger = env && strcmp (env , "0" ) != 0 ;
361
- gc_debug_alloc_init (& jl_gc_debug_env .pool , "POOL" );
362
- gc_debug_alloc_init (& jl_gc_debug_env .other , "OTHER" );
363
- gc_debug_alloc_init (& jl_gc_debug_env .print , "PRINT" );
364
- }
365
-
366
- static inline int gc_debug_check_pool (void )
302
+ int gc_debug_check_pool (void )
367
303
{
368
304
return gc_debug_alloc_check (& jl_gc_debug_env .pool );
369
305
}
370
306
371
- static inline int gc_debug_check_other (void )
307
+ int gc_debug_check_other (void )
372
308
{
373
309
return gc_debug_alloc_check (& jl_gc_debug_env .other );
374
310
}
@@ -393,7 +329,7 @@ void gc_debug_critical_error(void)
393
329
}
394
330
}
395
331
396
- static inline void gc_debug_print (void )
332
+ void gc_debug_print (void )
397
333
{
398
334
if (!gc_debug_alloc_check (& jl_gc_debug_env .print ))
399
335
return ;
@@ -426,21 +362,13 @@ static void gc_scrub_range(char *stack_lo, char *stack_hi)
426
362
}
427
363
}
428
364
429
- static void gc_scrub (char * stack_hi )
365
+ void gc_scrub (char * stack_hi )
430
366
{
431
367
gc_scrub_range (gc_stack_lo , stack_hi );
432
368
}
433
-
434
369
#else
435
-
436
- static inline int gc_debug_check_other (void )
437
- {
438
- return 0 ;
439
- }
440
-
441
- static inline int gc_debug_check_pool (void )
370
+ void gc_debug_critical_error (void )
442
371
{
443
- return 0 ;
444
372
}
445
373
446
374
void gc_debug_print_status (void )
@@ -452,34 +380,14 @@ void gc_debug_print_status(void)
452
380
"(Pool: %" PRIu64 "; Big: %" PRIu64 "); GC: %d\n" ,
453
381
pool_count + big_count , pool_count , big_count , gc_num .pause );
454
382
}
455
-
456
- void gc_debug_critical_error (void )
457
- {
458
- }
459
-
460
- static inline void gc_debug_print (void )
461
- {
462
- }
463
-
464
- static inline void gc_debug_init (void )
465
- {
466
- }
467
-
468
- static void gc_scrub (char * stack_hi )
469
- {
470
- (void )stack_hi ;
471
- }
472
-
473
383
#endif
474
384
475
385
#ifdef OBJPROFILE
476
386
static htable_t obj_counts [3 ];
477
387
static htable_t obj_sizes [3 ];
478
- static inline void objprofile_count (void * ty , int old , int sz )
388
+ void objprofile_count (void * ty , int old , int sz )
479
389
{
480
- #ifdef GC_VERIFY
481
- if (verifying ) return ;
482
- #endif
390
+ if (gc_verifying ) return ;
483
391
if ((intptr_t )ty <= 0x10 ) {
484
392
ty = (void * )jl_buff_tag ;
485
393
}
@@ -500,7 +408,7 @@ static inline void objprofile_count(void *ty, int old, int sz)
500
408
* ((intptr_t * )bp ) += sz ;
501
409
}
502
410
503
- static void objprofile_reset (void )
411
+ void objprofile_reset (void )
504
412
{
505
413
for (int g = 0 ; g < 3 ; g ++ ) {
506
414
htable_reset (& obj_counts [g ], 0 );
@@ -548,7 +456,7 @@ static void objprofile_print(htable_t nums, htable_t sizes)
548
456
}
549
457
}
550
458
551
- static void objprofile_printall (void )
459
+ void objprofile_printall (void )
552
460
{
553
461
jl_printf (JL_STDERR , "Transient mark :\n" );
554
462
objprofile_print (obj_counts [0 ], obj_sizes [0 ]);
@@ -557,28 +465,37 @@ static void objprofile_printall(void)
557
465
jl_printf (JL_STDERR , "Remset :\n" );
558
466
objprofile_print (obj_counts [2 ], obj_sizes [2 ]);
559
467
}
468
+ #endif
560
469
561
- static void objprofile_init (void )
470
+ void gc_debug_init (void )
562
471
{
472
+ #ifdef GC_DEBUG_ENV
473
+ gc_stack_lo = (char * )gc_get_stack_ptr ();
474
+ char * env = getenv ("JULIA_GC_NO_GENERATIONAL" );
475
+ if (env && strcmp (env , "0" ) != 0 )
476
+ jl_gc_debug_env .sweep_mask = GC_MARKED ;
477
+ env = getenv ("JULIA_GC_WAIT_FOR_DEBUGGER" );
478
+ jl_gc_debug_env .wait_for_debugger = env && strcmp (env , "0" ) != 0 ;
479
+ gc_debug_alloc_init (& jl_gc_debug_env .pool , "POOL" );
480
+ gc_debug_alloc_init (& jl_gc_debug_env .other , "OTHER" );
481
+ gc_debug_alloc_init (& jl_gc_debug_env .print , "PRINT" );
482
+ #endif
483
+
484
+ #ifdef GC_VERIFY
485
+ for (int i = 0 ; i < 4 ; i ++ )
486
+ arraylist_new (& bits_save [i ], 0 );
487
+ arraylist_new (& lostval_parents , 0 );
488
+ arraylist_new (& lostval_parents_done , 0 );
489
+ #endif
490
+
491
+ #ifdef OBJPROFILE
563
492
for (int g = 0 ;g < 3 ;g ++ ) {
564
493
htable_new (& obj_counts [g ], 0 );
565
494
htable_new (& obj_sizes [g ], 0 );
566
495
}
567
- }
568
- #else
569
- static inline void objprofile_count (void * ty , int old , int sz )
570
- {
571
- }
572
-
573
- static inline void objprofile_printall (void )
574
- {
575
- }
576
-
577
- static inline void objprofile_reset (void )
578
- {
496
+ #endif
579
497
}
580
498
581
- static void objprofile_init (void )
582
- {
499
+ #ifdef __cplusplus
583
500
}
584
501
#endif
0 commit comments