realloc on mm level

This commit is contained in:
dcode 2019-04-17 17:48:26 +02:00
parent 504e207184
commit ffdda4b695
9 changed files with 1114 additions and 587 deletions

View File

@ -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)

View File

@ -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)
)
)

View File

@ -1 +1 @@
!optimized.wasm
!untouched.wasm

View File

@ -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<Block>(changetype<usize>(block) - sizeof<usize>());
}
@ -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<u32>(changetype<usize>(root) + (fl << alignof<u32>()), value, SL_START);
@inline function SETSL(root: Root, fl: usize, slMap: u32): void {
store<u32>(changetype<usize>(root) + (fl << alignof<u32>()), 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<Block>(
load<usize>(
changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>(),
HL_START)
);
return changetype<Block>(load<usize>(changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>(), 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<usize>(
changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>() , changetype<usize>(head),
HL_START);
store<usize>(changetype<usize>(root) + (fl * SL_SIZE + <usize>sl) * sizeof<usize>() , changetype<usize>(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<Block>(changetype<usize>(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<usize>(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<usize>((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 = <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>block);
prepareBlock(root, <Block>block, payloadSize);
return <Block>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<usize>(newBlock) + BLOCK_OVERHEAD, changetype<usize>(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<usize>(allocateBlock(root, size)) + BLOCK_OVERHEAD;
}
// search for a suitable block
if (size >= BLOCK_MAXSIZE) throw new Error("allocation too large");
size = max<usize>((size + AL_MASK) & ~AL_MASK, BLOCK_MINSIZE); // align and ensure min size
var block = searchBlock(root, size);
if (!block) {
growMemory(root, size);
block = <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>block, size); // FIXME: why's <Block> 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<usize>(reallocateBlock(ROOT, changetype<Block>(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<Block>(data - BLOCK_OVERHEAD));
}
if (DEBUG) assert(ROOT); // must be initialized
assert(data != 0 && !(data & AL_MASK)); // must exist and be aligned
freeBlock(ROOT, changetype<Block>(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 {}

View File

@ -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 = '<span class="num">' + (i == hl.length - 1 ? "tail" : i) + '</span>' + " " + ptr.toString(16);
el.innerHTML = '<span class="num">' + (i == hl.length - 1 ? "tail" : i) + '</span>' + " " + 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);
}
</script>

Binary file not shown.

View File

@ -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
)
)

Binary file not shown.

View File

@ -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)
)
)