github.com/cloudwego/frugal@v0.1.7/internal/loader/funcdata_go116_117.go (about) 1 // +build go1.16,!go1.18 2 3 /* 4 * Copyright 2022 ByteDance Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package loader 20 21 import ( 22 `unsafe` 23 24 `github.com/cloudwego/frugal/internal/rt` 25 ) 26 27 type _Func struct { 28 entry uintptr 29 nameoff int32 30 args int32 31 deferreturn uint32 32 pcsp uint32 33 pcfile uint32 34 pcln uint32 35 npcdata uint32 36 cuOffset uint32 37 funcID uint8 38 _ [2]byte 39 nfuncdata uint8 40 pcdata [2]uint32 41 argptrs uintptr 42 localptrs uintptr 43 } 44 45 type _FuncTab struct { 46 entry uintptr 47 funcoff uintptr 48 } 49 50 type _PCHeader struct { 51 magic uint32 52 pad1, pad2 uint8 53 minLC uint8 54 ptrSize uint8 55 nfunc int 56 nfiles uint 57 funcnameOffset uintptr 58 cuOffset uintptr 59 filetabOffset uintptr 60 pctabOffset uintptr 61 pclnOffset uintptr 62 } 63 64 type _BitVector struct { 65 n int32 66 bytedata *uint8 67 } 68 69 type _ModuleData struct { 70 pcHeader *_PCHeader 71 funcnametab []byte 72 cutab []uint32 73 filetab []byte 74 pctab []byte 75 pclntable []_Func 76 ftab []_FuncTab 77 findfunctab *_FindFuncBucket 78 minpc, maxpc uintptr 79 text, etext uintptr 80 noptrdata, enoptrdata uintptr 81 data, edata uintptr 82 bss, ebss uintptr 83 noptrbss, enoptrbss uintptr 84 end, gcdata, gcbss uintptr 85 types, etypes uintptr 86 textsectmap [][3]uintptr 87 typelinks []int32 88 itablinks []unsafe.Pointer 89 ptab [][2]int32 90 pluginpath string 91 pkghashes []struct{} 92 modulename string 93 modulehashes []struct{} 94 hasmain uint8 95 gcdatamask, gcbssmask _BitVector 96 typemap map[int32]unsafe.Pointer 97 bad bool 98 next *_ModuleData 99 } 100 101 type _FindFuncBucket struct { 102 idx uint32 103 subbuckets [16]byte 104 } 105 106 const minfunc = 16 // minimum function size 107 const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table 108 109 var modHeader = &_PCHeader { 110 magic : 0xfffffffa, 111 minLC : 1, 112 nfunc : 1, 113 ptrSize : 4 << (^uintptr(0) >> 63), 114 } 115 116 var ( 117 emptyByte byte 118 bucketList []*_FindFuncBucket 119 ) 120 121 func registerFunction(name string, pc uintptr, size uintptr, frame rt.Frame) { 122 var pbase uintptr 123 var sbase uintptr 124 125 /* PC ranges */ 126 minpc := pc 127 maxpc := pc + size 128 pctab := make([]byte, 1) 129 ffunc := make([]_FindFuncBucket, size / pcbucketsize + 1) 130 131 /* initialize the find function buckets */ 132 for i := range ffunc { 133 ffunc[i].idx = 1 134 } 135 136 /* define the PC-SP ranges */ 137 for i, r := range frame.SpTab { 138 nb := r.Nb 139 ds := int(r.Sp - sbase) 140 141 /* check for remaining size */ 142 if nb == 0 { 143 if i == len(frame.SpTab) - 1 { 144 nb = size - pbase 145 } else { 146 panic("invalid PC-SP tab") 147 } 148 } 149 150 /* check for the first entry */ 151 if i == 0 { 152 pctab = append(pctab, encodeFirst(ds)...) 153 } else { 154 pctab = append(pctab, encodeValue(ds)...) 155 } 156 157 /* encode the length */ 158 sbase = r.Sp 159 pbase = pbase + nb 160 pctab = append(pctab, encodeVariant(int(nb))...) 161 } 162 163 /* pin the find function bucket */ 164 ftab := &ffunc[0] 165 pctab = append(pctab, 0) 166 bucketList = append(bucketList, ftab) 167 168 /* function entry */ 169 fn := _Func { 170 entry : pc, 171 nameoff : 1, 172 args : int32(frame.ArgSize), 173 pcsp : 1, 174 npcdata : 2, 175 nfuncdata : 2, 176 cuOffset : 1, 177 argptrs : frame.ArgPtrs.Pin(), 178 localptrs : frame.LocalPtrs.Pin(), 179 } 180 181 /* mark the entire function as a single line of code */ 182 fn.pcln = uint32(len(pctab)) 183 fn.pcfile = uint32(len(pctab)) 184 pctab = append(pctab, encodeFirst(1)...) 185 pctab = append(pctab, encodeVariant(int(size))...) 186 pctab = append(pctab, 0) 187 188 /* set the entire function to use stack map 0 */ 189 fn.pcdata[_PCDATA_StackMapIndex] = uint32(len(pctab)) 190 pctab = append(pctab, encodeFirst(0)...) 191 pctab = append(pctab, encodeVariant(int(size))...) 192 pctab = append(pctab, 0) 193 194 /* mark the entire function as unsafe to async-preempt */ 195 fn.pcdata[_PCDATA_UnsafePoint] = uint32(len(pctab)) 196 pctab = append(pctab, encodeFirst(_PCDATA_UnsafePointUnsafe)...) 197 pctab = append(pctab, encodeVariant(int(size))...) 198 pctab = append(pctab, 0) 199 200 /* function table */ 201 tab := []_FuncTab { 202 {entry: pc}, 203 {entry: pc}, 204 {entry: maxpc}, 205 } 206 207 /* module data */ 208 mod := &_ModuleData { 209 pcHeader : modHeader, 210 funcnametab : append(append([]byte{0}, name...), 0), 211 cutab : []uint32{0, 0, 1}, 212 filetab : []byte("\x00(jit-generated)\x00"), 213 pctab : pctab, 214 pclntable : []_Func{fn}, 215 ftab : tab, 216 findfunctab : ftab, 217 minpc : minpc, 218 maxpc : maxpc, 219 modulename : name, 220 gcdata : uintptr(unsafe.Pointer(&emptyByte)), 221 gcbss : uintptr(unsafe.Pointer(&emptyByte)), 222 } 223 224 /* verify and register the new module */ 225 moduledataverify1(mod) 226 registerModule(mod) 227 }