mirror of
https://github.com/DataDog/go-profiler-notes.git
synced 2026-06-23 09:56:47 +08:00
fix unwind tests
This commit is contained in:
parent
81352c678a
commit
ed2fa54799
4 changed files with 3179 additions and 620 deletions
|
|
@ -7,35 +7,17 @@ This directory contains benchmarks to explore which factors impact stack unwindi
|
||||||
The benchmark below shows that stack unwinding has O(N) complexity with regard to the number of call frames on the stack:
|
The benchmark below shows that stack unwinding has O(N) complexity with regard to the number of call frames on the stack:
|
||||||
|
|
||||||
```
|
```
|
||||||
BenchmarkStackDepth/8-12 2208600 547.2 ns/op
|
BenchmarkStackDepth/8-12 1968214 612.2 ns/op
|
||||||
BenchmarkStackDepth/16-12 1447922 810.8 ns/op
|
BenchmarkStackDepth/16-12 975457 1184 ns/op
|
||||||
BenchmarkStackDepth/32-12 915291 1338 ns/op
|
BenchmarkStackDepth/32-12 572706 2101 ns/op
|
||||||
BenchmarkStackDepth/64-12 488719 2366 ns/op
|
BenchmarkStackDepth/64-12 333598 3596 ns/op
|
||||||
BenchmarkStackDepth/128-12 264735 4462 ns/op
|
BenchmarkStackDepth/128-12 182450 6561 ns/op
|
||||||
BenchmarkStackDepth/256-12 137575 8643 ns/op
|
BenchmarkStackDepth/256-12 94783 12548 ns/op
|
||||||
BenchmarkStackDepth/512-12 68355 17316 ns/op
|
BenchmarkStackDepth/512-12 48439 24471 ns/op
|
||||||
BenchmarkStackDepth/1024-12 34710 34810 ns/op
|
BenchmarkStackDepth/1024-12 24884 48310 ns/op
|
||||||
```
|
```
|
||||||
|
|
||||||
## Result 2: O(N) Function Size
|
Tests were done on my local machine:
|
||||||
|
|
||||||
Perhaps suprisingly, stack unwinding is also O(N) with regard to the size of the generated machine code for the function:
|
|
||||||
|
|
||||||
```
|
|
||||||
BenchmarkFunctionSize/1-12 2562176 462.8 ns/op
|
|
||||||
BenchmarkFunctionSize/2-12 2509465 484.7 ns/op
|
|
||||||
BenchmarkFunctionSize/4-12 2356609 504.6 ns/op
|
|
||||||
BenchmarkFunctionSize/8-12 2095870 568.3 ns/op
|
|
||||||
BenchmarkFunctionSize/16-12 1778889 669.7 ns/op
|
|
||||||
BenchmarkFunctionSize/32-12 1396009 856.0 ns/op
|
|
||||||
BenchmarkFunctionSize/64-12 943807 1269 ns/op
|
|
||||||
BenchmarkFunctionSize/128-12 516487 2271 ns/op
|
|
||||||
BenchmarkFunctionSize/256-12 277821 4490 ns/op
|
|
||||||
```
|
|
||||||
|
|
||||||
## Disclaimer
|
|
||||||
|
|
||||||
YMMV, and especially the function size also depends on the program counter at which the function is being unwound. All tests were done on my local machine:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
go test -bench .
|
go test -bench .
|
||||||
|
|
|
||||||
3079
examples/stack-unwind-overhead/generated.go
Normal file
3079
examples/stack-unwind-overhead/generated.go
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:generate go run .
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := run(); err != nil {
|
if err := run(); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
|
@ -14,5 +16,61 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
return nil
|
file, err := os.Create("generated.go")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
fmt.Fprint(file, `// Code generated by go generate; DO NOT EDIT.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:noinline
|
||||||
|
func stackdepth1(fn func()) { fn() }
|
||||||
|
`)
|
||||||
|
|
||||||
|
max := 1024
|
||||||
|
for i := 2; i <= max; i++ {
|
||||||
|
fmt.Fprintf(
|
||||||
|
file,
|
||||||
|
"//go:noinline\nfunc stackdepth%d(fn func()) { stackdepth%d(fn) }\n",
|
||||||
|
i,
|
||||||
|
i-1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(file, "\nvar stackdepth = map[int]func(func()) {\n")
|
||||||
|
for i := 1; i <= max; i++ {
|
||||||
|
fmt.Fprintf(file, "\t%d: stackdepth%d,\n", i, i)
|
||||||
|
}
|
||||||
|
fmt.Fprint(file, "}\n")
|
||||||
|
|
||||||
|
// Disabled: Turned out to be a deadend
|
||||||
|
//for i := 1; i <= max; i *= 2 {
|
||||||
|
//fmt.Fprintf(file, "//go:noinline\n")
|
||||||
|
//fmt.Fprintf(file, "func funcsize%d(v0, n int, fn func()) int {\n", i)
|
||||||
|
//for n := 1; n <= i; n++ {
|
||||||
|
//fmt.Fprintf(file, "\tv%d := v%d\n", n, n-1)
|
||||||
|
//fmt.Fprintf(file, "\tv%d = (^v%d + %d)\n", n, n, n)
|
||||||
|
//fmt.Fprintf(file, "\tif v%d == 23 {\n", n)
|
||||||
|
//sum := []string{}
|
||||||
|
//for j := 0; j <= n; j++ {
|
||||||
|
//sum = append(sum, fmt.Sprintf("v%d", j))
|
||||||
|
//}
|
||||||
|
//fmt.Fprintf(file, "\t\treturn %s\n", strings.Join(sum, " + "))
|
||||||
|
//fmt.Fprintf(file, "\t}\n")
|
||||||
|
//}
|
||||||
|
//fmt.Fprintf(file, "\tfn()\n")
|
||||||
|
//fmt.Fprintf(file, "\treturn -1\n")
|
||||||
|
//fmt.Fprintf(file, "}\n\n")
|
||||||
|
//}
|
||||||
|
|
||||||
|
//fmt.Fprint(file, "\nvar funcsize = map[int]func(int, int, func()) int {\n")
|
||||||
|
//for i := 1; i <= max; i *= 2 {
|
||||||
|
//fmt.Fprintf(file, "\t%d: funcsize%d,\n", i, i)
|
||||||
|
//}
|
||||||
|
//fmt.Fprint(file, "}\n")
|
||||||
|
|
||||||
|
return file.Close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import (
|
||||||
func BenchmarkStackDepth(b *testing.B) {
|
func BenchmarkStackDepth(b *testing.B) {
|
||||||
for d := 8; d <= 1024; d = d * 2 {
|
for d := 8; d <= 1024; d = d * 2 {
|
||||||
b.Run(fmt.Sprintf("%d", d), func(b *testing.B) {
|
b.Run(fmt.Sprintf("%d", d), func(b *testing.B) {
|
||||||
callers := make([]uintptr, d)
|
callers := make([]uintptr, d*2)
|
||||||
atStackDepth(d, func() {
|
atStackDepth(d, func() {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if n := runtime.Callers(0, callers); n != d {
|
if n := runtime.Callers(1, callers); n != d {
|
||||||
b.Fatalf("got=%d want=%d", n, d)
|
b.Fatalf("got=%d want=%d", n, d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,598 +23,38 @@ func BenchmarkStackDepth(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// atStackDepth recursively calls itself until the number of stack frames
|
// atStackDepth calls functions that call each other until there are depth-1
|
||||||
// reaches the desired depth, and then calls fn.
|
// functions on the stack and then calls fn.
|
||||||
|
//go:noinline
|
||||||
func atStackDepth(depth int, fn func()) {
|
func atStackDepth(depth int, fn func()) {
|
||||||
pcs := make([]uintptr, depth+10)
|
pcs := make([]uintptr, depth+10)
|
||||||
n := runtime.Callers(1, pcs)
|
remaining := depth - runtime.Callers(1, pcs) - 1
|
||||||
if n > depth {
|
if remaining < 1 {
|
||||||
panic("depth exceeded")
|
panic("can't simulate desired stack depth: too low")
|
||||||
} else if n < depth {
|
} else if remaining == 1 {
|
||||||
atStackDepth(depth, fn)
|
fn()
|
||||||
return
|
} else if f, ok := stackdepth[remaining]; !ok {
|
||||||
}
|
panic("can't simulate desired stack depth: no map entry")
|
||||||
|
} else {
|
||||||
fn()
|
f(fn)
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkFunctionSize(b *testing.B) {
|
|
||||||
m := map[int]func(func()){
|
|
||||||
1: dostuff1,
|
|
||||||
2: dostuff2,
|
|
||||||
4: dostuff4,
|
|
||||||
8: dostuff8,
|
|
||||||
16: dostuff16,
|
|
||||||
32: dostuff32,
|
|
||||||
64: dostuff64,
|
|
||||||
128: dostuff128,
|
|
||||||
256: dostuff256,
|
|
||||||
}
|
|
||||||
|
|
||||||
var callers = make([]uintptr, 32)
|
|
||||||
for s := 1; s <= 256; s = s * 2 {
|
|
||||||
b.Run(fmt.Sprintf("%d", s), func(b *testing.B) {
|
|
||||||
m[s](func() {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
runtime.Callers(0, callers)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dostuff is supposed to generate a bunch of machine code that will hopefully
|
// disabled: turned out to be a deadend
|
||||||
// be inlined into its callers.
|
//func BenchmarkFunctionSize(b *testing.B) {
|
||||||
func dostuff() int {
|
//var callers = make([]uintptr, 32)
|
||||||
m := map[int]string{}
|
//for s := 1; s <= 1024; s = s * 2 {
|
||||||
m[0] = "foo"
|
//b.Run(fmt.Sprintf("%d", s), func(b *testing.B) {
|
||||||
m[100] = "bar"
|
//called := false
|
||||||
return len(m)
|
//funcsize[s](0, 0, func() {
|
||||||
}
|
//for i := 0; i < b.N; i++ {
|
||||||
|
//runtime.Callers(0, callers)
|
||||||
func dostuff1(fn func()) {
|
//}
|
||||||
dostuff()
|
//called = true
|
||||||
fn()
|
//})
|
||||||
}
|
//if !called {
|
||||||
|
//b.Fatal("not called")
|
||||||
func dostuff2(fn func()) {
|
//}
|
||||||
dostuff()
|
//})
|
||||||
dostuff()
|
//}
|
||||||
fn()
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff4(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff8(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff16(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff32(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff64(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff128(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
||||||
func dostuff256(fn func()) {
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
dostuff()
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue