@@ -486,7 +486,7 @@ export function maybeInitialize(): Root {
486486var collectLock : bool = false ;
487487
488488/** 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 {
490490 if ( DEBUG ) assert ( ! collectLock ) ; // must not allocate while collecting
491491 var payloadSize = prepareSize ( size ) ;
492492 var block = searchBlock ( root , payloadSize ) ;
@@ -509,7 +509,7 @@ export function allocateBlock(root: Root, size: usize): Block {
509509 }
510510 if ( DEBUG ) assert ( ( block . mmInfo & ~ TAGS_MASK ) >= payloadSize ) ; // must fit
511511 block . gcInfo = 0 ; // RC=0
512- // block.rtId = 0; // set by the caller (__alloc)
512+ block . rtId = id ;
513513 block . rtSize = size ;
514514 removeBlock ( root , < Block > block ) ;
515515 prepareBlock ( root , < Block > block , payloadSize ) ;
@@ -521,12 +521,6 @@ export function allocateBlock(root: Root, size: usize): Block {
521521export function reallocateBlock ( root : Root , block : Block , size : usize ) : Block {
522522 var payloadSize = prepareSize ( size ) ;
523523 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- }
530524
531525 // possibly split and update runtime size if it still fits
532526 if ( payloadSize <= ( blockInfo & ~ TAGS_MASK ) ) {
@@ -552,8 +546,8 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
552546 }
553547
554548 // 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
557551 memory . copy ( changetype < usize > ( newBlock ) + BLOCK_OVERHEAD , changetype < usize > ( block ) + BLOCK_OVERHEAD , size ) ;
558552 if ( changetype < usize > ( block ) >= __heap_base ) freeBlock ( root , block ) ;
559553 return newBlock ;
@@ -562,30 +556,40 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
562556/** Frees a block. */
563557export function freeBlock ( root : Root , block : Block ) : void {
564558 var blockInfo = block . mmInfo ;
565- assert ( ! ( blockInfo & FREE ) ) ; // must be used (user might call through to this)
566559 block . mmInfo = blockInfo | FREE ;
567560 insertBlock ( root , block ) ;
568561 if ( isDefined ( ASC_RTRACE ) ) onfree ( block ) ;
569562}
570563
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+
571575// @ts -ignore: decorator
572576@global @unsafe
573577export 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 ;
577581}
578582
579583// @ts -ignore: decorator
580584@global @unsafe
581585export 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 ;
584589}
585590
586591// @ts -ignore: decorator
587592@global @unsafe
588593export 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 ) ) ;
591595}
0 commit comments