@@ -207,36 +207,30 @@ function insertBlock(root: Root, block: Block): void {
207
207
208
208
// merge with right block if also free
209
209
if ( rightInfo & FREE ) {
210
- let newSize = ( blockInfo & ~ TAGS_MASK ) + BLOCK_OVERHEAD + ( rightInfo & ~ TAGS_MASK ) ;
211
- if ( newSize < BLOCK_MAXSIZE ) {
212
- removeBlock ( root , right ) ;
213
- block . mmInfo = blockInfo = ( blockInfo & TAGS_MASK ) | newSize ;
214
- right = GETRIGHT ( block ) ;
215
- rightInfo = right . mmInfo ;
216
- // 'back' is set below
217
- }
210
+ removeBlock ( root , right ) ;
211
+ block . mmInfo = blockInfo = blockInfo + BLOCK_OVERHEAD + ( rightInfo & ~ TAGS_MASK ) ; // keep block tags
212
+ right = GETRIGHT ( block ) ;
213
+ rightInfo = right . mmInfo ;
214
+ // 'back' is set below
218
215
}
219
216
220
217
// merge with left block if also free
221
218
if ( blockInfo & LEFTFREE ) {
222
219
let left = GETFREELEFT ( block ) ;
223
220
let leftInfo = left . mmInfo ;
224
221
if ( DEBUG ) assert ( leftInfo & FREE ) ; // must be free according to right tags
225
- let newSize = ( leftInfo & ~ TAGS_MASK ) + BLOCK_OVERHEAD + ( blockInfo & ~ TAGS_MASK ) ;
226
- if ( newSize < BLOCK_MAXSIZE ) {
227
- removeBlock ( root , left ) ;
228
- left . mmInfo = blockInfo = ( leftInfo & TAGS_MASK ) | newSize ;
229
- block = left ;
230
- // 'back' is set below
231
- }
222
+ removeBlock ( root , left ) ;
223
+ block = left ;
224
+ block . mmInfo = blockInfo = leftInfo + BLOCK_OVERHEAD + ( blockInfo & ~ TAGS_MASK ) ; // keep left tags
225
+ // 'back' is set below
232
226
}
233
227
234
228
right . mmInfo = rightInfo | LEFTFREE ;
235
229
// reference to right is no longer used now, hence rightInfo is not synced
236
230
237
231
// we now know the size of the block
238
232
var size = blockInfo & ~ TAGS_MASK ;
239
- if ( DEBUG ) assert ( size >= BLOCK_MINSIZE && size < BLOCK_MAXSIZE ) ; // must be a valid size
233
+ if ( DEBUG ) assert ( size >= BLOCK_MINSIZE ) ; // must be a valid size
240
234
if ( DEBUG ) assert ( changetype < usize > ( block ) + BLOCK_OVERHEAD + size == changetype < usize > ( right ) ) ; // must match
241
235
242
236
// set 'back' to itself at the end of block
@@ -249,8 +243,9 @@ function insertBlock(root: Root, block: Block): void {
249
243
sl = < u32 > ( size >> AL_BITS ) ;
250
244
} else {
251
245
const inv : usize = sizeof < usize > ( ) * 8 - 1 ;
252
- fl = inv - clz < usize > ( size ) ;
253
- sl = < u32 > ( ( size >> ( fl - SL_BITS ) ) ^ ( 1 << SL_BITS ) ) ;
246
+ let boundedSize = min ( size , BLOCK_MAXSIZE ) ;
247
+ fl = inv - clz < usize > ( boundedSize ) ;
248
+ sl = < u32 > ( ( boundedSize >> ( fl - SL_BITS ) ) ^ ( 1 << SL_BITS ) ) ;
254
249
fl -= SB_BITS - 1 ;
255
250
}
256
251
if ( DEBUG ) assert ( fl < FL_BITS && sl < SL_SIZE ) ; // fl/sl out of range
@@ -272,7 +267,7 @@ function removeBlock(root: Root, block: Block): void {
272
267
var blockInfo = block . mmInfo ;
273
268
if ( DEBUG ) assert ( blockInfo & FREE ) ; // must be free
274
269
var size = blockInfo & ~ TAGS_MASK ;
275
- if ( DEBUG ) assert ( size >= BLOCK_MINSIZE && size < BLOCK_MAXSIZE ) ; // must be valid
270
+ if ( DEBUG ) assert ( size >= BLOCK_MINSIZE ) ; // must be valid
276
271
277
272
// mapping_insert
278
273
var fl : usize , sl : u32 ;
@@ -281,8 +276,9 @@ function removeBlock(root: Root, block: Block): void {
281
276
sl = < u32 > ( size >> AL_BITS ) ;
282
277
} else {
283
278
const inv : usize = sizeof < usize > ( ) * 8 - 1 ;
284
- fl = inv - clz < usize > ( size ) ;
285
- sl = < u32 > ( ( size >> ( fl - SL_BITS ) ) ^ ( 1 << SL_BITS ) ) ;
279
+ let boundedSize = min ( size , BLOCK_MAXSIZE ) ;
280
+ fl = inv - clz < usize > ( boundedSize ) ;
281
+ sl = < u32 > ( ( boundedSize >> ( fl - SL_BITS ) ) ^ ( 1 << SL_BITS ) ) ;
286
282
fl -= SB_BITS - 1 ;
287
283
}
288
284
if ( DEBUG ) assert ( fl < FL_BITS && sl < SL_SIZE ) ; // fl/sl out of range
@@ -528,8 +524,6 @@ export function reallocateBlock(root: Root, block: Block, size: usize): Block {
528
524
let mergeSize = blockSize + BLOCK_OVERHEAD + ( rightInfo & ~ TAGS_MASK ) ;
529
525
if ( mergeSize >= payloadSize ) {
530
526
removeBlock ( root , right ) ;
531
- // TODO: this can yield an intermediate block larger than BLOCK_MAXSIZE, which
532
- // is immediately split though. does this trigger any assertions / issues?
533
527
block . mmInfo = ( blockInfo & TAGS_MASK ) | mergeSize ;
534
528
prepareBlock ( root , block , payloadSize ) ;
535
529
if ( isDefined ( ASC_RTRACE ) ) onresize ( block , BLOCK_OVERHEAD + blockSize ) ;
0 commit comments