This commit is contained in:
dcode 2019-04-17 06:12:02 +02:00
parent 0ba0d8ae7a
commit 504e207184
8 changed files with 852 additions and 759 deletions

View File

@ -1,12 +1,12 @@
(module (module
(type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32)))
(type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$i (func (result i32)))
(type $FUNCSIG$vii (func (param i32 i32)))
(type $FUNCSIG$viii (func (param i32 i32 i32)))
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$iiii (func (param i32 i32 i32) (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$iii (func (param i32 i32) (result i32)))
(type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$vi (func (param i32)))
(type $FUNCSIG$viii (func (param i32 i32 i32)))
(type $FUNCSIG$v (func)) (type $FUNCSIG$v (func))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32))) (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
(memory $0 1) (memory $0 1)
@ -17,70 +17,7 @@
(export "memory.allocate" (func $assembly/index/memory.allocate)) (export "memory.allocate" (func $assembly/index/memory.allocate))
(export "memory.free" (func $assembly/index/memory.free)) (export "memory.free" (func $assembly/index/memory.free))
(export "memory.fill" (func $assembly/index/memory.fill)) (export "memory.fill" (func $assembly/index/memory.fill))
(func $../../runtime/assembly/index/setTail (; 1 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (func $../../runtime/assembly/index/removeBlock (; 1 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
local.get $0
local.get $1
i32.store offset=1568
)
(func $../../runtime/assembly/index/setSLMap (; 2 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0
local.get $1
i32.const 2
i32.shl
i32.add
local.get $2
i32.store offset=4
)
(func $../../runtime/assembly/index/setHead (; 3 ;) (type $FUNCSIG$viiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
local.get $0
local.get $1
i32.const 4
i32.shl
local.get $2
i32.add
i32.const 2
i32.shl
i32.add
local.get $3
i32.store offset=96
)
(func $../../runtime/assembly/index/getRight (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0
i32.const 16
i32.add
local.get $0
i32.load
i32.const -4
i32.and
i32.add
)
(func $../../runtime/assembly/index/fls<usize> (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
i32.const 31
local.get $0
i32.clz
i32.sub
)
(func $../../runtime/assembly/index/getHead (; 6 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
local.get $0
local.get $1
i32.const 4
i32.shl
local.get $2
i32.add
i32.const 2
i32.shl
i32.add
i32.load offset=96
)
(func $../../runtime/assembly/index/getSLMap (; 7 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
local.get $0
local.get $1
i32.const 2
i32.shl
i32.add
i32.load offset=4
)
(func $../../runtime/assembly/index/removeBlock (; 8 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32) (local $2 i32)
(local $3 i32) (local $3 i32)
(local $4 i32) (local $4 i32)
@ -100,8 +37,10 @@
i32.const 0 i32.const 0
else else
local.get $2 local.get $2
i32.const 31
local.get $2 local.get $2
call $../../runtime/assembly/index/fls<usize> i32.clz
i32.sub
local.tee $3 local.tee $3
i32.const 4 i32.const 4
i32.sub i32.sub
@ -131,26 +70,44 @@
local.get $5 local.get $5
i32.store offset=16 i32.store offset=16
end end
local.get $1
local.get $0 local.get $0
local.get $3 local.get $3
i32.const 4
i32.shl
local.get $4 local.get $4
call $../../runtime/assembly/index/getHead i32.add
local.get $1 i32.const 2
i32.shl
i32.add
i32.load offset=96
i32.eq i32.eq
if if
local.get $0 local.get $0
local.get $3 local.get $3
i32.const 4
i32.shl
local.get $4 local.get $4
i32.add
i32.const 2
i32.shl
i32.add
local.get $2 local.get $2
call $../../runtime/assembly/index/setHead i32.store offset=96
local.get $2 local.get $2
i32.eqz i32.eqz
if if
local.get $0 local.get $0
local.get $3 local.get $3
i32.const 2
i32.shl
i32.add
local.get $0 local.get $0
local.get $3 local.get $3
call $../../runtime/assembly/index/getSLMap i32.const 2
i32.shl
i32.add
i32.load offset=4
i32.const 1 i32.const 1
local.get $4 local.get $4
i32.shl i32.shl
@ -158,7 +115,7 @@
i32.xor i32.xor
i32.and i32.and
local.tee $1 local.tee $1
call $../../runtime/assembly/index/setSLMap i32.store offset=4
local.get $1 local.get $1
i32.eqz i32.eqz
if if
@ -176,7 +133,7 @@
end end
end end
) )
(func $../../runtime/assembly/index/insertBlock (; 9 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (func $../../runtime/assembly/index/insertBlock (; 2 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32) (local $2 i32)
(local $3 i32) (local $3 i32)
(local $4 i32) (local $4 i32)
@ -185,16 +142,22 @@
(local $7 i32) (local $7 i32)
local.get $1 local.get $1
i32.load i32.load
local.set $3 local.set $2
local.get $1 local.get $1
call $../../runtime/assembly/index/getRight i32.const 16
i32.add
local.get $1
i32.load
i32.const -4
i32.and
i32.add
local.tee $4 local.tee $4
i32.load i32.load
local.tee $5 local.tee $5
i32.const 1 i32.const 1
i32.and i32.and
if if
local.get $3 local.get $2
i32.const -4 i32.const -4
i32.and i32.and
i32.const 16 i32.const 16
@ -203,7 +166,7 @@
i32.const -4 i32.const -4
i32.and i32.and
i32.add i32.add
local.tee $2 local.tee $3
i32.const 1073741824 i32.const 1073741824
i32.lt_u i32.lt_u
if if
@ -211,21 +174,27 @@
local.get $4 local.get $4
call $../../runtime/assembly/index/removeBlock call $../../runtime/assembly/index/removeBlock
local.get $1 local.get $1
local.get $3 local.get $2
i32.const 3 i32.const 3
i32.and i32.and
local.get $2 local.get $3
i32.or i32.or
local.tee $3 local.tee $2
i32.store i32.store
local.get $1 local.get $1
call $../../runtime/assembly/index/getRight i32.const 16
i32.add
local.get $1
i32.load
i32.const -4
i32.and
i32.add
local.tee $4 local.tee $4
i32.load i32.load
local.set $5 local.set $5
end end
end end
local.get $3 local.get $2
i32.const 2 i32.const 2
i32.and i32.and
if if
@ -233,14 +202,14 @@
i32.const 4 i32.const 4
i32.sub i32.sub
i32.load i32.load
local.tee $2 local.tee $3
i32.load i32.load
local.tee $6 local.tee $6
i32.const -4 i32.const -4
i32.and i32.and
i32.const 16 i32.const 16
i32.add i32.add
local.get $3 local.get $2
i32.const -4 i32.const -4
i32.and i32.and
i32.add i32.add
@ -249,17 +218,17 @@
i32.lt_u i32.lt_u
if if
local.get $0 local.get $0
local.get $2 local.get $3
call $../../runtime/assembly/index/removeBlock call $../../runtime/assembly/index/removeBlock
local.get $2 local.get $3
local.get $6 local.get $6
i32.const 3 i32.const 3
i32.and i32.and
local.get $7 local.get $7
i32.or i32.or
local.tee $3 local.tee $2
i32.store i32.store
local.get $2 local.get $3
local.set $1 local.set $1
end end
end end
@ -273,8 +242,7 @@
i32.sub i32.sub
local.get $1 local.get $1
i32.store i32.store
local.get $0 local.get $2
local.get $3
i32.const -4 i32.const -4
i32.and i32.and
local.tee $2 local.tee $2
@ -284,26 +252,36 @@
local.get $2 local.get $2
i32.const 16 i32.const 16
i32.div_u i32.div_u
local.set $3 local.set $2
i32.const 0 i32.const 0
else else
local.get $2 local.get $2
i32.const 31
local.get $2 local.get $2
call $../../runtime/assembly/index/fls<usize> i32.clz
local.tee $2 i32.sub
local.tee $3
i32.const 4 i32.const 4
i32.sub i32.sub
i32.shr_u i32.shr_u
i32.const 16 i32.const 16
i32.xor i32.xor
local.set $3 local.set $2
local.get $2 local.get $3
i32.const 7 i32.const 7
i32.sub i32.sub
end end
local.tee $2 local.set $3
local.get $0
local.get $3 local.get $3
call $../../runtime/assembly/index/getHead i32.const 4
i32.shl
local.get $2
i32.add
i32.const 2
i32.shl
i32.add
i32.load offset=96
local.set $4 local.set $4
local.get $1 local.get $1
i32.const 0 i32.const 0
@ -318,30 +296,42 @@
i32.store offset=16 i32.store offset=16
end end
local.get $0 local.get $0
local.get $2
local.get $3 local.get $3
i32.const 4
i32.shl
local.get $2
i32.add
i32.const 2
i32.shl
i32.add
local.get $1 local.get $1
call $../../runtime/assembly/index/setHead i32.store offset=96
local.get $0 local.get $0
local.get $0 local.get $0
i32.load i32.load
i32.const 1 i32.const 1
local.get $2 local.get $3
i32.shl i32.shl
i32.or i32.or
i32.store i32.store
local.get $0 local.get $0
local.get $2
local.get $0
local.get $2
call $../../runtime/assembly/index/getSLMap
i32.const 1
local.get $3 local.get $3
i32.const 2
i32.shl
i32.add
local.get $0
local.get $3
i32.const 2
i32.shl
i32.add
i32.load offset=4
i32.const 1
local.get $2
i32.shl i32.shl
i32.or i32.or
call $../../runtime/assembly/index/setSLMap i32.store offset=4
) )
(func $../../runtime/assembly/index/addMemory (; 10 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (func $../../runtime/assembly/index/addMemory (; 3 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i32) (local $3 i32)
local.get $2 local.get $2
block (result i32) block (result i32)
@ -400,12 +390,12 @@
i32.store i32.store
local.get $0 local.get $0
local.get $2 local.get $2
call $../../runtime/assembly/index/setTail i32.store offset=1568
local.get $0 local.get $0
local.get $1 local.get $1
call $../../runtime/assembly/index/insertBlock call $../../runtime/assembly/index/insertBlock
) )
(func $../../runtime/assembly/index/initialize (; 11 ;) (type $FUNCSIG$i) (result i32) (func $../../runtime/assembly/index/initialize (; 4 ;) (type $FUNCSIG$i) (result i32)
(local $0 i32) (local $0 i32)
(local $1 i32) (local $1 i32)
(local $2 i32) (local $2 i32)
@ -441,7 +431,7 @@
i32.store i32.store
local.get $0 local.get $0
i32.const 0 i32.const 0
call $../../runtime/assembly/index/setTail i32.store offset=1568
loop $repeat|0 loop $repeat|0
block $break|0 block $break|0
local.get $2 local.get $2
@ -450,8 +440,11 @@
br_if $break|0 br_if $break|0
local.get $0 local.get $0
local.get $2 local.get $2
i32.const 2
i32.shl
i32.add
i32.const 0 i32.const 0
call $../../runtime/assembly/index/setSLMap i32.store offset=4
i32.const 0 i32.const 0
local.set $1 local.set $1
loop $repeat|1 loop $repeat|1
@ -462,9 +455,15 @@
br_if $break|1 br_if $break|1
local.get $0 local.get $0
local.get $2 local.get $2
i32.const 4
i32.shl
local.get $1 local.get $1
i32.add
i32.const 2
i32.shl
i32.add
i32.const 0 i32.const 0
call $../../runtime/assembly/index/setHead i32.store offset=96
local.get $1 local.get $1
i32.const 1 i32.const 1
i32.add i32.add
@ -491,7 +490,7 @@
call $../../runtime/assembly/index/addMemory call $../../runtime/assembly/index/addMemory
local.get $0 local.get $0
) )
(func $../../runtime/assembly/index/searchBlock (; 12 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (func $../../runtime/assembly/index/searchBlock (; 5 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
(local $2 i32) (local $2 i32)
local.get $0 local.get $0
local.get $1 local.get $1
@ -504,26 +503,25 @@
local.set $1 local.set $1
i32.const 0 i32.const 0
else else
block (result i32) i32.const 31
local.get $1 local.get $1
i32.const 536870912 i32.const 1
i32.lt_u i32.const 27
if local.get $1
local.get $1 i32.clz
i32.const 1 i32.sub
local.get $1 i32.shl
call $../../runtime/assembly/index/fls<usize> i32.add
i32.const 4 i32.const 1
i32.sub i32.sub
i32.shl local.get $1
i32.add local.get $1
i32.const 1 i32.const 536870912
i32.sub i32.lt_u
local.set $1 select
end local.tee $1
local.get $1 i32.clz
end i32.sub
call $../../runtime/assembly/index/fls<usize>
local.set $2 local.set $2
local.get $1 local.get $1
local.get $2 local.get $2
@ -538,7 +536,10 @@
i32.sub i32.sub
end end
local.tee $2 local.tee $2
call $../../runtime/assembly/index/getSLMap i32.const 2
i32.shl
i32.add
i32.load offset=4
i32.const -1 i32.const -1
local.get $1 local.get $1
i32.shl i32.shl
@ -546,10 +547,16 @@
local.tee $1 local.tee $1
if (result i32) if (result i32)
local.get $0 local.get $0
local.get $2
local.get $1 local.get $1
i32.ctz i32.ctz
call $../../runtime/assembly/index/getHead local.get $2
i32.const 4
i32.shl
i32.add
i32.const 2
i32.shl
i32.add
i32.load offset=96
else else
local.get $0 local.get $0
i32.load i32.load
@ -561,21 +568,30 @@
i32.and i32.and
local.tee $1 local.tee $1
if (result i32) if (result i32)
local.get $0
local.get $0 local.get $0
local.get $1 local.get $1
i32.ctz i32.ctz
local.tee $1 local.tee $1
local.get $0 i32.const 2
local.get $1 i32.shl
call $../../runtime/assembly/index/getSLMap i32.add
i32.load offset=4
i32.ctz i32.ctz
call $../../runtime/assembly/index/getHead local.get $1
i32.const 4
i32.shl
i32.add
i32.const 2
i32.shl
i32.add
i32.load offset=96
else else
i32.const 0 i32.const 0
end end
end end
) )
(func $../../runtime/assembly/index/growMemory (; 13 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (func $../../runtime/assembly/index/growMemory (; 6 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32)
(local $2 i32) (local $2 i32)
(local $3 i32) (local $3 i32)
(local $4 i32) (local $4 i32)
@ -616,7 +632,7 @@
i32.shl i32.shl
call $../../runtime/assembly/index/addMemory call $../../runtime/assembly/index/addMemory
) )
(func $../../runtime/assembly/index/prepareBlock (; 14 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (func $../../runtime/assembly/index/prepareBlock (; 7 ;) (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
(local $3 i32) (local $3 i32)
(local $4 i32) (local $4 i32)
local.get $1 local.get $1
@ -663,9 +679,21 @@
i32.and i32.and
i32.store i32.store
local.get $1 local.get $1
call $../../runtime/assembly/index/getRight i32.const 16
i32.add
local.get $1 local.get $1
call $../../runtime/assembly/index/getRight i32.load
i32.const -4
i32.and
i32.add
local.get $1
i32.const 16
i32.add
local.get $1
i32.load
i32.const -4
i32.and
i32.add
i32.load i32.load
i32.const -3 i32.const -3
i32.and i32.and
@ -675,7 +703,7 @@
i32.const 16 i32.const 16
i32.add i32.add
) )
(func $../../runtime/assembly/index/__mm_allocate (; 15 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (func $../../runtime/assembly/index/__mm_allocate (; 8 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
(local $1 i32) (local $1 i32)
(local $2 i32) (local $2 i32)
global.get $../../runtime/assembly/index/ROOT global.get $../../runtime/assembly/index/ROOT
@ -692,7 +720,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 498 i32.const 495
i32.const 29 i32.const 29
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -737,11 +765,11 @@
local.get $1 local.get $1
call $../../runtime/assembly/index/prepareBlock call $../../runtime/assembly/index/prepareBlock
) )
(func $assembly/index/memory.allocate (; 16 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32) (func $assembly/index/memory.allocate (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
local.get $0 local.get $0
call $../../runtime/assembly/index/__mm_allocate call $../../runtime/assembly/index/__mm_allocate
) )
(func $../../runtime/assembly/index/__mm_free (; 17 ;) (type $FUNCSIG$vi) (param $0 i32) (func $../../runtime/assembly/index/__mm_free (; 10 ;) (type $FUNCSIG$vi) (param $0 i32)
(local $1 i32) (local $1 i32)
local.get $0 local.get $0
if if
@ -763,11 +791,11 @@
end end
end end
) )
(func $assembly/index/memory.free (; 18 ;) (type $FUNCSIG$vi) (param $0 i32) (func $assembly/index/memory.free (; 11 ;) (type $FUNCSIG$vi) (param $0 i32)
local.get $0 local.get $0
call $../../runtime/assembly/index/__mm_free call $../../runtime/assembly/index/__mm_free
) )
(func $~lib/memory/memory.fill (; 19 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (func $~lib/memory/memory.fill (; 12 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
(local $3 i64) (local $3 i64)
(local $4 i32) (local $4 i32)
block $~lib/util/memory/memset|inlined.0 block $~lib/util/memory/memset|inlined.0
@ -997,13 +1025,13 @@
end end
end end
) )
(func $assembly/index/memory.fill (; 20 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32) (func $assembly/index/memory.fill (; 13 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
local.get $0 local.get $0
local.get $1 local.get $1
local.get $2 local.get $2
call $~lib/memory/memory.fill call $~lib/memory/memory.fill
) )
(func $null (; 21 ;) (type $FUNCSIG$v) (func $null (; 14 ;) (type $FUNCSIG$v)
nop nop
) )
) )

File diff suppressed because it is too large Load Diff

1
tests/runtime/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
!optimized.wasm

View File

@ -15,22 +15,8 @@
/////////////////////// The TLSF (Two-Level Segregate Fit) memory allocator /////////////////////// /////////////////////// The TLSF (Two-Level Segregate Fit) memory allocator ///////////////////////
// see: http://www.gii.upv.es/tlsf/ // see: http://www.gii.upv.es/tlsf/
/** Determines the first (LSB to MSB) set bit's index of a word. */ // - `ffs(x)` is equivalent to `ctz(x)` with x != 0
// @ts-ignore: decorator // - `fls(x)` is equivalent to `sizeof(x) * 8 - clz(x) - 1`
@inline
function ffs<T extends number>(word: T): T {
return ctz<T>(word); // for word != 0
}
/** Determines the last (LSB to MSB) set bit's index of a word. */
// @ts-ignore: decorator
@inline
function fls<T extends number>(word: T): T {
// @ts-ignore: type
const inv: T = sizeof<T>() * 8 - 1;
// @ts-ignore: type
return inv - clz<T>(word);
}
// ╒══════════════ Block size interpretation (32-bit) ═════════════╕ // ╒══════════════ Block size interpretation (32-bit) ═════════════╕
// 3 2 1 // 3 2 1
@ -126,15 +112,13 @@ function fls<T extends number>(word: T): T {
/** Gets the left block of a block. Only valid if the left block is free. */ /** Gets the left block of a block. Only valid if the left block is free. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function GETLEFT(block: Block): Block {
function getLeft(block: Block): Block {
return load<Block>(changetype<usize>(block) - sizeof<usize>()); return load<Block>(changetype<usize>(block) - sizeof<usize>());
} }
/** Gets the right block of of a block by advancing to the right by its size. */ /** Gets the right block of of a block by advancing to the right by its size. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function GETRIGHT(block: Block): Block {
function getRight(block: Block): Block {
return changetype<Block>(changetype<usize>(block) + BLOCK_OVERHEAD + (block.mmInfo & ~TAGS_MASK)); return changetype<Block>(changetype<usize>(block) + BLOCK_OVERHEAD + (block.mmInfo & ~TAGS_MASK));
} }
@ -179,21 +163,21 @@ function getRight(block: Block): Block {
var ROOT: Root; var ROOT: Root;
/** Gets the second level map of the specified first level. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function GETSL(root: Root, fl: usize): u32 {
function getSLMap(root: Root, fl: usize): u32 {
return load<u32>(changetype<usize>(root) + (fl << alignof<u32>()), SL_START); return load<u32>(changetype<usize>(root) + (fl << alignof<u32>()), SL_START);
} }
/** Sets the second level map of the specified first level. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function SETSL(root: Root, fl: usize, value: u32): void {
function setSLMap(root: Root, fl: usize, value: u32): void {
store<u32>(changetype<usize>(root) + (fl << alignof<u32>()), value, SL_START); store<u32>(changetype<usize>(root) + (fl << alignof<u32>()), value, SL_START);
} }
/** Gets the head of the free list for the specified combination of first and second level. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function GETHEAD(root: Root, fl: usize, sl: u32): Block | null {
function getHead(root: Root, fl: usize, sl: u32): Block | null {
return changetype<Block>( return changetype<Block>(
load<usize>( load<usize>(
changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>(), changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>(),
@ -201,23 +185,23 @@ function getHead(root: Root, fl: usize, sl: u32): Block | null {
); );
} }
/** Sets the head of the free list for the specified combination of first and second level. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function SETHEAD(root: Root, fl: usize, sl: u32, head: Block | null): void {
function setHead(root: Root, fl: usize, sl: u32, value: Block | null): void {
store<usize>( store<usize>(
changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>() , changetype<usize>(value), changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>() , changetype<usize>(head),
HL_START); HL_START);
} }
/** Gets the tail block.. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function GETTAIL(root: Root): Block {
function getTail(root: Root): Block {
return load<Block>(changetype<usize>(root), HL_END); return load<Block>(changetype<usize>(root), HL_END);
} }
/** Sets the tail block. */
// @ts-ignore: decorator // @ts-ignore: decorator
@inline @inline function SETTAIL(root: Root, tail: Block): void {
function setTail(root: Root, tail: Block): void {
store<Block>(changetype<usize>(root), tail, HL_END); store<Block>(changetype<usize>(root), tail, HL_END);
} }
@ -227,7 +211,7 @@ function insertBlock(root: Root, block: Block): void {
var blockInfo = block.mmInfo; var blockInfo = block.mmInfo;
if (DEBUG) assert(blockInfo & FREE); // must be free if (DEBUG) assert(blockInfo & FREE); // must be free
var right = getRight(block); var right = GETRIGHT(block);
var rightInfo = right.mmInfo; var rightInfo = right.mmInfo;
// merge with right block if also free // merge with right block if also free
@ -236,7 +220,7 @@ function insertBlock(root: Root, block: Block): void {
if (newSize < BLOCK_MAXSIZE) { if (newSize < BLOCK_MAXSIZE) {
removeBlock(root, right); removeBlock(root, right);
block.mmInfo = blockInfo = (blockInfo & TAGS_MASK) | newSize; block.mmInfo = blockInfo = (blockInfo & TAGS_MASK) | newSize;
right = getRight(block); right = GETRIGHT(block);
rightInfo = right.mmInfo; rightInfo = right.mmInfo;
// 'back' is set below // 'back' is set below
} }
@ -244,7 +228,7 @@ function insertBlock(root: Root, block: Block): void {
// merge with left block if also free // merge with left block if also free
if (blockInfo & LEFTFREE) { if (blockInfo & LEFTFREE) {
let left = getLeft(block); let left = GETLEFT(block);
let leftInfo = left.mmInfo; let leftInfo = left.mmInfo;
if (DEBUG) assert(leftInfo & FREE); // must be free according to right tags if (DEBUG) assert(leftInfo & FREE); // must be free according to right tags
let newSize = (leftInfo & ~TAGS_MASK) + BLOCK_OVERHEAD + (blockInfo & ~TAGS_MASK); let newSize = (leftInfo & ~TAGS_MASK) + BLOCK_OVERHEAD + (blockInfo & ~TAGS_MASK);
@ -273,22 +257,23 @@ function insertBlock(root: Root, block: Block): void {
fl = 0; fl = 0;
sl = <u32>(size / AL_SIZE); sl = <u32>(size / AL_SIZE);
} else { } else {
fl = fls<usize>(size); const inv: usize = sizeof<usize>() * 8 - 1;
fl = inv - clz<usize>(size);
sl = <u32>((size >> (fl - SL_BITS)) ^ (1 << SL_BITS)); sl = <u32>((size >> (fl - SL_BITS)) ^ (1 << SL_BITS));
fl -= SB_BITS - 1; fl -= SB_BITS - 1;
} }
if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range
// perform insertion // perform insertion
var head = getHead(root, fl, sl); var head = GETHEAD(root, fl, sl);
block.prev = null; block.prev = null;
block.next = head; block.next = head;
if (head) head.prev = block; if (head) head.prev = block;
setHead(root, fl, sl, block); SETHEAD(root, fl, sl, block);
// update first and second level maps // update first and second level maps
root.flMap |= (1 << fl); root.flMap |= (1 << fl);
setSLMap(root, fl, getSLMap(root, fl) | (1 << sl)); SETSL(root, fl, GETSL(root, fl) | (1 << sl));
} }
/** Removes a free block from internal lists. */ /** Removes a free block from internal lists. */
@ -304,7 +289,8 @@ function removeBlock(root: Root, block: Block): void {
fl = 0; fl = 0;
sl = <u32>(size / AL_SIZE); sl = <u32>(size / AL_SIZE);
} else { } else {
fl = fls<usize>(size); const inv: usize = sizeof<usize>() * 8 - 1;
fl = inv - clz<usize>(size);
sl = <u32>((size >> (fl - SL_BITS)) ^ (1 << SL_BITS)); sl = <u32>((size >> (fl - SL_BITS)) ^ (1 << SL_BITS));
fl -= SB_BITS - 1; fl -= SB_BITS - 1;
} }
@ -317,13 +303,13 @@ function removeBlock(root: Root, block: Block): void {
if (next) next.prev = prev; if (next) next.prev = prev;
// update head if we are removing it // update head if we are removing it
if (block == getHead(root, fl, sl)) { if (block == GETHEAD(root, fl, sl)) {
setHead(root, fl, sl, next); SETHEAD(root, fl, sl, next);
// clear second level map if head is empty now // clear second level map if head is empty now
if (!next) { if (!next) {
let slMap = getSLMap(root, fl); let slMap = GETSL(root, fl);
setSLMap(root, fl, slMap &= ~(1 << sl)); SETSL(root, fl, slMap &= ~(1 << sl));
// clear first level map if second level is empty now // clear first level map if second level is empty now
if (!slMap) root.flMap &= ~(1 << fl); if (!slMap) root.flMap &= ~(1 << fl);
@ -345,17 +331,19 @@ function searchBlock(root: Root, size: usize): Block | null {
sl = <u32>(size / AL_SIZE); sl = <u32>(size / AL_SIZE);
} else { } else {
const halfMaxSize = BLOCK_MAXSIZE >> 1; // don't round last fl const halfMaxSize = BLOCK_MAXSIZE >> 1; // don't round last fl
const inv: usize = sizeof<usize>() * 8 - 1;
const invRound = inv - SL_BITS;
let requestSize = size < halfMaxSize let requestSize = size < halfMaxSize
? size + (1 << fls<usize>(size) - SL_BITS) - 1 ? size + (1 << (invRound - clz<usize>(size))) - 1
: size; : size;
fl = fls<usize>(requestSize); fl = inv - clz<usize>(requestSize);
sl = <u32>((requestSize >> (fl - SL_BITS)) ^ (1 << SL_BITS)); sl = <u32>((requestSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));
fl -= SB_BITS - 1; fl -= SB_BITS - 1;
} }
if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range
// search second level // search second level
var slMap = getSLMap(root, fl) & (~0 << sl); var slMap = GETSL(root, fl) & (~0 << sl);
var head: Block | null; var head: Block | null;
if (!slMap) { if (!slMap) {
// search next larger first level // search next larger first level
@ -363,13 +351,13 @@ function searchBlock(root: Root, size: usize): Block | null {
if (!flMap) { if (!flMap) {
head = null; head = null;
} else { } else {
fl = ffs<usize>(flMap); fl = ctz<usize>(flMap);
slMap = getSLMap(root, fl); slMap = GETSL(root, fl);
if (DEBUG) assert(slMap); // can't be zero if fl points here if (DEBUG) assert(slMap); // can't be zero if fl points here
head = getHead(root, fl, ffs<u32>(slMap)); head = GETHEAD(root, fl, ctz<u32>(slMap));
} }
} else { } else {
head = getHead(root, fl, ffs<u32>(slMap)); head = GETHEAD(root, fl, ctz<u32>(slMap));
} }
return head; return head;
} }
@ -399,7 +387,7 @@ function prepareBlock(root: Root, block: Block, size: usize): usize {
// 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 LEFT_FREE
} else { } else {
block.mmInfo = blockInfo & ~FREE; block.mmInfo = blockInfo & ~FREE;
getRight(block).mmInfo &= ~LEFTFREE; GETRIGHT(block).mmInfo &= ~LEFTFREE;
} }
return changetype<usize>(block) + BLOCK_OVERHEAD; return changetype<usize>(block) + BLOCK_OVERHEAD;
@ -415,7 +403,7 @@ function addMemory(root: Root, start: usize, end: usize): bool {
); );
} }
var tail = getTail(root); var tail = GETTAIL(root);
var tailInfo: usize = 0; var tailInfo: usize = 0;
if (tail) { // more memory if (tail) { // more memory
if (DEBUG) assert(start >= changetype<usize>(tail) + BLOCK_OVERHEAD); if (DEBUG) assert(start >= changetype<usize>(tail) + BLOCK_OVERHEAD);
@ -449,7 +437,7 @@ function addMemory(root: Root, start: usize, end: usize): bool {
// tail is a zero-length used block // tail is a zero-length used block
tail = changetype<Block>(start + size - BLOCK_OVERHEAD); tail = changetype<Block>(start + size - BLOCK_OVERHEAD);
tail.mmInfo = 0 | LEFTFREE; tail.mmInfo = 0 | LEFTFREE;
setTail(root, tail); SETTAIL(root, tail);
insertBlock(root, left); // also merges with free left before tail / sets 'back' insertBlock(root, left); // also merges with free left before tail / sets 'back'
@ -476,11 +464,11 @@ function initialize(): Root {
if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable(); if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable();
var root = changetype<Root>(rootOffset); var root = changetype<Root>(rootOffset);
root.flMap = 0; root.flMap = 0;
setTail(root, changetype<Block>(0)); SETTAIL(root, changetype<Block>(0));
for (let fl: usize = 0; fl < FL_BITS; ++fl) { for (let fl: usize = 0; fl < FL_BITS; ++fl) {
setSLMap(root, fl, 0); SETSL(root, fl, 0);
for (let sl: u32 = 0; sl < SL_SIZE; ++sl) { for (let sl: u32 = 0; sl < SL_SIZE; ++sl) {
setHead(root, fl, sl, null); SETHEAD(root, fl, sl, null);
} }
} }
addMemory(root, (rootOffset + ROOT_SIZE + AL_MASK) & ~AL_MASK, memory.size() << 16); addMemory(root, (rootOffset + ROOT_SIZE + AL_MASK) & ~AL_MASK, memory.size() << 16);

View File

@ -12,7 +12,7 @@ const HL_SIZE = FL_BITS * SL_SIZE;
var exports; var exports;
var ROOT; var ROOT;
var U32; var U32;
fetch("untouched.wasm").then(result => fetch("optimized.wasm").then(result =>
result.arrayBuffer() result.arrayBuffer()
).then(buffer => ).then(buffer =>
WebAssembly.instantiate(buffer, { WebAssembly.instantiate(buffer, {
@ -62,6 +62,11 @@ function toBits(n, l) {
} }
function init() { function init() {
document.getElementById("albits").innerText = AL_BITS;
document.getElementById("flbits").innerText = FL_BITS;
document.getElementById("slbits").innerText = SL_BITS;
document.getElementById("overhead").innerText = OVERHEAD;
var fls = document.getElementById("fl"); var fls = document.getElementById("fl");
var sls = document.getElementById("sl"); var sls = document.getElementById("sl");
var hls = document.getElementById("hl"); var hls = document.getElementById("hl");
@ -133,8 +138,8 @@ function allocate(size) {
<style> <style>
/* General */ /* General */
body { font-family: sans-serif; font-size: 0.8em; } body { font-family: sans-serif; font-size: 0.8em; margin: 0; padding: 1em; }
h1 { font-size: 1em; } h1 { font-size: 1em; margin: -1em -1em 0 -1em; padding: 1em; background: #7f7; }
h2 { background: #333; color: #ddd; font-size: 1em; padding: 0.5em; border-radius: 5px; } h2 { background: #333; color: #ddd; font-size: 1em; padding: 0.5em; border-radius: 5px; }
input, button { border: 1px solid #999; border-radius: 0.2em; padding: 0.5em; } input, button { border: 1px solid #999; border-radius: 0.2em; padding: 0.5em; }
button { cursor: pointer; background: #ddd; } button { cursor: pointer; background: #ddd; }
@ -143,25 +148,28 @@ button:hover { background: #bbb; }
/* Lists */ /* Lists */
.fl, .sl, .hl, .seg { float: left; padding: 0.4em; margin: 0.2em; border: 1px solid #ddd; border-radius: 3px; } .fl, .sl, .hl, .seg { float: left; padding: 0.4em; margin: 0.2em; border: 1px solid #ddd; border-radius: 3px; }
.sl { min-width: 12em; } .sl { min-width: 12em; }
.hl { min-width: 6em; font-size: 0.8em; } .hl { min-width: 7em; font-size: 0.8em; }
.num { color: #fff; background: rgba(0, 0, 0, 0.3); padding: 0.4em; margin-left: -0.4em; border-radius: 0.2em; } .num { color: #fff; background: rgba(0, 0, 0, 0.3); padding: 0.4em; margin-left: -0.4em; border-radius: 0.2em; }
.set { background: #7f7; } .set { background: #7f7; }
.seg button { margin-left: 0.5em; } .seg button { margin-left: 0.5em; }
.sub { vertical-align: sub; font-size: 0.8em; }
</style> </style>
<h1>AssemblyScript Runtime Visualizer</h1> <h1>AssemblyScript Runtime Visualizer / TLSF</h1>
<p> <p>
<strong>Notes:</strong> <strong>Notes:</strong>
<ul> <ul>
<li>It is expected that there is exactly one block on initialization. This is the remaining space (&lt; 64K) within the last page after static data.</li> <li>It is expected that there is exactly one block on initialization. This is the remaining space (&lt; 64K) within the last page after static data.</li>
<li>It is expected that if two adjacent blocks of size K are freed, the merged block doesn't go into the first level list for K*2 because its size is actually larger than that (K + OVERHEAD + K).</li> <li>It is expected that if two adjacent blocks of size K are freed, the merged block doesn't go into the first level list for K*2 because its size is actually larger than that (K + OVERHEAD + K).</li>
<li>It is expected that if memory grows beyond 1GB, that even if all blocks are free'd there are at least two (or even three if the largest block is in the middle) remaining blocks, because a single block must not be larger than 1GB.</li> <li>It is expected that if memory grows beyond 1GB, that even if all blocks are free'd there are at least two (or even three if the largest block is in the middle) remaining blocks, because a single block must not be larger than 1GB.</li>
<li>It is expected that after other operations have already been performed, being able to allocate 1GB can't be guaranteed anymore, even if there should be enough space left in absolute terms, because prior subdivision prevents it.</li> <li>It is expected that after other operations have already been performed, being able to allocate 1GB can't be guaranteed anymore, even if there should be enough space left in absolute terms, if prior subdivision prevents it.</li>
<li>It is expected that the second level 0 in first level 0 isn't ever used due to alignment guarantees. Smallest block is 32 bytes (16 bytes overhead + 16 bytes payload if used, respectively linking information if free) in this implementation.</li>
</ul> </ul>
</p> </p>
<p><strong>Implementation constants:</strong> <span id="albits">?</span> bits alignment, <span id="flbits">?</span> bits first level, <span id="slbits">?</span> bits second level, <span id="overhead">?</span> B overhead</p>
<h2>First level bitmap</h2> <h2>First level bitmap</h2>
<p>The first level map is a bitmap determining whether free blocks exists in at least one of its respective second levels. In this implementation, the first bit indicates whether a small block (&lt; 256B) exists. Each bit doubles the size.</p> <p>The first level map is a bitmap determining whether free blocks exist in at least one of its respective second levels. In this implementation, the first bit indicates whether a small block (&lt; 256B) exists. Each bit doubles the size.</p>
<div id="fl"></div> <div id="fl"></div>
<div class="clear"></div> <div class="clear"></div>
@ -176,21 +184,41 @@ button:hover { background: #bbb; }
<div class="clear"></div> <div class="clear"></div>
<h2>Allocator</h2> <h2>Allocator</h2>
<p>Chose a size to allocate. Annotated list indexes depend on implementation constants but match those of this implementation.</p>
<p> <p>
Click to allocate: <input type="text" value="1" size="10" id="size" /> <button onclick="allocate(document.getElementById('size').value); update()">B</button> &nbsp;
<input type="text" value="1024" size="10" id="size" /> <button onclick="allocate(document.getElementById('size').value); update()">B</button> &nbsp; </p>
<button onclick="allocate(1024); update()">1 KB</button> <p>
<button onclick="allocate(10240); update()">10 KB</button> Small blocks:
<button onclick="allocate(102400); update()">100 KB</button> &nbsp; <button onclick="allocate(0); update()">0 B</button>
<button onclick="allocate(1048576); update()">1 MB</button> <button onclick="allocate(16); update()">16 B <span class="sub">fl=0 sl=1</span></button>
<button onclick="allocate(10485760); update()">10 MB</button> <button onclick="allocate(32); update()">32 B <span class="sub">fl=0 sl=2</span></button>
<button onclick="allocate(104857600); update()">100 MB</button> <button onclick="allocate(48); update()">48 B <span class="sub">fl=0 sl=3</span></button>
<button onclick="allocate(134217728-OVERHEAD); update()">128 MB - OVERHEAD</button> <button onclick="allocate(64); update()">64 B <span class="sub">fl=0 sl=4</span></button>
<button onclick="allocate(268435456-OVERHEAD); update()">256 MB - OVERHEAD</button> ...
<button onclick="allocate(536870912-OVERHEAD); update()">512 MB - OVERHEAD</button> &nbsp; <button onclick="allocate(256-OVERHEAD); update()">256 B - δ <span class="sub">fl=0 sl=MSB</span></button>
<button onclick="allocate(1073741824-OVERHEAD); update()">1 GB - OVERHEAD</button> (δ ≙ block overhead)
</p>
<p>
Common blocks:
<button onclick="allocate(256); update()">256 B <span class="sub">fl=1 sl=0</span></button>
<button onclick="allocate(512-OVERHEAD); update()">512 B - δ <span class="sub">fl=1 sl=MSB</span></button>
<button onclick="allocate(1024-OVERHEAD); update()">1 KB - δ <span class="sub">fl=2 sl=MSB</span></button>
<button onclick="allocate(2048-OVERHEAD); update()">2 KB - δ <span class="sub">fl=3 sl=MSB</span></button>
<button onclick="allocate(4096-OVERHEAD); update()">4 KB - δ <span class="sub">fl=4 sl=MSB</span></button>
(e.g. allocate 3, free middle, check second level)
</p>
<p>
Large blocks:
<button onclick="allocate(67108864-OVERHEAD); update()">64 MB - δ <span class="sub">fl=MSB-4 sl=MSB</span></button>
<button onclick="allocate(134217728-OVERHEAD); update()">128 MB - δ <span class="sub">fl=MSB-3 sl=MSB</span></button>
<button onclick="allocate(268435456-OVERHEAD); update()">256 MB - δ <span class="sub">fl=MSB-2 sl=MSB</span></button>
<button onclick="allocate(536870912-OVERHEAD); update()">512 MB - δ <span class="sub">fl=MSB-1 sl=MSB</span></button>
<button onclick="allocate(1073741824-OVERHEAD); update()">1 GB - δ <span class="sub">fl=MSB sl=MSB</span></button>
</p>
</p> </p>
<h2>Segments</h2> <h2>Segments</h2>
<p>Allocations performed above are tracked here so you can free them again. Note that TLSF alone does not keep track of used blocks (unless free'd and put in a free list again). It is expected that adjacent free blocks become merged automatically.</p>
<div id="segs"></div> <div id="segs"></div>
<div class="clear"></div> <div class="clear"></div>

Binary file not shown.

View File

@ -727,7 +727,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 507 i32.const 495
i32.const 29 i32.const 29
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable

View File

@ -48,7 +48,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 297 i32.const 282
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -73,7 +73,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 299 i32.const 284
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -89,14 +89,10 @@
i32.div_u i32.div_u
local.set $5 local.set $5
else else
block $assembly/index/fls<usize>|inlined.0 (result i32) i32.const 31
local.get $3 local.get $3
local.set $6 i32.clz
i32.const 31 i32.sub
local.get $6
i32.clz
i32.sub
end
local.set $4 local.set $4
local.get $3 local.get $3
local.get $4 local.get $4
@ -129,42 +125,42 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 311 i32.const 297
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
local.get $1 local.get $1
i32.load offset=16 i32.load offset=16
local.set $7 local.set $6
local.get $1 local.get $1
i32.load offset=20 i32.load offset=20
local.set $8 local.set $7
local.get $6
if
local.get $6
local.get $7
i32.store offset=20
end
local.get $7 local.get $7
if if
local.get $7 local.get $7
local.get $8 local.get $6
i32.store offset=20
end
local.get $8
if
local.get $8
local.get $7
i32.store offset=16 i32.store offset=16
end end
local.get $1 local.get $1
block $assembly/index/getHead|inlined.1 (result i32) block $assembly/index/GETHEAD|inlined.1 (result i32)
local.get $0 local.get $0
local.set $10 local.set $10
local.get $4 local.get $4
local.set $9 local.set $9
local.get $5 local.get $5
local.set $6 local.set $8
local.get $10 local.get $10
local.get $9 local.get $9
i32.const 16 i32.const 16
i32.mul i32.mul
local.get $6 local.get $8
i32.add i32.add
i32.const 4 i32.const 4
i32.mul i32.mul
@ -173,15 +169,15 @@
end end
i32.eq i32.eq
if if
block $assembly/index/setHead|inlined.1 block $assembly/index/SETHEAD|inlined.1
local.get $0 local.get $0
local.set $11 local.set $11
local.get $4 local.get $4
local.set $10 local.set $10
local.get $5 local.get $5
local.set $9 local.set $9
local.get $8 local.get $7
local.set $6 local.set $8
local.get $11 local.get $11
local.get $10 local.get $10
i32.const 16 i32.const 16
@ -191,38 +187,38 @@
i32.const 4 i32.const 4
i32.mul i32.mul
i32.add i32.add
local.get $6 local.get $8
i32.store offset=96 i32.store offset=96
end end
local.get $8 local.get $7
i32.eqz i32.eqz
if if
block $assembly/index/getSLMap|inlined.0 (result i32) block $assembly/index/GETSL|inlined.0 (result i32)
local.get $0 local.get $0
local.set $9 local.set $9
local.get $4 local.get $4
local.set $6 local.set $8
local.get $9 local.get $9
local.get $6 local.get $8
i32.const 2 i32.const 2
i32.shl i32.shl
i32.add i32.add
i32.load offset=4 i32.load offset=4
end end
local.set $6 local.set $8
block $assembly/index/setSLMap|inlined.1 block $assembly/index/SETSL|inlined.1
local.get $0 local.get $0
local.set $11 local.set $11
local.get $4 local.get $4
local.set $10 local.set $10
local.get $6 local.get $8
i32.const 1 i32.const 1
local.get $5 local.get $5
i32.shl i32.shl
i32.const -1 i32.const -1
i32.xor i32.xor
i32.and i32.and
local.tee $6 local.tee $8
local.set $9 local.set $9
local.get $11 local.get $11
local.get $10 local.get $10
@ -232,7 +228,7 @@
local.get $9 local.get $9
i32.store offset=4 i32.store offset=4
end end
local.get $6 local.get $8
i32.eqz i32.eqz
if if
local.get $0 local.get $0
@ -267,7 +263,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 226 i32.const 210
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -282,12 +278,12 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 228 i32.const 212
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
block $assembly/index/getRight|inlined.0 (result i32) block $assembly/index/GETRIGHT|inlined.0 (result i32)
local.get $1 local.get $1
local.set $3 local.set $3
local.get $3 local.get $3
@ -338,7 +334,7 @@
i32.or i32.or
local.tee $2 local.tee $2
i32.store i32.store
block $assembly/index/getRight|inlined.1 (result i32) block $assembly/index/GETRIGHT|inlined.1 (result i32)
local.get $1 local.get $1
local.set $6 local.set $6
local.get $6 local.get $6
@ -362,7 +358,7 @@
i32.const 2 i32.const 2
i32.and i32.and
if if
block $assembly/index/getLeft|inlined.0 (result i32) block $assembly/index/GETLEFT|inlined.0 (result i32)
local.get $1 local.get $1
local.set $3 local.set $3
local.get $3 local.get $3
@ -381,7 +377,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 249 i32.const 233
i32.const 15 i32.const 15
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -444,7 +440,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 264 i32.const 248
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -460,7 +456,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 265 i32.const 249
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -481,14 +477,10 @@
i32.div_u i32.div_u
local.set $10 local.set $10
else else
block $assembly/index/fls<usize>|inlined.1 (result i32) i32.const 31
local.get $8 local.get $8
local.set $7 i32.clz
i32.const 31 i32.sub
local.get $7
i32.clz
i32.sub
end
local.set $9 local.set $9
local.get $8 local.get $8
local.get $9 local.get $9
@ -521,12 +513,12 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 280 i32.const 265
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
block $assembly/index/getHead|inlined.2 (result i32) block $assembly/index/GETHEAD|inlined.2 (result i32)
local.get $0 local.get $0
local.set $3 local.set $3
local.get $9 local.get $9
@ -557,7 +549,7 @@
local.get $1 local.get $1
i32.store offset=16 i32.store offset=16
end end
block $assembly/index/setHead|inlined.2 block $assembly/index/SETHEAD|inlined.2
local.get $0 local.get $0
local.set $12 local.set $12
local.get $9 local.get $9
@ -586,8 +578,8 @@
i32.shl i32.shl
i32.or i32.or
i32.store i32.store
block $assembly/index/setSLMap|inlined.2 block $assembly/index/SETSL|inlined.2
block $assembly/index/getSLMap|inlined.1 (result i32) block $assembly/index/GETSL|inlined.1 (result i32)
local.get $0 local.get $0
local.set $13 local.set $13
local.get $9 local.get $9
@ -644,12 +636,12 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 411 i32.const 399
i32.const 4 i32.const 4
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
block $assembly/index/getTail|inlined.0 (result i32) block $assembly/index/GETTAIL|inlined.0 (result i32)
local.get $0 local.get $0
local.set $3 local.set $3
local.get $3 local.get $3
@ -669,7 +661,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 421 i32.const 409
i32.const 15 i32.const 15
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -700,7 +692,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 433 i32.const 421
i32.const 4 i32.const 4
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -755,7 +747,7 @@
i32.const 2 i32.const 2
i32.or i32.or
i32.store i32.store
block $assembly/index/setTail|inlined.1 block $assembly/index/SETTAIL|inlined.1
local.get $0 local.get $0
local.set $9 local.set $9
local.get $4 local.get $4
@ -823,7 +815,7 @@
local.get $3 local.get $3
i32.const 0 i32.const 0
i32.store i32.store
block $assembly/index/setTail|inlined.0 block $assembly/index/SETTAIL|inlined.0
local.get $3 local.get $3
local.set $5 local.set $5
i32.const 0 i32.const 0
@ -842,7 +834,7 @@
i32.eqz i32.eqz
br_if $break|0 br_if $break|0
block block
block $assembly/index/setSLMap|inlined.0 block $assembly/index/SETSL|inlined.0
local.get $3 local.get $3
local.set $7 local.set $7
local.get $4 local.get $4
@ -866,7 +858,7 @@
i32.lt_u i32.lt_u
i32.eqz i32.eqz
br_if $break|1 br_if $break|1
block $assembly/index/setHead|inlined.0 block $assembly/index/SETHEAD|inlined.0
local.get $3 local.get $3
local.set $9 local.set $9
local.get $4 local.get $4
@ -932,7 +924,6 @@
(local $7 i32) (local $7 i32)
(local $8 i32) (local $8 i32)
(local $9 i32) (local $9 i32)
(local $10 i32)
local.get $1 local.get $1
i32.const 256 i32.const 256
i32.lt_u i32.lt_u
@ -950,15 +941,9 @@
if (result i32) if (result i32)
local.get $1 local.get $1
i32.const 1 i32.const 1
block $assembly/index/fls<usize>|inlined.2 (result i32) i32.const 27
local.get $1 local.get $1
local.set $4 i32.clz
i32.const 31
local.get $4
i32.clz
i32.sub
end
i32.const 4
i32.sub i32.sub
i32.shl i32.shl
i32.add i32.add
@ -968,14 +953,10 @@
local.get $1 local.get $1
end end
local.set $4 local.set $4
block $assembly/index/fls<usize>|inlined.3 (result i32) i32.const 31
local.get $4 local.get $4
local.set $5 i32.clz
i32.const 31 i32.sub
local.get $5
i32.clz
i32.sub
end
local.set $2 local.set $2
local.get $4 local.get $4
local.get $2 local.get $2
@ -1008,12 +989,12 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 355 i32.const 343
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
block $assembly/index/getSLMap|inlined.2 (result i32) block $assembly/index/GETSL|inlined.2 (result i32)
local.get $0 local.get $0
local.set $5 local.set $5
local.get $2 local.get $2
@ -1052,14 +1033,10 @@
i32.const 0 i32.const 0
local.set $7 local.set $7
else else
block $assembly/index/ffs<usize>|inlined.0 (result i32) local.get $4
local.get $4 i32.ctz
local.set $5
local.get $5
i32.ctz
end
local.set $2 local.set $2
block $assembly/index/getSLMap|inlined.3 (result i32) block $assembly/index/GETSL|inlined.3 (result i32)
local.get $0 local.get $0
local.set $8 local.set $8
local.get $2 local.get $2
@ -1077,22 +1054,18 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 368 i32.const 356
i32.const 17 i32.const 17
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
end end
block $assembly/index/getHead|inlined.3 (result i32) block $assembly/index/GETHEAD|inlined.3 (result i32)
local.get $0 local.get $0
local.set $9 local.set $9
local.get $2 local.get $2
local.set $8 local.set $8
block $assembly/index/ffs<u32>|inlined.0 (result i32) local.get $6
local.get $6 i32.ctz
local.set $10
local.get $10
i32.ctz
end
local.set $5 local.set $5
local.get $9 local.get $9
local.get $8 local.get $8
@ -1108,17 +1081,13 @@
local.set $7 local.set $7
end end
else else
block $assembly/index/getHead|inlined.4 (result i32) block $assembly/index/GETHEAD|inlined.4 (result i32)
local.get $0 local.get $0
local.set $8 local.set $8
local.get $2 local.get $2
local.set $5 local.set $5
block $assembly/index/ffs<u32>|inlined.1 (result i32) local.get $6
local.get $6 i32.ctz
local.set $9
local.get $9
i32.ctz
end
local.set $4 local.set $4
local.get $8 local.get $8
local.get $5 local.get $5
@ -1212,7 +1181,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 383 i32.const 371
i32.const 4 i32.const 4
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1265,7 +1234,7 @@
i32.xor i32.xor
i32.and i32.and
i32.store i32.store
block $assembly/index/getRight|inlined.3 (result i32) block $assembly/index/GETRIGHT|inlined.3 (result i32)
local.get $1 local.get $1
local.set $5 local.set $5
local.get $5 local.get $5
@ -1279,7 +1248,7 @@
i32.and i32.and
i32.add i32.add
end end
block $assembly/index/getRight|inlined.2 (result i32) block $assembly/index/GETRIGHT|inlined.2 (result i32)
local.get $1 local.get $1
local.set $5 local.set $5
local.get $5 local.get $5
@ -1324,7 +1293,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 507 i32.const 495
i32.const 29 i32.const 29
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1363,7 +1332,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 513 i32.const 501
i32.const 15 i32.const 15
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1381,7 +1350,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 515 i32.const 503
i32.const 13 i32.const 13
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1413,7 +1382,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 492 i32.const 480
i32.const 2 i32.const 2
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1439,7 +1408,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 526 i32.const 514
i32.const 4 i32.const 4
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1785,7 +1754,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 649 i32.const 637
i32.const 15 i32.const 15
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -1983,7 +1952,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 604 i32.const 592
i32.const 17 i32.const 17
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -2030,7 +1999,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 615 i32.const 603
i32.const 6 i32.const 6
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -2067,7 +2036,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 626 i32.const 614
i32.const 24 i32.const 24
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable
@ -2096,7 +2065,7 @@
if if
i32.const 0 i32.const 0
i32.const 24 i32.const 24
i32.const 633 i32.const 621
i32.const 2 i32.const 2
call $~lib/builtins/abort call $~lib/builtins/abort
unreachable unreachable