diff --git a/tests/allocators/asrt/optimized.wat b/tests/allocators/asrt/optimized.wat index 8bd7534f..315ac962 100644 --- a/tests/allocators/asrt/optimized.wat +++ b/tests/allocators/asrt/optimized.wat @@ -1,12 +1,11 @@ (module (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$i (func (result i32))) - (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$vii (func (param i32 i32))) - (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$v (func)) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) @@ -490,7 +489,33 @@ call $../../runtime/assembly/index/addMemory local.get $0 ) - (func $../../runtime/assembly/index/searchBlock (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $../../runtime/assembly/index/prepareSize (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + local.get $0 + i32.const 1073741824 + i32.ge_u + if + i32.const 0 + i32.const 24 + i32.const 466 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 15 + i32.add + i32.const -16 + i32.and + local.tee $0 + i32.const 16 + local.tee $1 + local.get $0 + local.get $1 + i32.gt_u + select + ) + (func $../../runtime/assembly/index/searchBlock (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) local.get $0 local.get $1 @@ -591,7 +616,7 @@ end end ) - (func $../../runtime/assembly/index/growMemory (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $../../runtime/assembly/index/growMemory (; 7 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -632,16 +657,12 @@ i32.shl call $../../runtime/assembly/index/addMemory ) - (func $../../runtime/assembly/index/prepareBlock (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $../../runtime/assembly/index/prepareBlock (; 8 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) local.get $1 i32.load - local.set $3 - local.get $0 - local.get $1 - call $../../runtime/assembly/index/removeBlock - local.get $3 + local.tee $3 i32.const -4 i32.and local.get $2 @@ -662,7 +683,7 @@ i32.add local.get $2 i32.add - local.tee $2 + local.tee $1 local.get $4 i32.const 16 i32.sub @@ -670,7 +691,7 @@ i32.or i32.store local.get $0 - local.get $2 + local.get $1 call $../../runtime/assembly/index/insertBlock else local.get $1 @@ -699,101 +720,73 @@ i32.and i32.store end - local.get $1 - i32.const 16 - i32.add ) - (func $../../runtime/assembly/index/__mm_allocate (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) + (func $../../runtime/assembly/index/allocateBlock (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) - global.get $../../runtime/assembly/index/ROOT + (local $3 i32) + local.get $0 + local.get $1 + call $../../runtime/assembly/index/prepareSize + local.tee $3 + call $../../runtime/assembly/index/searchBlock local.tee $2 i32.eqz if - call $../../runtime/assembly/index/initialize - local.tee $2 - global.set $../../runtime/assembly/index/ROOT - end - local.get $0 - i32.const 1073741824 - i32.ge_u - if - i32.const 0 - i32.const 24 - i32.const 495 - i32.const 29 - call $~lib/builtins/abort - unreachable + local.get $0 + local.get $3 + call $../../runtime/assembly/index/growMemory + local.get $0 + local.get $3 + call $../../runtime/assembly/index/searchBlock + local.set $2 end local.get $2 - local.get $0 - i32.const 15 - i32.add - i32.const -16 - i32.and - local.tee $0 - i32.const 16 - local.tee $1 - local.get $0 - local.get $1 - i32.gt_u - select - local.tee $1 - call $../../runtime/assembly/index/searchBlock - local.tee $0 - i32.eqz - if - local.get $2 - local.get $1 - call $../../runtime/assembly/index/growMemory - local.get $2 - local.get $1 - call $../../runtime/assembly/index/searchBlock - local.set $0 - end - local.get $0 i32.const 0 i32.store offset=4 - local.get $0 + local.get $2 i32.const 0 i32.store offset=8 - local.get $0 + local.get $2 local.get $1 i32.store offset=12 + local.get $0 local.get $2 + call $../../runtime/assembly/index/removeBlock local.get $0 - local.get $1 + local.get $2 + local.get $3 call $../../runtime/assembly/index/prepareBlock + local.get $2 ) - (func $assembly/index/memory.allocate (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - local.get $0 - call $../../runtime/assembly/index/__mm_allocate - ) - (func $../../runtime/assembly/index/__mm_free (; 10 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/memory.allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (local $1 i32) - local.get $0 + global.get $../../runtime/assembly/index/ROOT + local.tee $1 + i32.eqz if - global.get $../../runtime/assembly/index/ROOT + call $../../runtime/assembly/index/initialize local.tee $1 - if - local.get $0 - i32.const 16 - i32.sub - local.tee $0 - local.get $0 - i32.load - i32.const 1 - i32.or - i32.store - local.get $1 - local.get $0 - call $../../runtime/assembly/index/insertBlock - end + global.set $../../runtime/assembly/index/ROOT end + local.get $1 + local.get $0 + call $../../runtime/assembly/index/allocateBlock + i32.const 16 + i32.add ) (func $assembly/index/memory.free (; 11 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 - call $../../runtime/assembly/index/__mm_free + i32.const 16 + i32.sub + local.tee $0 + local.get $0 + i32.load + i32.const 1 + i32.or + i32.store + global.get $../../runtime/assembly/index/ROOT + local.get $0 + call $../../runtime/assembly/index/insertBlock ) (func $~lib/memory/memory.fill (; 12 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i64) diff --git a/tests/allocators/asrt/untouched.wat b/tests/allocators/asrt/untouched.wat index 3167815e..201974bd 100644 --- a/tests/allocators/asrt/untouched.wat +++ b/tests/allocators/asrt/untouched.wat @@ -5,8 +5,8 @@ (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$vii (func (param i32 i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$viii (func (param i32 i32 i32))) + (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$v (func)) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) @@ -41,7 +41,7 @@ if i32.const 0 i32.const 24 - i32.const 282 + i32.const 276 i32.const 13 call $~lib/builtins/abort unreachable @@ -66,7 +66,7 @@ if i32.const 0 i32.const 24 - i32.const 284 + i32.const 278 i32.const 13 call $~lib/builtins/abort unreachable @@ -118,7 +118,7 @@ if i32.const 0 i32.const 24 - i32.const 297 + i32.const 291 i32.const 13 call $~lib/builtins/abort unreachable @@ -256,7 +256,7 @@ if i32.const 0 i32.const 24 - i32.const 210 + i32.const 204 i32.const 13 call $~lib/builtins/abort unreachable @@ -271,7 +271,7 @@ if i32.const 0 i32.const 24 - i32.const 212 + i32.const 206 i32.const 13 call $~lib/builtins/abort unreachable @@ -351,7 +351,7 @@ i32.const 2 i32.and if - block $../../runtime/assembly/index/GETLEFT|inlined.0 (result i32) + block $../../runtime/assembly/index/GETFREELEFT|inlined.0 (result i32) local.get $1 local.set $3 local.get $3 @@ -370,7 +370,7 @@ if i32.const 0 i32.const 24 - i32.const 233 + i32.const 227 i32.const 15 call $~lib/builtins/abort unreachable @@ -433,7 +433,7 @@ if i32.const 0 i32.const 24 - i32.const 248 + i32.const 242 i32.const 13 call $~lib/builtins/abort unreachable @@ -449,7 +449,7 @@ if i32.const 0 i32.const 24 - i32.const 249 + i32.const 243 i32.const 13 call $~lib/builtins/abort unreachable @@ -506,7 +506,7 @@ if i32.const 0 i32.const 24 - i32.const 265 + i32.const 259 i32.const 13 call $~lib/builtins/abort unreachable @@ -629,7 +629,7 @@ if i32.const 0 i32.const 24 - i32.const 399 + i32.const 385 i32.const 4 call $~lib/builtins/abort unreachable @@ -654,7 +654,7 @@ if i32.const 0 i32.const 24 - i32.const 409 + i32.const 395 i32.const 15 call $~lib/builtins/abort unreachable @@ -685,7 +685,7 @@ if i32.const 0 i32.const 24 - i32.const 421 + i32.const 407 i32.const 4 call $~lib/builtins/abort unreachable @@ -908,7 +908,36 @@ drop local.get $3 ) - (func $../../runtime/assembly/index/searchBlock (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $../../runtime/assembly/index/prepareSize (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + local.get $0 + i32.const 1073741824 + i32.ge_u + if + i32.const 0 + i32.const 24 + i32.const 466 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $1 + i32.const 16 + local.tee $2 + local.get $1 + local.get $2 + i32.gt_u + select + ) + (func $../../runtime/assembly/index/searchBlock (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -982,7 +1011,7 @@ if i32.const 0 i32.const 24 - i32.const 343 + i32.const 337 i32.const 13 call $~lib/builtins/abort unreachable @@ -1047,7 +1076,7 @@ if i32.const 0 i32.const 24 - i32.const 356 + i32.const 350 i32.const 17 call $~lib/builtins/abort unreachable @@ -1097,7 +1126,7 @@ end local.get $7 ) - (func $../../runtime/assembly/index/growMemory (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $../../runtime/assembly/index/growMemory (; 7 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -1150,38 +1179,26 @@ call $../../runtime/assembly/index/addMemory drop ) - (func $../../runtime/assembly/index/prepareBlock (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $../../runtime/assembly/index/prepareBlock (; 8 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) local.get $1 i32.load local.set $3 - local.get $3 - i32.const 1 + local.get $2 + i32.const 15 i32.and - i32.const 0 - i32.ne - if (result i32) - local.get $2 - i32.const 15 - i32.and - i32.eqz - else - i32.const 0 - end + i32.eqz i32.eqz if i32.const 0 i32.const 24 - i32.const 371 - i32.const 4 + i32.const 364 + i32.const 13 call $~lib/builtins/abort unreachable end - local.get $0 - local.get $1 - call $../../runtime/assembly/index/removeBlock local.get $3 i32.const 3 i32.const -1 @@ -1262,15 +1279,75 @@ i32.and i32.store end - local.get $1 - i32.const 16 - i32.add ) - (func $../../runtime/assembly/index/__mm_allocate (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) + (func $../../runtime/assembly/index/allocateBlock (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) - (local $4 i32) + local.get $1 + call $../../runtime/assembly/index/prepareSize + local.set $2 + local.get $0 + local.get $2 + call $../../runtime/assembly/index/searchBlock + local.set $3 + local.get $3 + i32.eqz + if + local.get $0 + local.get $2 + call $../../runtime/assembly/index/growMemory + local.get $0 + local.get $2 + call $../../runtime/assembly/index/searchBlock + local.set $3 + local.get $3 + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 477 + i32.const 15 + call $~lib/builtins/abort + unreachable + end + end + local.get $3 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $2 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 479 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 0 + i32.store offset=4 + local.get $3 + i32.const 0 + i32.store offset=8 + local.get $3 + local.get $1 + i32.store offset=12 + local.get $0 + local.get $3 + call $../../runtime/assembly/index/removeBlock + local.get $0 + local.get $3 + local.get $2 + call $../../runtime/assembly/index/prepareBlock + local.get $3 + ) + (func $../../runtime/assembly/index/__mm_allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) global.get $../../runtime/assembly/index/ROOT local.set $1 local.get $1 @@ -1280,93 +1357,17 @@ local.tee $1 global.set $../../runtime/assembly/index/ROOT end + local.get $1 local.get $0 - i32.const 1073741824 - i32.ge_u - if - i32.const 0 - i32.const 24 - i32.const 495 - i32.const 29 - call $~lib/builtins/abort - unreachable - end - local.get $0 - i32.const 15 - i32.add - i32.const 15 - i32.const -1 - i32.xor - i32.and - local.tee $2 + call $../../runtime/assembly/index/allocateBlock i32.const 16 - local.tee $3 - local.get $2 - local.get $3 - i32.gt_u - select - local.set $0 - local.get $1 - local.get $0 - call $../../runtime/assembly/index/searchBlock - local.set $4 - local.get $4 - i32.eqz - if - local.get $1 - local.get $0 - call $../../runtime/assembly/index/growMemory - local.get $1 - local.get $0 - call $../../runtime/assembly/index/searchBlock - local.set $4 - local.get $4 - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 501 - i32.const 15 - call $~lib/builtins/abort - unreachable - end - end - local.get $4 - i32.load - i32.const 3 - i32.const -1 - i32.xor - i32.and - local.get $0 - i32.ge_u - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 503 - i32.const 13 - call $~lib/builtins/abort - unreachable - end - local.get $4 - i32.const 0 - i32.store offset=4 - local.get $4 - i32.const 0 - i32.store offset=8 - local.get $4 - local.get $0 - i32.store offset=12 - local.get $1 - local.get $4 - local.get $0 - call $../../runtime/assembly/index/prepareBlock + i32.add ) - (func $assembly/index/memory.allocate (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (func $assembly/index/memory.allocate (; 11 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) local.get $0 call $../../runtime/assembly/index/__mm_allocate ) - (func $../../runtime/assembly/index/freeBlock (; 10 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $../../runtime/assembly/index/freeBlock (; 12 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) local.get $1 i32.load @@ -1379,7 +1380,7 @@ if i32.const 0 i32.const 24 - i32.const 480 + i32.const 530 i32.const 2 call $~lib/builtins/abort unreachable @@ -1393,40 +1394,48 @@ local.get $1 call $../../runtime/assembly/index/insertBlock ) - (func $../../runtime/assembly/index/__mm_free (; 11 ;) (type $FUNCSIG$vi) (param $0 i32) - (local $1 i32) - local.get $0 + (func $../../runtime/assembly/index/__mm_free (; 13 ;) (type $FUNCSIG$vi) (param $0 i32) + global.get $../../runtime/assembly/index/ROOT + i32.eqz if + i32.const 0 + i32.const 24 + i32.const 556 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 0 + i32.ne + if (result i32) local.get $0 i32.const 15 i32.and i32.eqz - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 514 - i32.const 4 - call $~lib/builtins/abort - unreachable - end - global.get $../../runtime/assembly/index/ROOT - local.set $1 - local.get $1 - if - local.get $1 - local.get $0 - i32.const 16 - i32.sub - call $../../runtime/assembly/index/freeBlock - end + else + i32.const 0 end + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 557 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + global.get $../../runtime/assembly/index/ROOT + local.get $0 + i32.const 16 + i32.sub + call $../../runtime/assembly/index/freeBlock ) - (func $assembly/index/memory.free (; 12 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/memory.free (; 14 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 call $../../runtime/assembly/index/__mm_free ) - (func $~lib/memory/memory.fill (; 13 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/memory/memory.fill (; 15 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1683,12 +1692,12 @@ end end ) - (func $assembly/index/memory.fill (; 14 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (func $assembly/index/memory.fill (; 16 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) local.get $0 local.get $1 local.get $2 call $~lib/memory/memory.fill ) - (func $null (; 15 ;) (type $FUNCSIG$v) + (func $null (; 17 ;) (type $FUNCSIG$v) ) ) diff --git a/tests/runtime/.gitignore b/tests/runtime/.gitignore index cec7a80f..4ef75906 100644 --- a/tests/runtime/.gitignore +++ b/tests/runtime/.gitignore @@ -1 +1 @@ -!optimized.wasm +!untouched.wasm diff --git a/tests/runtime/assembly/index.ts b/tests/runtime/assembly/index.ts index d4936bc6..3129d070 100644 --- a/tests/runtime/assembly/index.ts +++ b/tests/runtime/assembly/index.ts @@ -80,7 +80,7 @@ // ├───────────────────────────────────────────────────────────────┤ │ // │ if free: back ▲ │ ◄─┘ // └───────────────────────────────────────────────────────────────┘ payload ┘ >= MIN SIZE -// F: FREE, L: LEFT_FREE +// F: FREE, L: LEFTFREE @unmanaged class Block { /** Memory manager info. */ @@ -97,7 +97,7 @@ /** Next free block, if any. Only valid if free, otherwise part of payload. */ next: Block | null; - // If the block is free, there is a backreference at its end pointing at its start. + // If the block is free, there is a 'back'reference at its end pointing at its start. } // Block constants. Overhead is always present, no matter if free or used. Also, a block must have @@ -112,7 +112,7 @@ /** Gets the left block of a block. Only valid if the left block is free. */ // @ts-ignore: decorator -@inline function GETLEFT(block: Block): Block { +@inline function GETFREELEFT(block: Block): Block { return load(changetype(block) - sizeof()); } @@ -132,13 +132,13 @@ // ├───────────────────────────────────────────────────────────────┤ │ │ // │ slMap[1] │ ◄─┤ │ // ├───────────────────────────────────────────────────────────────┤ u32 │ -// │ slMap[21] │ ◄─┘ │ +// │ slMap[22] │ ◄─┘ │ // ╞═══════════════════════════════════════════════════════════════╡ usize // │ head[0] │ ◄────┤ // ├───────────────────────────────────────────────────────────────┤ │ // │ ... │ ◄────┤ // ├───────────────────────────────────────────────────────────────┤ │ -// │ head[351] │ ◄────┤ +// │ head[367] │ ◄────┤ // ╞═══════════════════════════════════════════════════════════════╡ │ // │ tail │ ◄────┘ // └───────────────────────────────────────────────────────────────┘ SIZE ┘ @@ -171,26 +171,20 @@ var ROOT: Root; /** Sets the second level map of the specified first level. */ // @ts-ignore: decorator -@inline function SETSL(root: Root, fl: usize, value: u32): void { - store(changetype(root) + (fl << alignof()), value, SL_START); +@inline function SETSL(root: Root, fl: usize, slMap: u32): void { + store(changetype(root) + (fl << alignof()), slMap, SL_START); } /** Gets the head of the free list for the specified combination of first and second level. */ // @ts-ignore: decorator @inline function GETHEAD(root: Root, fl: usize, sl: u32): Block | null { - return changetype( - load( - changetype(root) + (fl * SL_SIZE + sl) * sizeof(), - HL_START) - ); + return changetype(load(changetype(root) + (fl * SL_SIZE + sl) * sizeof(), HL_START)); } /** Sets the head of the free list for the specified combination of first and second level. */ // @ts-ignore: decorator @inline function SETHEAD(root: Root, fl: usize, sl: u32, head: Block | null): void { - store( - changetype(root) + (fl * SL_SIZE + sl) * sizeof() , changetype(head), - HL_START); + store(changetype(root) + (fl * SL_SIZE + sl) * sizeof() , changetype(head), HL_START); } /** Gets the tail block.. */ @@ -228,7 +222,7 @@ function insertBlock(root: Root, block: Block): void { // merge with left block if also free if (blockInfo & LEFTFREE) { - let left = GETLEFT(block); + let left = GETFREELEFT(block); let leftInfo = left.mmInfo; if (DEBUG) assert(leftInfo & FREE); // must be free according to right tags let newSize = (leftInfo & ~TAGS_MASK) + BLOCK_OVERHEAD + (blockInfo & ~TAGS_MASK); @@ -362,18 +356,12 @@ function searchBlock(root: Root, size: usize): Block | null { return head; } -/** Prepares the specified free block for use, possibly splitting it. */ -function prepareBlock(root: Root, block: Block, size: usize): usize { +/** Prepares the specified block before (re-)use, possibly splitting it. */ +function prepareBlock(root: Root, block: Block, size: usize): void { // size was already asserted by caller var blockInfo = block.mmInfo; - if (DEBUG) { - assert( - (blockInfo & FREE) != 0 && // must be free - !(size & AL_MASK) // size must be aligned so the new block is - ); - } - removeBlock(root, block); + if (DEBUG) assert(!(size & AL_MASK)); // size must be aligned so the new block is // split if the block can hold another MINSIZE block incl. overhead var remaining = (blockInfo & ~TAGS_MASK) - size; @@ -381,16 +369,14 @@ function prepareBlock(root: Root, block: Block, size: usize): usize { block.mmInfo = size | (blockInfo & LEFTFREE); // also discards FREE let spare = changetype(changetype(block) + BLOCK_OVERHEAD + size); - spare.mmInfo = (remaining - BLOCK_OVERHEAD) | FREE; // not LEFT_FREE + spare.mmInfo = (remaining - BLOCK_OVERHEAD) | FREE; // not LEFTFREE insertBlock(root, spare); // also sets 'back' - // otherwise tag block as no longer FREE and right as no longer LEFT_FREE + // otherwise tag block as no longer FREE and right as no longer LEFTFREE } else { block.mmInfo = blockInfo & ~FREE; GETRIGHT(block).mmInfo &= ~LEFTFREE; } - - return changetype(block) + BLOCK_OVERHEAD; } /** Adds more memory to the pool. */ @@ -475,6 +461,70 @@ function initialize(): Root { return root; } +/** Prepares and checks an allocation size. */ +function prepareSize(size: usize): usize { + if (size >= BLOCK_MAXSIZE) throw new Error("allocation too large"); + return max((size + AL_MASK) & ~AL_MASK, BLOCK_MINSIZE); // align and ensure min size +} + +/** Allocates a block of the specified size. */ +function allocateBlock(root: Root, size: usize): Block { + var payloadSize = prepareSize(size); + var block = searchBlock(root, payloadSize); + if (!block) { + growMemory(root, payloadSize); + block = searchBlock(root, payloadSize); + if (DEBUG) assert(block); // must be found now + } + if (DEBUG) assert((block.mmInfo & ~TAGS_MASK) >= payloadSize); // must fit + block.gcInfo = 0; + block.rtId = 0; // not determined yet + block.rtSize = size; + removeBlock(root, block); + prepareBlock(root, block, payloadSize); + return block; +} + +/** Reallocates a block to the specified size. */ +function reallocateBlock(root: Root, block: Block, size: usize): Block { + var payloadSize = prepareSize(size); + var blockInfo = block.mmInfo; + if (DEBUG) assert(!(blockInfo & FREE)); // must be used + + // possibly split and update runtime size if it still fits + if (payloadSize <= (blockInfo & ~TAGS_MASK)) { + prepareBlock(root, block, payloadSize); + block.rtSize = size; + return block; + } + + // merge with right free block if merger is large enough + var right = GETRIGHT(block); + var rightInfo = right.mmInfo; + if (rightInfo & FREE) { + let mergeSize = (blockInfo & ~TAGS_MASK) + BLOCK_OVERHEAD + (rightInfo & ~TAGS_MASK); + if (mergeSize >= payloadSize) { + removeBlock(root, right); + // TODO: this can yield an intermediate block larger than BLOCK_MAXSIZE, which + // is immediately split though. does this trigger any assertions / issues? + block.mmInfo = (blockInfo & TAGS_MASK) | mergeSize; + block.rtSize = size; + prepareBlock(root, block, payloadSize); + return block; + } + } + + // otherwise move the block + var newBlock = allocateBlock(root, size); + newBlock.gcInfo = block.gcInfo; + newBlock.rtId = block.rtId; + memory.copy(changetype(newBlock) + BLOCK_OVERHEAD, changetype(block) + BLOCK_OVERHEAD, size); + block.mmInfo = blockInfo | FREE; + insertBlock(root, block); + return newBlock; +} + +/** Frees a block. */ function freeBlock(root: Root, block: Block): void { var blockInfo = block.mmInfo; assert(!(blockInfo & FREE)); // must be used (user might call through to this) @@ -487,34 +537,25 @@ function freeBlock(root: Root, block: Block): void { // @ts-ignore: decorator @global @unsafe function __mm_allocate(size: usize): usize { - // initialize if necessary var root = ROOT; if (!root) ROOT = root = initialize(); + return changetype(allocateBlock(root, size)) + BLOCK_OVERHEAD; +} - // search for a suitable block - if (size >= BLOCK_MAXSIZE) throw new Error("allocation too large"); - size = max((size + AL_MASK) & ~AL_MASK, BLOCK_MINSIZE); // align and ensure min size - var block = searchBlock(root, size); - if (!block) { - growMemory(root, size); - block = searchBlock(root, size); - if (DEBUG) assert(block); // must be found now - } - if (DEBUG) assert((block.mmInfo & ~TAGS_MASK) >= size); // must fit - block.gcInfo = 0; - block.rtId = 0; // not determined yet - block.rtSize = size; - return prepareBlock(root, block, size); // FIXME: why's still necessary? +// @ts-ignore: decorator +@global @unsafe +function __mm_reallocate(data: usize, size: usize): usize { + if (DEBUG) assert(ROOT); // must be initialized + assert(data != 0 && !(data & AL_MASK)); // must exist and be aligned + return changetype(reallocateBlock(ROOT, changetype(data - BLOCK_OVERHEAD), size)) + BLOCK_OVERHEAD; } // @ts-ignore: decorator @global @unsafe function __mm_free(data: usize): void { - if (data) { - assert(!(data & AL_MASK)); // must be aligned (user might call through to this) - let root = ROOT; - if (root) freeBlock(root, changetype(data - BLOCK_OVERHEAD)); - } + if (DEBUG) assert(ROOT); // must be initialized + assert(data != 0 && !(data & AL_MASK)); // must exist and be aligned + freeBlock(ROOT, changetype(data - BLOCK_OVERHEAD)); } /////////////////////////// A Pure Reference Counting Garbage Collector /////////////////////////// @@ -771,9 +812,12 @@ function __gc_release(ref: usize): void { // keep alive, everything else is reached from here export { __mm_allocate, + __mm_reallocate, __mm_free, __rt_visit, __gc_retain, __gc_release, collectCycles as __gc_collect }; + +// @start export function main(): void {} diff --git a/tests/runtime/index.html b/tests/runtime/index.html index 6858828a..d6c79dbb 100644 --- a/tests/runtime/index.html +++ b/tests/runtime/index.html @@ -12,7 +12,7 @@ const HL_SIZE = FL_BITS * SL_SIZE; var exports; var ROOT; var U32; -fetch("optimized.wasm").then(result => +fetch("untouched.wasm").then(result => result.arrayBuffer() ).then(buffer => WebAssembly.instantiate(buffer, { @@ -55,8 +55,8 @@ var slValue; var hlValue; var tailValue; -function toBits(n, l) { - var s = n.toString(2); +function toBits(n, l, radix = 2) { + var s = n.toString(radix); while (s.length < l) s = "0" + s; return s; } @@ -108,21 +108,29 @@ function update() { hl.forEach((el, i) => { var ptr = U32[(ROOT + 4 + fl.length * 4 + i * 4) >> 2]; el.className = ptr ? "hl set" : "hl"; - el.innerHTML = '' + (i == hl.length - 1 ? "tail" : i) + '' + " " + ptr.toString(16); + el.innerHTML = '' + (i == hl.length - 1 ? "tail" : i) + '' + " " + toBits(ptr, 6, 16); }); } function allocate(size) { var ptr = exports.__mm_allocate(size); if (!ptr) { - alert("allocation failed"); + alert("should not happen"); return; } var el = document.createElement("div"); el.className = "seg"; - var es = document.createElement("span"); - es.innerText = size; + var es = document.createElement("input"); + es.size = 10; + es.value = size; el.appendChild(es); + var er = document.createElement("button"); + er.innerText = "realloc"; + er.onclick = function() { + ptr = exports.__mm_reallocate(ptr, es.value >>> 0); + update(); + }; + el.appendChild(er); var ef = document.createElement("button"); ef.innerText = "free"; el.appendChild(ef); @@ -132,7 +140,6 @@ function allocate(size) { update(); }; document.getElementById("segs").appendChild(el); - } diff --git a/tests/runtime/optimized.wasm b/tests/runtime/optimized.wasm deleted file mode 100644 index a09173be..00000000 Binary files a/tests/runtime/optimized.wasm and /dev/null differ diff --git a/tests/runtime/optimized.wat b/tests/runtime/optimized.wat index ef509453..5b8b4477 100644 --- a/tests/runtime/optimized.wat +++ b/tests/runtime/optimized.wat @@ -3,11 +3,11 @@ (type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$vii (func (param i32 i32))) - (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$v (func)) - (type $FUNCSIG$viii (func (param i32 i32 i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) (data (i32.const 8) "\10\00\00\00\"") @@ -19,6 +19,7 @@ (global $assembly/index/ROOTS (mut i32) (i32.const 0)) (export "memory" (memory $0)) (export "__mm_allocate" (func $assembly/index/__mm_allocate)) + (export "__mm_reallocate" (func $assembly/index/__mm_reallocate)) (export "__mm_free" (func $assembly/index/__mm_free)) (export "__rt_visit" (func $assembly/index/__rt_visit)) (export "__gc_retain" (func $assembly/index/__gc_retain)) @@ -497,7 +498,33 @@ call $assembly/index/addMemory local.get $0 ) - (func $assembly/index/searchBlock (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $assembly/index/prepareSize (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + local.get $0 + i32.const 1073741824 + i32.ge_u + if + i32.const 0 + i32.const 24 + i32.const 466 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 15 + i32.add + i32.const -16 + i32.and + local.tee $0 + i32.const 16 + local.tee $1 + local.get $0 + local.get $1 + i32.gt_u + select + ) + (func $assembly/index/searchBlock (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) local.get $0 local.get $1 @@ -598,7 +625,7 @@ end end ) - (func $assembly/index/growMemory (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $assembly/index/growMemory (; 7 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -639,16 +666,12 @@ i32.shl call $assembly/index/addMemory ) - (func $assembly/index/prepareBlock (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $assembly/index/prepareBlock (; 8 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) local.get $1 i32.load - local.set $3 - local.get $0 - local.get $1 - call $assembly/index/removeBlock - local.get $3 + local.tee $3 i32.const -4 i32.and local.get $2 @@ -669,7 +692,7 @@ i32.add local.get $2 i32.add - local.tee $2 + local.tee $1 local.get $4 i32.const 16 i32.sub @@ -677,7 +700,7 @@ i32.or i32.store local.get $0 - local.get $2 + local.get $1 call $assembly/index/insertBlock else local.get $1 @@ -706,73 +729,347 @@ i32.and i32.store end - local.get $1 - i32.const 16 - i32.add ) - (func $assembly/index/__mm_allocate (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) + (func $assembly/index/allocateBlock (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) - global.get $assembly/index/ROOT + (local $3 i32) + local.get $0 + local.get $1 + call $assembly/index/prepareSize + local.tee $3 + call $assembly/index/searchBlock local.tee $2 i32.eqz if - call $assembly/index/initialize - local.tee $2 - global.set $assembly/index/ROOT - end - local.get $0 - i32.const 1073741824 - i32.ge_u - if - i32.const 0 - i32.const 24 - i32.const 495 - i32.const 29 - call $~lib/builtins/abort - unreachable + local.get $0 + local.get $3 + call $assembly/index/growMemory + local.get $0 + local.get $3 + call $assembly/index/searchBlock + local.set $2 end local.get $2 - local.get $0 - i32.const 15 - i32.add - i32.const -16 - i32.and - local.tee $0 - i32.const 16 - local.tee $1 - local.get $0 - local.get $1 - i32.gt_u - select - local.tee $1 - call $assembly/index/searchBlock - local.tee $0 - i32.eqz - if - local.get $2 - local.get $1 - call $assembly/index/growMemory - local.get $2 - local.get $1 - call $assembly/index/searchBlock - local.set $0 - end - local.get $0 i32.const 0 i32.store offset=4 - local.get $0 + local.get $2 i32.const 0 i32.store offset=8 - local.get $0 + local.get $2 local.get $1 i32.store offset=12 + local.get $0 local.get $2 + call $assembly/index/removeBlock + local.get $0 + local.get $2 + local.get $3 + call $assembly/index/prepareBlock + local.get $2 + ) + (func $assembly/index/__mm_allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + global.get $assembly/index/ROOT + local.tee $1 + i32.eqz + if + call $assembly/index/initialize + local.tee $1 + global.set $assembly/index/ROOT + end + local.get $1 + local.get $0 + call $assembly/index/allocateBlock + i32.const 16 + i32.add + ) + (func $~lib/memory/memory.copy (; 11 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + block $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.eq + br_if $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $1 + i32.lt_u + if + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|0 + local.get $0 + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + br $continue|0 + end + end + loop $continue|1 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $0 + local.get $1 + i64.load + i64.store + local.get $2 + i32.const 8 + i32.sub + local.set $2 + local.get $0 + i32.const 8 + i32.add + local.set $0 + local.get $1 + i32.const 8 + i32.add + local.set $1 + br $continue|1 + end + end + end + loop $continue|2 + local.get $2 + if + local.get $0 + local.tee $3 + i32.const 1 + i32.add + local.set $0 + local.get $3 + block (result i32) + local.get $1 + local.tee $3 + i32.const 1 + i32.add + local.set $1 + local.get $3 + i32.load8_u + end + i32.store8 + local.get $2 + i32.const 1 + i32.sub + local.set $2 + br $continue|2 + end + end + else + local.get $1 + i32.const 7 + i32.and + local.get $0 + i32.const 7 + i32.and + i32.eq + if + loop $continue|3 + local.get $0 + local.get $2 + i32.add + i32.const 7 + i32.and + if + local.get $2 + i32.eqz + br_if $~lib/util/memory/memmove|inlined.0 + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|3 + end + end + loop $continue|4 + local.get $2 + i32.const 8 + i32.ge_u + if + local.get $2 + i32.const 8 + i32.sub + local.tee $2 + local.get $0 + i32.add + local.get $1 + local.get $2 + i32.add + i64.load + i64.store + br $continue|4 + end + end + end + loop $continue|5 + local.get $2 + if + local.get $0 + local.get $2 + i32.const 1 + i32.sub + local.tee $2 + i32.add + local.get $1 + local.get $2 + i32.add + i32.load8_u + i32.store8 + br $continue|5 + end + end + end + end + ) + (func $assembly/index/reallocateBlock (; 12 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + local.get $2 + call $assembly/index/prepareSize + local.tee $3 + local.get $1 + i32.load + local.tee $4 + i32.const -4 + i32.and + i32.le_u + if + local.get $0 + local.get $1 + local.get $3 + call $assembly/index/prepareBlock + local.get $1 + local.get $2 + i32.store offset=12 + local.get $1 + return + end + local.get $1 + i32.const 16 + i32.add + local.get $1 + i32.load + i32.const -4 + i32.and + i32.add + local.tee $6 + i32.load + local.tee $5 + i32.const 1 + i32.and + if + local.get $4 + i32.const -4 + i32.and + i32.const 16 + i32.add + local.get $5 + i32.const -4 + i32.and + i32.add + local.tee $5 + local.get $3 + i32.ge_u + if + local.get $0 + local.get $6 + call $assembly/index/removeBlock + local.get $1 + local.get $4 + i32.const 3 + i32.and + local.get $5 + i32.or + i32.store + local.get $1 + local.get $2 + i32.store offset=12 + local.get $0 + local.get $1 + local.get $3 + call $assembly/index/prepareBlock + local.get $1 + return + end + end + local.get $0 + local.get $2 + call $assembly/index/allocateBlock + local.tee $3 + local.get $1 + i32.load offset=4 + i32.store offset=4 + local.get $3 + local.get $1 + i32.load offset=8 + i32.store offset=8 + local.get $3 + i32.const 16 + i32.add + local.get $1 + i32.const 16 + i32.add + local.get $2 + call $~lib/memory/memory.copy + local.get $1 + local.get $4 + i32.const 1 + i32.or + i32.store local.get $0 local.get $1 - call $assembly/index/prepareBlock + call $assembly/index/insertBlock + local.get $3 ) - (func $assembly/index/freeBlock (; 9 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $assembly/index/__mm_reallocate (; 13 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + global.get $assembly/index/ROOT + local.get $0 + i32.const 16 + i32.sub + local.get $1 + call $assembly/index/reallocateBlock + i32.const 16 + i32.add + ) + (func $assembly/index/freeBlock (; 14 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) local.get $1 local.get $1 i32.load @@ -783,22 +1080,14 @@ local.get $1 call $assembly/index/insertBlock ) - (func $assembly/index/__mm_free (; 10 ;) (type $FUNCSIG$vi) (param $0 i32) - (local $1 i32) + (func $assembly/index/__mm_free (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) + global.get $assembly/index/ROOT local.get $0 - if - global.get $assembly/index/ROOT - local.tee $1 - if - local.get $1 - local.get $0 - i32.const 16 - i32.sub - call $assembly/index/freeBlock - end - end + i32.const 16 + i32.sub + call $assembly/index/freeBlock ) - (func $assembly/index/decrement (; 11 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/decrement (; 16 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 i32.load offset=4 i32.const 268435455 @@ -813,7 +1102,7 @@ end unreachable ) - (func $assembly/index/markGray (; 12 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/markGray (; 17 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -833,7 +1122,7 @@ unreachable end ) - (func $assembly/index/scanBlack (; 13 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/scanBlack (; 18 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 local.get $0 i32.load offset=4 @@ -842,7 +1131,7 @@ i32.store offset=4 unreachable ) - (func $assembly/index/scan (; 14 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/scan (; 19 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -872,7 +1161,7 @@ end end ) - (func $assembly/index/collectWhite (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/collectWhite (; 20 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -894,7 +1183,7 @@ local.get $0 call $assembly/index/freeBlock ) - (func $assembly/index/__rt_visit (; 16 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $assembly/index/__rt_visit (; 21 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) block $break|0 block $case4|0 block $case3|0 @@ -944,7 +1233,7 @@ call $assembly/index/collectWhite end ) - (func $assembly/index/__gc_retain (; 17 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/__gc_retain (; 22 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if local.get $0 @@ -958,7 +1247,7 @@ i32.store offset=4 end ) - (func $assembly/index/__gc_release (; 18 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/__gc_release (; 23 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if local.get $0 @@ -967,7 +1256,7 @@ call $assembly/index/decrement end ) - (func $assembly/index/collectCycles (; 19 ;) (type $FUNCSIG$v) + (func $assembly/index/collectCycles (; 24 ;) (type $FUNCSIG$v) (local $0 i32) (local $1 i32) (local $2 i32) @@ -1089,7 +1378,7 @@ local.get $5 global.set $assembly/index/CUR ) - (func $null (; 20 ;) (type $FUNCSIG$v) + (func $null (; 25 ;) (type $FUNCSIG$v) nop ) ) diff --git a/tests/runtime/untouched.wasm b/tests/runtime/untouched.wasm new file mode 100644 index 00000000..d5fdae90 Binary files /dev/null and b/tests/runtime/untouched.wasm differ diff --git a/tests/runtime/untouched.wat b/tests/runtime/untouched.wat index 16c44551..5b5a1d4c 100644 --- a/tests/runtime/untouched.wat +++ b/tests/runtime/untouched.wat @@ -5,9 +5,9 @@ (type $FUNCSIG$viiii (func (param i32 i32 i32 i32))) (type $FUNCSIG$vii (func (param i32 i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$viii (func (param i32 i32 i32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$v (func)) - (type $FUNCSIG$viii (func (param i32 i32 i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (memory $0 1) (data (i32.const 8) "\10\00\00\00\"\00\00\00\00\00\00\00\00\00\00\00a\00s\00s\00e\00m\00b\00l\00y\00/\00i\00n\00d\00e\00x\00.\00t\00s\00") @@ -22,6 +22,7 @@ (global $~lib/memory/HEAP_BASE i32 (i32.const 108)) (export "memory" (memory $0)) (export "__mm_allocate" (func $assembly/index/__mm_allocate)) + (export "__mm_reallocate" (func $assembly/index/__mm_reallocate)) (export "__mm_free" (func $assembly/index/__mm_free)) (export "__rt_visit" (func $assembly/index/__rt_visit)) (export "__gc_retain" (func $assembly/index/__gc_retain)) @@ -48,7 +49,7 @@ if i32.const 0 i32.const 24 - i32.const 282 + i32.const 276 i32.const 13 call $~lib/builtins/abort unreachable @@ -73,7 +74,7 @@ if i32.const 0 i32.const 24 - i32.const 284 + i32.const 278 i32.const 13 call $~lib/builtins/abort unreachable @@ -125,7 +126,7 @@ if i32.const 0 i32.const 24 - i32.const 297 + i32.const 291 i32.const 13 call $~lib/builtins/abort unreachable @@ -263,7 +264,7 @@ if i32.const 0 i32.const 24 - i32.const 210 + i32.const 204 i32.const 13 call $~lib/builtins/abort unreachable @@ -278,7 +279,7 @@ if i32.const 0 i32.const 24 - i32.const 212 + i32.const 206 i32.const 13 call $~lib/builtins/abort unreachable @@ -358,7 +359,7 @@ i32.const 2 i32.and if - block $assembly/index/GETLEFT|inlined.0 (result i32) + block $assembly/index/GETFREELEFT|inlined.0 (result i32) local.get $1 local.set $3 local.get $3 @@ -377,7 +378,7 @@ if i32.const 0 i32.const 24 - i32.const 233 + i32.const 227 i32.const 15 call $~lib/builtins/abort unreachable @@ -440,7 +441,7 @@ if i32.const 0 i32.const 24 - i32.const 248 + i32.const 242 i32.const 13 call $~lib/builtins/abort unreachable @@ -456,7 +457,7 @@ if i32.const 0 i32.const 24 - i32.const 249 + i32.const 243 i32.const 13 call $~lib/builtins/abort unreachable @@ -513,7 +514,7 @@ if i32.const 0 i32.const 24 - i32.const 265 + i32.const 259 i32.const 13 call $~lib/builtins/abort unreachable @@ -636,7 +637,7 @@ if i32.const 0 i32.const 24 - i32.const 399 + i32.const 385 i32.const 4 call $~lib/builtins/abort unreachable @@ -661,7 +662,7 @@ if i32.const 0 i32.const 24 - i32.const 409 + i32.const 395 i32.const 15 call $~lib/builtins/abort unreachable @@ -692,7 +693,7 @@ if i32.const 0 i32.const 24 - i32.const 421 + i32.const 407 i32.const 4 call $~lib/builtins/abort unreachable @@ -915,7 +916,36 @@ drop local.get $3 ) - (func $assembly/index/searchBlock (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (func $assembly/index/prepareSize (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + local.get $0 + i32.const 1073741824 + i32.ge_u + if + i32.const 0 + i32.const 24 + i32.const 466 + i32.const 29 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 15 + i32.add + i32.const 15 + i32.const -1 + i32.xor + i32.and + local.tee $1 + i32.const 16 + local.tee $2 + local.get $1 + local.get $2 + i32.gt_u + select + ) + (func $assembly/index/searchBlock (; 6 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -989,7 +1019,7 @@ if i32.const 0 i32.const 24 - i32.const 343 + i32.const 337 i32.const 13 call $~lib/builtins/abort unreachable @@ -1054,7 +1084,7 @@ if i32.const 0 i32.const 24 - i32.const 356 + i32.const 350 i32.const 17 call $~lib/builtins/abort unreachable @@ -1104,7 +1134,7 @@ end local.get $7 ) - (func $assembly/index/growMemory (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $assembly/index/growMemory (; 7 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) @@ -1157,38 +1187,26 @@ call $assembly/index/addMemory drop ) - (func $assembly/index/prepareBlock (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $assembly/index/prepareBlock (; 8 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) local.get $1 i32.load local.set $3 - local.get $3 - i32.const 1 + local.get $2 + i32.const 15 i32.and - i32.const 0 - i32.ne - if (result i32) - local.get $2 - i32.const 15 - i32.and - i32.eqz - else - i32.const 0 - end + i32.eqz i32.eqz if i32.const 0 i32.const 24 - i32.const 371 - i32.const 4 + i32.const 364 + i32.const 13 call $~lib/builtins/abort unreachable end - local.get $0 - local.get $1 - call $assembly/index/removeBlock local.get $3 i32.const 3 i32.const -1 @@ -1269,15 +1287,75 @@ i32.and i32.store end - local.get $1 - i32.const 16 - i32.add ) - (func $assembly/index/__mm_allocate (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - (local $1 i32) + (func $assembly/index/allocateBlock (; 9 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) - (local $4 i32) + local.get $1 + call $assembly/index/prepareSize + local.set $2 + local.get $0 + local.get $2 + call $assembly/index/searchBlock + local.set $3 + local.get $3 + i32.eqz + if + local.get $0 + local.get $2 + call $assembly/index/growMemory + local.get $0 + local.get $2 + call $assembly/index/searchBlock + local.set $3 + local.get $3 + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 477 + i32.const 15 + call $~lib/builtins/abort + unreachable + end + end + local.get $3 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + local.get $2 + i32.ge_u + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 479 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $3 + i32.const 0 + i32.store offset=4 + local.get $3 + i32.const 0 + i32.store offset=8 + local.get $3 + local.get $1 + i32.store offset=12 + local.get $0 + local.get $3 + call $assembly/index/removeBlock + local.get $0 + local.get $3 + local.get $2 + call $assembly/index/prepareBlock + local.get $3 + ) + (func $assembly/index/__mm_allocate (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) global.get $assembly/index/ROOT local.set $1 local.get $1 @@ -1287,159 +1365,13 @@ local.tee $1 global.set $assembly/index/ROOT end + local.get $1 local.get $0 - i32.const 1073741824 - i32.ge_u - if - i32.const 0 - i32.const 24 - i32.const 495 - i32.const 29 - call $~lib/builtins/abort - unreachable - end - local.get $0 - i32.const 15 - i32.add - i32.const 15 - i32.const -1 - i32.xor - i32.and - local.tee $2 + call $assembly/index/allocateBlock i32.const 16 - local.tee $3 - local.get $2 - local.get $3 - i32.gt_u - select - local.set $0 - local.get $1 - local.get $0 - call $assembly/index/searchBlock - local.set $4 - local.get $4 - i32.eqz - if - local.get $1 - local.get $0 - call $assembly/index/growMemory - local.get $1 - local.get $0 - call $assembly/index/searchBlock - local.set $4 - local.get $4 - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 501 - i32.const 15 - call $~lib/builtins/abort - unreachable - end - end - local.get $4 - i32.load - i32.const 3 - i32.const -1 - i32.xor - i32.and - local.get $0 - i32.ge_u - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 503 - i32.const 13 - call $~lib/builtins/abort - unreachable - end - local.get $4 - i32.const 0 - i32.store offset=4 - local.get $4 - i32.const 0 - i32.store offset=8 - local.get $4 - local.get $0 - i32.store offset=12 - local.get $1 - local.get $4 - local.get $0 - call $assembly/index/prepareBlock + i32.add ) - (func $assembly/index/freeBlock (; 9 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) - (local $2 i32) - local.get $1 - i32.load - local.set $2 - local.get $2 - i32.const 1 - i32.and - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 480 - i32.const 2 - call $~lib/builtins/abort - unreachable - end - local.get $1 - local.get $2 - i32.const 1 - i32.or - i32.store - local.get $0 - local.get $1 - call $assembly/index/insertBlock - ) - (func $assembly/index/__mm_free (; 10 ;) (type $FUNCSIG$vi) (param $0 i32) - (local $1 i32) - local.get $0 - if - local.get $0 - i32.const 15 - i32.and - i32.eqz - i32.eqz - if - i32.const 0 - i32.const 24 - i32.const 514 - i32.const 4 - call $~lib/builtins/abort - unreachable - end - global.get $assembly/index/ROOT - local.set $1 - local.get $1 - if - local.get $1 - local.get $0 - i32.const 16 - i32.sub - call $assembly/index/freeBlock - end - end - ) - (func $assembly/index/__rt_visit_members (; 11 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) - unreachable - ) - (func $assembly/index/__rt_flags (; 12 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - unreachable - ) - (func $~lib/memory/memory.allocate (; 13 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) - i32.const 0 - i32.const 80 - i32.const 61 - i32.const 9 - call $~lib/builtins/abort - unreachable - ) - (func $~lib/memory/memory.copy (; 14 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) + (func $~lib/memory/memory.copy (; 11 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) @@ -1648,7 +1580,260 @@ end end ) - (func $assembly/index/growRoots (; 15 ;) (type $FUNCSIG$v) + (func $assembly/index/reallocateBlock (; 12 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + local.get $2 + call $assembly/index/prepareSize + local.set $3 + local.get $1 + i32.load + local.set $4 + local.get $4 + i32.const 1 + i32.and + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 492 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $3 + local.get $4 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.le_u + if + local.get $0 + local.get $1 + local.get $3 + call $assembly/index/prepareBlock + local.get $1 + local.get $2 + i32.store offset=12 + local.get $1 + return + end + block $assembly/index/GETRIGHT|inlined.4 (result i32) + local.get $1 + local.set $5 + local.get $5 + i32.const 16 + i32.add + local.get $5 + i32.load + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + end + local.set $6 + local.get $6 + i32.load + local.set $7 + local.get $7 + i32.const 1 + i32.and + if + local.get $4 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.const 16 + i32.add + local.get $7 + i32.const 3 + i32.const -1 + i32.xor + i32.and + i32.add + local.set $5 + local.get $5 + local.get $3 + i32.ge_u + if + local.get $0 + local.get $6 + call $assembly/index/removeBlock + local.get $1 + local.get $4 + i32.const 3 + i32.and + local.get $5 + i32.or + i32.store + local.get $1 + local.get $2 + i32.store offset=12 + local.get $0 + local.get $1 + local.get $3 + call $assembly/index/prepareBlock + local.get $1 + return + end + end + local.get $0 + local.get $2 + call $assembly/index/allocateBlock + local.set $8 + local.get $8 + local.get $1 + i32.load offset=4 + i32.store offset=4 + local.get $8 + local.get $1 + i32.load offset=8 + i32.store offset=8 + local.get $8 + i32.const 16 + i32.add + local.get $1 + i32.const 16 + i32.add + local.get $2 + call $~lib/memory/memory.copy + local.get $1 + local.get $4 + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $1 + call $assembly/index/insertBlock + local.get $8 + ) + (func $assembly/index/__mm_reallocate (; 13 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + global.get $assembly/index/ROOT + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 548 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 0 + i32.ne + if (result i32) + local.get $0 + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 549 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + global.get $assembly/index/ROOT + local.get $0 + i32.const 16 + i32.sub + local.get $1 + call $assembly/index/reallocateBlock + i32.const 16 + i32.add + ) + (func $assembly/index/freeBlock (; 14 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (local $2 i32) + local.get $1 + i32.load + local.set $2 + local.get $2 + i32.const 1 + i32.and + i32.eqz + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 530 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + local.get $1 + local.get $2 + i32.const 1 + i32.or + i32.store + local.get $0 + local.get $1 + call $assembly/index/insertBlock + ) + (func $assembly/index/__mm_free (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) + global.get $assembly/index/ROOT + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 556 + i32.const 13 + call $~lib/builtins/abort + unreachable + end + local.get $0 + i32.const 0 + i32.ne + if (result i32) + local.get $0 + i32.const 15 + i32.and + i32.eqz + else + i32.const 0 + end + i32.eqz + if + i32.const 0 + i32.const 24 + i32.const 557 + i32.const 2 + call $~lib/builtins/abort + unreachable + end + global.get $assembly/index/ROOT + local.get $0 + i32.const 16 + i32.sub + call $assembly/index/freeBlock + ) + (func $assembly/index/__rt_visit_members (; 16 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + unreachable + ) + (func $assembly/index/__rt_flags (; 17 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + unreachable + ) + (func $~lib/memory/memory.allocate (; 18 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) + i32.const 0 + i32.const 80 + i32.const 61 + i32.const 9 + call $~lib/builtins/abort + unreachable + ) + (func $assembly/index/growRoots (; 19 ;) (type $FUNCSIG$v) (local $0 i32) (local $1 i32) (local $2 i32) @@ -1692,7 +1877,7 @@ i32.add global.set $assembly/index/END ) - (func $assembly/index/appendRoot (; 16 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/appendRoot (; 20 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) global.get $assembly/index/CUR local.set $1 @@ -1712,7 +1897,7 @@ i32.add global.set $assembly/index/CUR ) - (func $assembly/index/decrement (; 17 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/decrement (; 21 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) (local $2 i32) local.get $0 @@ -1754,7 +1939,7 @@ if i32.const 0 i32.const 24 - i32.const 637 + i32.const 678 i32.const 15 call $~lib/builtins/abort unreachable @@ -1798,7 +1983,7 @@ end end ) - (func $assembly/index/markGray (; 18 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/markGray (; 22 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -1823,7 +2008,7 @@ call $assembly/index/__rt_visit_members end ) - (func $assembly/index/scanBlack (; 19 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/scanBlack (; 23 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 local.get $0 i32.load offset=4 @@ -1838,7 +2023,7 @@ i32.const 4 call $assembly/index/__rt_visit_members ) - (func $assembly/index/scan (; 20 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/scan (; 24 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -1873,7 +2058,7 @@ end end ) - (func $assembly/index/collectWhite (; 21 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/collectWhite (; 25 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -1900,7 +2085,7 @@ local.get $0 call $assembly/index/freeBlock ) - (func $assembly/index/__rt_visit (; 22 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (func $assembly/index/__rt_visit (; 26 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) block $break|0 block $case5|0 @@ -1952,7 +2137,7 @@ if i32.const 0 i32.const 24 - i32.const 592 + i32.const 633 i32.const 17 call $~lib/builtins/abort unreachable @@ -1999,7 +2184,7 @@ if i32.const 0 i32.const 24 - i32.const 603 + i32.const 644 i32.const 6 call $~lib/builtins/abort unreachable @@ -2036,14 +2221,14 @@ if i32.const 0 i32.const 24 - i32.const 614 + i32.const 655 i32.const 24 call $~lib/builtins/abort unreachable end end ) - (func $assembly/index/increment (; 23 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/increment (; 27 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) local.get $0 i32.load offset=4 @@ -2065,7 +2250,7 @@ if i32.const 0 i32.const 24 - i32.const 621 + i32.const 662 i32.const 2 call $~lib/builtins/abort unreachable @@ -2076,7 +2261,7 @@ i32.add i32.store offset=4 ) - (func $assembly/index/__gc_retain (; 24 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/__gc_retain (; 28 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if local.get $0 @@ -2085,7 +2270,7 @@ call $assembly/index/increment end ) - (func $assembly/index/__gc_release (; 25 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $assembly/index/__gc_release (; 29 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if local.get $0 @@ -2094,7 +2279,7 @@ call $assembly/index/decrement end ) - (func $assembly/index/collectCycles (; 26 ;) (type $FUNCSIG$v) + (func $assembly/index/collectCycles (; 30 ;) (type $FUNCSIG$v) (local $0 i32) (local $1 i32) (local $2 i32) @@ -2246,6 +2431,6 @@ local.get $0 global.set $assembly/index/CUR ) - (func $null (; 27 ;) (type $FUNCSIG$v) + (func $null (; 31 ;) (type $FUNCSIG$v) ) )