123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- 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))
- }
|