summaryrefslogtreecommitdiff
path: root/vendor/github.com/jtolds/gls/stack_tags.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jtolds/gls/stack_tags.go')
-rw-r--r--vendor/github.com/jtolds/gls/stack_tags.go147
1 files changed, 147 insertions, 0 deletions
diff --git a/vendor/github.com/jtolds/gls/stack_tags.go b/vendor/github.com/jtolds/gls/stack_tags.go
new file mode 100644
index 0000000..37bbd33
--- /dev/null
+++ b/vendor/github.com/jtolds/gls/stack_tags.go
@@ -0,0 +1,147 @@
+package gls
+
+// so, basically, we're going to encode integer tags in base-16 on the stack
+
+const (
+ bitWidth = 4
+ stackBatchSize = 16
+)
+
+var (
+ pc_lookup = make(map[uintptr]int8, 17)
+ mark_lookup [16]func(uint, func())
+)
+
+func init() {
+ setEntries := func(f func(uint, func()), v int8) {
+ var ptr uintptr
+ f(0, func() {
+ ptr = findPtr()
+ })
+ pc_lookup[ptr] = v
+ if v >= 0 {
+ mark_lookup[v] = f
+ }
+ }
+ setEntries(github_com_jtolds_gls_markS, -0x1)
+ setEntries(github_com_jtolds_gls_mark0, 0x0)
+ setEntries(github_com_jtolds_gls_mark1, 0x1)
+ setEntries(github_com_jtolds_gls_mark2, 0x2)
+ setEntries(github_com_jtolds_gls_mark3, 0x3)
+ setEntries(github_com_jtolds_gls_mark4, 0x4)
+ setEntries(github_com_jtolds_gls_mark5, 0x5)
+ setEntries(github_com_jtolds_gls_mark6, 0x6)
+ setEntries(github_com_jtolds_gls_mark7, 0x7)
+ setEntries(github_com_jtolds_gls_mark8, 0x8)
+ setEntries(github_com_jtolds_gls_mark9, 0x9)
+ setEntries(github_com_jtolds_gls_markA, 0xa)
+ setEntries(github_com_jtolds_gls_markB, 0xb)
+ setEntries(github_com_jtolds_gls_markC, 0xc)
+ setEntries(github_com_jtolds_gls_markD, 0xd)
+ setEntries(github_com_jtolds_gls_markE, 0xe)
+ setEntries(github_com_jtolds_gls_markF, 0xf)
+}
+
+func addStackTag(tag uint, context_call func()) {
+ if context_call == nil {
+ return
+ }
+ github_com_jtolds_gls_markS(tag, context_call)
+}
+
+// these private methods are named this horrendous name so gopherjs support
+// is easier. it shouldn't add any runtime cost in non-js builds.
+
+//go:noinline
+func github_com_jtolds_gls_markS(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark0(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark1(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark2(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark3(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark4(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark5(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark6(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark7(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark8(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_mark9(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markA(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markB(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markC(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markD(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markE(tag uint, cb func()) { _m(tag, cb) }
+
+//go:noinline
+func github_com_jtolds_gls_markF(tag uint, cb func()) { _m(tag, cb) }
+
+func _m(tag_remainder uint, cb func()) {
+ if tag_remainder == 0 {
+ cb()
+ } else {
+ mark_lookup[tag_remainder&0xf](tag_remainder>>bitWidth, cb)
+ }
+}
+
+func readStackTag() (tag uint, ok bool) {
+ var current_tag uint
+ offset := 0
+ for {
+ batch, next_offset := getStack(offset, stackBatchSize)
+ for _, pc := range batch {
+ val, ok := pc_lookup[pc]
+ if !ok {
+ continue
+ }
+ if val < 0 {
+ return current_tag, true
+ }
+ current_tag <<= bitWidth
+ current_tag += uint(val)
+ }
+ if next_offset == 0 {
+ break
+ }
+ offset = next_offset
+ }
+ return 0, false
+}
+
+func (m *ContextManager) preventInlining() {
+ // dunno if findPtr or getStack are likely to get inlined in a future release
+ // of go, but if they are inlined and their callers are inlined, that could
+ // hork some things. let's do our best to explain to the compiler that we
+ // really don't want those two functions inlined by saying they could change
+ // at any time. assumes preventInlining doesn't get compiled out.
+ // this whole thing is probably overkill.
+ findPtr = m.values[0][0].(func() uintptr)
+ getStack = m.values[0][1].(func(int, int) ([]uintptr, int))
+}