@@ -486,7 +486,7 @@ export function maybeInitialize(): Root {
486
486
var collectLock : bool = false ;
487
487
488
488
/** Allocates a block of the specified size. */
489
- export function allocateBlock ( root : Root , size : usize ) : Block {
489
+ export function allocateBlock ( root : Root , size : usize , id : u32 ) : Block {
490
490
if ( DEBUG ) assert ( ! collectLock ) ; // must not allocate while collecting
491
491
var payloadSize = prepareSize ( size ) ;
492
492
var block = searchBlock ( root , payloadSize ) ;
@@ -509,7 +509,7 @@ export function allocateBlock(root: Root, size: usize): Block {
509
509
}
510
510
if ( DEBUG ) assert ( ( block . mmInfo & ~ TAGS_MASK ) >= payloadSize ) ; // must fit
511
511
block . gcInfo = 0 ; // RC=0
512
- // block.rtId = 0; // set by the caller (__alloc)
512
+ block . rtId = id ;
513
513
block . rtSize = size ;
514
514
removeBlock ( root , < Block > block ) ;
515
515
prepareBlock ( root , < Block > block , payloadSize ) ;
@@ -521,12 +521,6 @@ export function allocateBlock(root: Root, size: usize): Block {
521
521
export function reallocateBlock ( root : Root , block : Block , size : usize ) : Block {
522
522
var payloadSize = prepareSize ( size ) ;
523
523
var blockInfo = block . mmInfo ;
524
- if ( DEBUG ) {
525
- assert (
526
- ! ( blockInfo & FREE ) && // must be used
527
- ! ( block . gcInfo & ~ REFCOUNT_MASK ) // not buffered or != BLACK
528
- ) ;
529
- }
530
524
531
525
// possibly split and update runtime size if it still fits
532
526
if ( payloadSize <= ( blockInfo & ~ TAGS_MASK ) ) {
@@ -552,8 +546,8 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
552
546
}
553
547
554
548
// otherwise move the block
555
- var newBlock = allocateBlock ( root , size ) ; // may invalidate cached blockInfo
556
- newBlock . rtId = block . rtId ;
549
+ var newBlock = allocateBlock ( root , size , block . rtId ) ; // may invalidate cached blockInfo
550
+ newBlock . gcInfo = block . gcInfo ; // keep RC
557
551
memory . copy ( changetype < usize > ( newBlock ) + BLOCK_OVERHEAD , changetype < usize > ( block ) + BLOCK_OVERHEAD , size ) ;
558
552
if ( changetype < usize > ( block ) >= __heap_base ) freeBlock ( root , block ) ;
559
553
return newBlock ;
@@ -562,30 +556,40 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
562
556
/** Frees a block. */
563
557
export function freeBlock ( root : Root , block : Block ) : void {
564
558
var blockInfo = block . mmInfo ;
565
- assert ( ! ( blockInfo & FREE ) ) ; // must be used (user might call through to this)
566
559
block . mmInfo = blockInfo | FREE ;
567
560
insertBlock ( root , block ) ;
568
561
if ( isDefined ( ASC_RTRACE ) ) onfree ( block ) ;
569
562
}
570
563
564
+ /** Checks that a used block is valid to be freed or reallocated. */
565
+ function checkUsedBlock ( ref : usize ) : Block {
566
+ var block = changetype < Block > ( ref - BLOCK_OVERHEAD ) ;
567
+ assert (
568
+ ref != 0 && ! ( ref & AL_MASK ) && // must exist and be aligned
569
+ ! ( block . mmInfo & FREE ) && // must be used
570
+ ! ( block . gcInfo & ~ REFCOUNT_MASK ) // not buffered or != BLACK
571
+ ) ;
572
+ return block ;
573
+ }
574
+
571
575
// @ts -ignore: decorator
572
576
@global @unsafe
573
577
export function __alloc ( size : usize , id : u32 ) : usize {
574
- var block = allocateBlock ( maybeInitialize ( ) , size ) ;
575
- block . rtId = id ;
576
- return changetype < usize > ( block ) + BLOCK_OVERHEAD ;
578
+ return changetype < usize > (
579
+ allocateBlock ( maybeInitialize ( ) , size , id )
580
+ ) + BLOCK_OVERHEAD ;
577
581
}
578
582
579
583
// @ts -ignore: decorator
580
584
@global @unsafe
581
585
export function __realloc ( ref : usize , size : usize ) : usize {
582
- assert ( ref != 0 && ! ( ref & AL_MASK ) ) ; // must exist and be aligned
583
- return changetype < usize > ( reallocateBlock ( maybeInitialize ( ) , changetype < Block > ( ref - BLOCK_OVERHEAD ) , size ) ) + BLOCK_OVERHEAD ;
586
+ return changetype < usize > (
587
+ reallocateBlock ( maybeInitialize ( ) , checkUsedBlock ( ref ) , size )
588
+ ) + BLOCK_OVERHEAD ;
584
589
}
585
590
586
591
// @ts -ignore: decorator
587
592
@global @unsafe
588
593
export function __free ( ref : usize ) : void {
589
- assert ( ref != 0 && ! ( ref & AL_MASK ) ) ; // must exist and be aligned
590
- freeBlock ( maybeInitialize ( ) , changetype < Block > ( ref - BLOCK_OVERHEAD ) ) ;
594
+ freeBlock ( maybeInitialize ( ) , checkUsedBlock ( ref ) ) ;
591
595
}
0 commit comments