runtime: aggregate defer allocations
benchmark old ns/op new ns/op delta
BenchmarkDefer 165 113 -31.52%
BenchmarkDefer10 155 103 -33.55%
BenchmarkDeferMany 216 158 -26.85%
benchmark old allocs new allocs delta
BenchmarkDefer 1 0 -100.00%
BenchmarkDefer10 1 0 -100.00%
BenchmarkDeferMany 1 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkDefer 64 0 -100.00%
BenchmarkDefer10 64 0 -100.00%
BenchmarkDeferMany 64 66 3.12%
Fixes #2364.
R=ken2
CC=golang-dev
https://golang.org/cl/7001051
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 6c9d50e..0c941f8 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -68,6 +68,7 @@
typedef struct ChanType ChanType;
typedef struct MapType MapType;
typedef struct Defer Defer;
+typedef struct DeferChunk DeferChunk;
typedef struct Panic Panic;
typedef struct Hmap Hmap;
typedef struct Hchan Hchan;
@@ -218,6 +219,8 @@
int32 sig;
int32 writenbuf;
byte* writebuf;
+ DeferChunk *dchunk;
+ DeferChunk *dchunknext;
uintptr sigcode0;
uintptr sigcode1;
uintptr sigpc;
@@ -518,7 +521,8 @@
struct Defer
{
int32 siz;
- bool nofree;
+ bool special; // not part of defer frame
+ bool free; // if special, free when done
byte* argp; // where args were copied from
byte* pc;
byte* fn;
@@ -526,6 +530,12 @@
void* args[1]; // padded to actual size
};
+struct DeferChunk
+{
+ DeferChunk *prev;
+ uintptr off;
+};
+
/*
* panics
*/