@@ -516,67 +516,66 @@ static inline void objprofile_count(void* ty, int old, int sz)
516
516
517
517
#define inc_sat (v ,s ) v = (v) >= s ? s : (v)+1
518
518
519
- static inline int gc_setmark_big (void * o , int mark_mode )
519
+ static inline int gc_setmark_big (void * o , int bits )
520
520
{
521
+ int mark_mode = GC_MARKED_NOESC ;
521
522
#ifdef GC_VERIFY
522
523
if (verifying ) {
523
524
_gc_setmark (o , mark_mode );
524
525
return 0 ;
525
526
}
526
527
#endif
527
528
bigval_t * hdr = bigval_header (o );
528
- int bits = gc_bits (o );
529
- if (bits == GC_QUEUED || bits == GC_MARKED )
530
- mark_mode = GC_MARKED ;
531
- if ((mark_mode == GC_MARKED ) & (bits != GC_MARKED )) {
532
- // Move hdr from big_objects list to big_objects_marked list
533
- * hdr -> prev = hdr -> next ;
534
- if (hdr -> next )
535
- hdr -> next -> prev = hdr -> prev ;
536
- hdr -> next = big_objects_marked ;
537
- hdr -> prev = & big_objects_marked ;
538
- if (big_objects_marked )
539
- big_objects_marked -> prev = & hdr -> next ;
540
- big_objects_marked = hdr ;
541
- }
542
529
if (!(bits & GC_MARKED )) {
530
+ if (bits == GC_QUEUED )
531
+ mark_mode = GC_MARKED ;
532
+ if ((mark_mode == GC_MARKED ) & (bits != GC_MARKED )) {
533
+ // Move hdr from big_objects list to big_objects_marked list
534
+ * hdr -> prev = hdr -> next ;
535
+ if (hdr -> next )
536
+ hdr -> next -> prev = hdr -> prev ;
537
+ hdr -> next = big_objects_marked ;
538
+ hdr -> prev = & big_objects_marked ;
539
+ if (big_objects_marked )
540
+ big_objects_marked -> prev = & hdr -> next ;
541
+ big_objects_marked = hdr ;
542
+ }
543
543
if (mark_mode == GC_MARKED )
544
544
perm_scanned_bytes += hdr -> sz & ~3 ;
545
545
else
546
546
scanned_bytes += hdr -> sz & ~3 ;
547
547
#ifdef OBJPROFILE
548
548
objprofile_count (jl_typeof (o ), mark_mode == GC_MARKED , hdr -> sz & ~3 );
549
549
#endif
550
+ _gc_setmark (o , mark_mode );
550
551
}
551
- _gc_setmark (o , mark_mode );
552
552
verify_val (jl_valueof (o ));
553
553
return mark_mode ;
554
554
}
555
555
556
- static inline int gc_setmark_pool (void * o , int mark_mode )
556
+ static inline int gc_setmark_pool (void * o , int bits )
557
557
{
558
+ int mark_mode = GC_MARKED_NOESC ;
558
559
#ifdef GC_VERIFY
559
560
if (verifying ) {
560
561
_gc_setmark (o , mark_mode );
561
562
return mark_mode ;
562
563
}
563
564
#endif
564
- gcpage_t * page = page_metadata (o );
565
- int bits = gc_bits (o );
566
- if (bits == GC_QUEUED || bits == GC_MARKED ) {
567
- mark_mode = GC_MARKED ;
568
- }
569
565
if (!(bits & GC_MARKED )) {
566
+ if (bits == GC_QUEUED )
567
+ mark_mode = GC_MARKED ;
568
+ gcpage_t * page = page_metadata (o );
570
569
if (mark_mode == GC_MARKED )
571
570
perm_scanned_bytes += page -> osize ;
572
571
else
573
572
scanned_bytes += page -> osize ;
574
573
#ifdef OBJPROFILE
575
574
objprofile_count (jl_typeof (o ), mark_mode == GC_MARKED , page -> osize );
576
575
#endif
576
+ _gc_setmark (o , mark_mode );
577
+ page -> gc_bits |= mark_mode ;
577
578
}
578
- _gc_setmark (o , mark_mode );
579
- page -> gc_bits |= mark_mode ;
580
579
verify_val (jl_valueof (o ));
581
580
return mark_mode ;
582
581
}
@@ -601,14 +600,19 @@ static inline int gc_setmark(jl_value_t *v, int sz, int mark_mode)
601
600
inline void gc_setmark_buf (void * o , int mark_mode )
602
601
{
603
602
buff_t * buf = gc_val_buf (o );
603
+ int bits = gc_bits (buf );
604
+ if (mark_mode == GC_MARKED && bits != GC_MARKED ) {
605
+ _gc_setmark (buf , GC_QUEUED );
606
+ bits = GC_QUEUED ;
607
+ }
604
608
#ifdef MEMDEBUG
605
- gc_setmark_big (buf , mark_mode );
609
+ gc_setmark_big (buf , bits );
606
610
return ;
607
611
#endif
608
612
if (buf -> pooled )
609
- gc_setmark_pool (buf , mark_mode );
613
+ gc_setmark_pool (buf , bits );
610
614
else
611
- gc_setmark_big (buf , mark_mode );
615
+ gc_setmark_big (buf , bits );
612
616
}
613
617
614
618
static NOINLINE void * malloc_page (void )
@@ -1450,16 +1454,20 @@ void jl_gc_setmark(jl_value_t *v) // TODO rename this as it is misleading now
1450
1454
if (!gc_marked (o )) {
1451
1455
// objprofile_count(jl_typeof(v), 1, 16);
1452
1456
#ifdef MEMDEBUG
1453
- gc_setmark_big (o , GC_MARKED_NOESC );
1457
+ gc_setmark_big (o , gc_bits ( o ) );
1454
1458
#else
1455
- gc_setmark_pool (o , GC_MARKED_NOESC );
1459
+ gc_setmark_pool (o , gc_bits ( o ) );
1456
1460
#endif
1457
1461
}
1458
1462
// perm_scanned_bytes = s;
1459
1463
}
1460
-
1464
+ static char * gc_stack_top ;
1465
+ static char * gc_stack_bot ;
1461
1466
static void gc_mark_stack (jl_value_t * ta , jl_gcframe_t * s , ptrint_t offset , int d )
1462
1467
{
1468
+ jl_task_t * task = (jl_task_t * )ta ;
1469
+ char * stkbuf = task == jl_current_task ? gc_stack_top : task -> stkbuf ;
1470
+ char * stkend = task == jl_current_task ? gc_stack_bot : stkbuf + task -> ssize ;
1463
1471
while (s != NULL ) {
1464
1472
s = (jl_gcframe_t * )((char * )s + offset );
1465
1473
jl_value_t * * * rts = (jl_value_t * * * )(((void * * )s )+ 2 );
@@ -1473,9 +1481,17 @@ static void gc_mark_stack(jl_value_t* ta, jl_gcframe_t *s, ptrint_t offset, int
1473
1481
}
1474
1482
else {
1475
1483
for (size_t i = 0 ; i < nr ; i ++ ) {
1476
- if (rts [i ] != NULL ) {
1484
+ void * v = rts [i ];
1485
+ if (v != NULL ) {
1477
1486
verify_parent2 ("task" , ta , & rts [i ], "stack(%d)" , (int )i );
1478
- gc_push_root (rts [i ], d );
1487
+ if (stkbuf <= (char * )v && (char * )v <= stkend ) {
1488
+ // if v is on the stack it is kept permanently marked
1489
+ // but we still need to scan it once
1490
+ push_root (v , d , gc_bits (jl_astaggedvalue (v )));
1491
+ }
1492
+ else {
1493
+ gc_push_root (v , d );
1494
+ }
1479
1495
}
1480
1496
}
1481
1497
}
@@ -1576,12 +1592,12 @@ static int push_root(jl_value_t *v, int d, int bits)
1576
1592
int refyoung = 0 ;
1577
1593
1578
1594
if (vt == (jl_value_t * )jl_weakref_type ) {
1579
- bits = gc_setmark (v , sizeof (jl_weakref_t ), GC_MARKED_NOESC );
1595
+ bits = gc_setmark (v , sizeof (jl_weakref_t ), bits );
1580
1596
goto ret ;
1581
1597
}
1582
1598
if ((jl_is_datatype (vt ) && ((jl_datatype_t * )vt )-> pointerfree )) {
1583
1599
int sz = jl_datatype_size (vt );
1584
- bits = gc_setmark (v , sz , GC_MARKED_NOESC );
1600
+ bits = gc_setmark (v , sz , bits );
1585
1601
goto ret ;
1586
1602
}
1587
1603
#define MARK (v , s ) do { \
@@ -1597,7 +1613,7 @@ static int push_root(jl_value_t *v, int d, int bits)
1597
1613
// some values have special representations
1598
1614
if (vt == (jl_value_t * )jl_simplevector_type ) {
1599
1615
size_t l = jl_svec_len (v );
1600
- MARK (v , bits = gc_setmark (v , l * sizeof (void * ) + sizeof (jl_svec_t ), GC_MARKED_NOESC ));
1616
+ MARK (v , bits = gc_setmark (v , l * sizeof (void * ) + sizeof (jl_svec_t ), bits ));
1601
1617
jl_value_t * * data = ((jl_svec_t * )v )-> data ;
1602
1618
for (size_t i = 0 ; i < l ; i ++ ) {
1603
1619
jl_value_t * elt = data [i ];
@@ -1618,7 +1634,7 @@ static int push_root(jl_value_t *v, int d, int bits)
1618
1634
#define _gc_setmark_pool gc_setmark_pool
1619
1635
#endif
1620
1636
MARK (a ,
1621
- bits = _gc_setmark_pool (o , GC_MARKED_NOESC );
1637
+ bits = _gc_setmark_pool (o , bits );
1622
1638
if (a -> how == 2 && todo ) {
1623
1639
objprofile_count (MATY , gc_bits (o ) == GC_MARKED , array_nbytes (a ));
1624
1640
if (gc_bits (o ) == GC_MARKED )
@@ -1628,7 +1644,7 @@ static int push_root(jl_value_t *v, int d, int bits)
1628
1644
});
1629
1645
else
1630
1646
MARK (a ,
1631
- bits = gc_setmark_big (o , GC_MARKED_NOESC );
1647
+ bits = gc_setmark_big (o , bits );
1632
1648
if (a -> how == 2 && todo ) {
1633
1649
objprofile_count (MATY , gc_bits (o ) == GC_MARKED , array_nbytes (a ));
1634
1650
if (gc_bits (o ) == GC_MARKED )
@@ -1670,11 +1686,11 @@ static int push_root(jl_value_t *v, int d, int bits)
1670
1686
}
1671
1687
}
1672
1688
else if (vt == (jl_value_t * )jl_module_type ) {
1673
- MARK (v , bits = gc_setmark (v , sizeof (jl_module_t ), GC_MARKED_NOESC ));
1689
+ MARK (v , bits = gc_setmark (v , sizeof (jl_module_t ), bits ));
1674
1690
refyoung |= gc_mark_module ((jl_module_t * )v , d );
1675
1691
}
1676
1692
else if (vt == (jl_value_t * )jl_task_type ) {
1677
- MARK (v , bits = gc_setmark (v , sizeof (jl_task_t ), GC_MARKED_NOESC ));
1693
+ MARK (v , bits = gc_setmark (v , sizeof (jl_task_t ), bits ));
1678
1694
gc_mark_task ((jl_task_t * )v , d );
1679
1695
// tasks should always be remarked since we do not trigger the write barrier
1680
1696
// for stores to stack slots
@@ -1697,7 +1713,7 @@ static int push_root(jl_value_t *v, int d, int bits)
1697
1713
dtsz = NWORDS (sizeof (jl_datatype_t ) + jl_datatype_nfields (v )* sizeof (jl_fielddesc_t ))* sizeof (void * );
1698
1714
else
1699
1715
dtsz = jl_datatype_size (dt );
1700
- MARK (v , bits = gc_setmark (v , dtsz , GC_MARKED_NOESC ));
1716
+ MARK (v , bits = gc_setmark (v , dtsz , bits ));
1701
1717
int nf = (int )jl_datatype_nfields (dt );
1702
1718
// TODO check if there is a perf improvement for objects with a lot of fields
1703
1719
// int fdsz = sizeof(void*)*nf;
@@ -1956,6 +1972,7 @@ void jl_gc_collect(int full)
1956
1972
JL_SIGATOMIC_BEGIN ();
1957
1973
jl_in_gc = 1 ;
1958
1974
uint64_t t0 = jl_hrtime ();
1975
+ gc_stack_top = (char * )& t0 ;
1959
1976
int recollect = 0 ;
1960
1977
#if defined(GC_TIME )
1961
1978
int wb_activations = mark_sp - saved_mark_sp ;
@@ -2366,6 +2383,8 @@ void jl_gc_init(void)
2366
2383
if (maxmem > max_collect_interval )
2367
2384
max_collect_interval = maxmem ;
2368
2385
#endif
2386
+ char _dummy ;
2387
+ gc_stack_bot = & _dummy ;
2369
2388
}
2370
2389
2371
2390
// GC summary stats
0 commit comments