@@ -89,12 +89,12 @@ class List {
89
89
* for that size. The bucket at index 0 corresponds to an allocation size of
90
90
* MAX_ALLOC (i.e. the whole address space).
91
91
*/
92
- var BUCKET_START : usize = HEAP_BASE ;
93
- var BUCKET_END : usize = BUCKET_START + BUCKET_COUNT * List . SIZE ;
92
+ var BUCKETS_START : usize = HEAP_BASE ;
93
+ var BUCKETS_END : usize = BUCKETS_START + BUCKET_COUNT * List . SIZE ;
94
94
95
- function get_bucket ( index : usize ) : List {
95
+ function buckets$get ( index : usize ) : List {
96
96
assert ( index < BUCKET_COUNT ) ;
97
- return changetype < List > ( BUCKET_START + index * List . SIZE ) ;
97
+ return changetype < List > ( BUCKETS_START + index * List . SIZE ) ;
98
98
}
99
99
100
100
/*
@@ -135,17 +135,17 @@ var bucket_limit: usize;
135
135
* since we only ever care about parent nodes.
136
136
*/
137
137
const SPLIT_COUNT : usize = ( 1 << ( BUCKET_COUNT - 1 ) ) / 8 ;
138
- var SPLIT_START : usize = BUCKET_END ;
139
- var SPLIT_END : usize = SPLIT_START + SPLIT_COUNT * sizeof < u8 > ( ) ;
138
+ var NODE_IS_SPLIT_START : usize = BUCKETS_END ;
139
+ var NODE_IS_SPLIT_END : usize = NODE_IS_SPLIT_START + SPLIT_COUNT * sizeof < u8 > ( ) ;
140
140
141
- function node_is_split ( index : usize ) : i32 {
141
+ function node_is_split$get ( index : usize ) : i32 {
142
142
assert ( index < SPLIT_COUNT ) ;
143
- return load < u8 > ( SPLIT_START + index ) ;
143
+ return load < u8 > ( NODE_IS_SPLIT_START + index ) ;
144
144
}
145
145
146
- function node_set_split ( index : usize , state : i32 ) : void {
146
+ function node_is_split$set ( index : usize , state : i32 ) : void {
147
147
assert ( index < SPLIT_COUNT ) ;
148
- store < u8 > ( SPLIT_START + index , state ) ;
148
+ store < u8 > ( NODE_IS_SPLIT_START + index , state ) ;
149
149
}
150
150
151
151
/*
@@ -166,15 +166,21 @@ var max_ptr: usize;
166
166
* front. It's only reserved when it's needed by calling this function. This
167
167
* will return false if the memory could not be reserved.
168
168
*/
169
- function update_max_ptr ( new_value : usize ) : bool {
169
+ function update_max_ptr ( new_value : usize ) : i32 {
170
170
if ( new_value > max_ptr ) {
171
- var pages = ( ( ( new_value - max_ptr ) + 0xffff ) & ~ 0xffff ) >>> 16 ;
172
- if ( grow_memory ( pages ) < 0 ) {
173
- return false ;
171
+ // if (brk(new_value)) {
172
+ // return 0;
173
+ // }
174
+ var oldPages = current_memory ( ) ;
175
+ var newPages = < u32 > ( ( ( new_value + 0xffff ) & ~ 0xffff ) >> 16 ) ;
176
+ assert ( newPages > oldPages ) ;
177
+ if ( grow_memory ( newPages - oldPages ) < 0 ) {
178
+ return 0 ;
174
179
}
175
- max_ptr = new_value ;
180
+ // max_ptr = new_value;
181
+ max_ptr = < usize > newPages << 16 ;
176
182
}
177
- return true ;
183
+ return 1 ;
178
184
}
179
185
180
186
/*
@@ -246,7 +252,7 @@ function node_for_ptr(ptr: usize, bucket: usize): usize {
246
252
*/
247
253
function parent_is_split ( index : usize ) : i32 {
248
254
index = ( index - 1 ) / 2 ;
249
- return ( node_is_split ( index / 8 ) >> < i32 > ( index % 8 ) ) & 1 ;
255
+ return ( node_is_split$get ( index / 8 ) > >> < i32 > ( index % 8 ) ) & 1 ;
250
256
}
251
257
252
258
/*
@@ -255,7 +261,9 @@ function parent_is_split(index: usize): i32 {
255
261
function flip_parent_is_split ( index : usize ) : void {
256
262
index = ( index - 1 ) / 2 ;
257
263
var indexDiv8 = index / 8 ;
258
- node_set_split ( indexDiv8 , node_is_split ( indexDiv8 ) ^ < i32 > ( 1 << ( index % 8 ) ) ) ;
264
+ node_is_split$set ( indexDiv8 ,
265
+ node_is_split$get ( indexDiv8 ) ^ < i32 > ( 1 << ( index % 8 ) )
266
+ ) ;
259
267
}
260
268
261
269
/*
@@ -292,8 +300,8 @@ function lower_bucket_limit(bucket: usize): u32 {
292
300
*/
293
301
if ( ! parent_is_split ( root ) ) {
294
302
list_remove ( changetype < List > ( base_ptr ) ) ;
295
- list_init ( get_bucket ( -- bucket_limit ) ) ;
296
- list_push ( get_bucket ( bucket_limit ) , changetype < List > ( base_ptr ) ) ;
303
+ list_init ( buckets$get ( -- bucket_limit ) ) ;
304
+ list_push ( buckets$get ( bucket_limit ) , changetype < List > ( base_ptr ) ) ;
297
305
continue ;
298
306
}
299
307
@@ -309,8 +317,8 @@ function lower_bucket_limit(bucket: usize): u32 {
309
317
if ( ! update_max_ptr ( right_child + List . SIZE ) ) {
310
318
return 0 ;
311
319
}
312
- list_push ( get_bucket ( bucket_limit ) , changetype < List > ( right_child ) ) ;
313
- list_init ( get_bucket ( -- bucket_limit ) ) ;
320
+ list_push ( buckets$get ( bucket_limit ) , changetype < List > ( right_child ) ) ;
321
+ list_init ( buckets$get ( -- bucket_limit ) ) ;
314
322
315
323
/*
316
324
* Set the grandparent's SPLIT flag so if we need to lower the bucket limit
@@ -325,8 +333,6 @@ function lower_bucket_limit(bucket: usize): u32 {
325
333
return 1 ;
326
334
}
327
335
328
- declare function logi ( i : i32 ) : void ;
329
-
330
336
@global
331
337
function allocate_memory ( request : usize ) : usize {
332
338
var original_bucket : usize , bucket : usize ;
@@ -346,12 +352,15 @@ function allocate_memory(request: usize): usize {
346
352
* possible allocation size. More memory will be reserved later as needed.
347
353
*/
348
354
if ( base_ptr == 0 ) {
349
- base_ptr = SPLIT_END ;
350
- max_ptr = < usize > current_memory ( ) << 16 ; // differs, must grow first
355
+ // base_ptr = max_ptr = (uint8_t *)sbrk(0);
356
+ base_ptr = ( NODE_IS_SPLIT_END + 7 ) & ~ 7 ; // must be aligned
357
+ max_ptr = < usize > current_memory ( ) << 16 ; // must grow first
351
358
bucket_limit = BUCKET_COUNT - 1 ;
352
- update_max_ptr ( base_ptr + List . SIZE ) ;
353
- list_init ( get_bucket ( BUCKET_COUNT - 1 ) ) ;
354
- list_push ( get_bucket ( BUCKET_COUNT - 1 ) , changetype < List > ( base_ptr ) ) ;
359
+ if ( ! update_max_ptr ( base_ptr + List . SIZE ) ) {
360
+ return 0 ;
361
+ }
362
+ list_init ( buckets$get ( BUCKET_COUNT - 1 ) ) ;
363
+ list_push ( buckets$get ( BUCKET_COUNT - 1 ) , changetype < List > ( base_ptr ) ) ;
355
364
}
356
365
357
366
/*
@@ -382,7 +391,7 @@ function allocate_memory(request: usize): usize {
382
391
* Try to pop a block off the free list for this bucket. If the free list
383
392
* is empty, we're going to have to split a larger block instead.
384
393
*/
385
- ptr = changetype < usize > ( list_pop ( get_bucket ( bucket ) ) ) ;
394
+ ptr = changetype < usize > ( list_pop ( buckets$get ( bucket ) ) ) ;
386
395
if ( ! ptr ) {
387
396
/*
388
397
* If we're not at the root of the tree or it's impossible to grow the
@@ -403,7 +412,7 @@ function allocate_memory(request: usize): usize {
403
412
if ( ! lower_bucket_limit ( bucket - 1 ) ) {
404
413
return 0 ;
405
414
}
406
- ptr = changetype < usize > ( list_pop ( get_bucket ( bucket ) ) ) ;
415
+ ptr = changetype < usize > ( list_pop ( buckets$get ( bucket ) ) ) ;
407
416
}
408
417
409
418
/*
@@ -413,7 +422,7 @@ function allocate_memory(request: usize): usize {
413
422
size = 1 << ( MAX_ALLOC_LOG2 - bucket ) ;
414
423
bytes_needed = bucket < original_bucket ? size / 2 + List . SIZE : size ;
415
424
if ( ! update_max_ptr ( ptr + bytes_needed ) ) {
416
- list_push ( get_bucket ( bucket ) , changetype < List > ( ptr ) ) ;
425
+ list_push ( buckets$get ( bucket ) , changetype < List > ( ptr ) ) ;
417
426
return 0 ;
418
427
}
419
428
@@ -444,7 +453,10 @@ function allocate_memory(request: usize): usize {
444
453
i = i * 2 + 1 ;
445
454
bucket ++ ;
446
455
flip_parent_is_split ( i ) ;
447
- list_push ( get_bucket ( bucket ) , changetype < List > ( ptr_for_node ( i + 1 , bucket ) ) ) ;
456
+ list_push (
457
+ buckets$get ( bucket ) ,
458
+ changetype < List > ( ptr_for_node ( i + 1 , bucket ) )
459
+ ) ;
448
460
}
449
461
450
462
/*
@@ -521,5 +533,5 @@ function free_memory(ptr: usize): void {
521
533
* followed by a "malloc" of the same size to ideally use the same address
522
534
* for better memory locality.
523
535
*/
524
- list_push ( get_bucket ( bucket ) , changetype < List > ( ptr_for_node ( i , bucket ) ) ) ;
536
+ list_push ( buckets$get ( bucket ) , changetype < List > ( ptr_for_node ( i , bucket ) ) ) ;
525
537
}
0 commit comments