github.com/cloudwego/frugal@v0.1.7/internal/loader/funcdata_go118_120.go (about) 1 // +build go1.18,!go1.21 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 _FuncTab struct { 28 entry uint32 29 funcoff uint32 30 } 31 32 type _PCHeader struct { 33 magic uint32 34 pad1, pad2 uint8 35 minLC uint8 36 ptrSize uint8 37 nfunc int 38 nfiles uint 39 textStart uintptr 40 funcnameOffset uintptr 41 cuOffset uintptr 42 filetabOffset uintptr 43 pctabOffset uintptr 44 pclnOffset uintptr 45 } 46 47 type _BitVector struct { 48 n int32 // # of bits 49 bytedata *uint8 50 } 51 52 type _FindFuncBucket struct { 53 idx uint32 54 subbuckets [16]byte 55 } 56 57 const minfunc = 16 58 const pcbucketsize = 256 * minfunc 59 60 var ( 61 emptyByte byte 62 bucketList []*_FindFuncBucket 63 ) 64 65 func registerFunction(name string, pc uintptr, size uintptr, frame rt.Frame) { 66 var pbase uintptr 67 var sbase uintptr 68 69 /* PC ranges */ 70 minpc := pc 71 maxpc := pc + size 72 pctab := make([]byte, 1) 73 ffunc := make([]_FindFuncBucket, size / pcbucketsize + 1) 74 75 /* define the PC-SP ranges */ 76 for i, r := range frame.SpTab { 77 nb := r.Nb 78 ds := int(r.Sp - sbase) 79 80 /* check for remaining size */ 81 if nb == 0 { 82 if i == len(frame.SpTab) - 1 { 83 nb = size - pbase 84 } else { 85 panic("invalid PC-SP tab") 86 } 87 } 88 89 /* check for the first entry */ 90 if i == 0 { 91 pctab = append(pctab, encodeFirst(ds)...) 92 } else { 93 pctab = append(pctab, encodeValue(ds)...) 94 } 95 96 /* encode the length */ 97 sbase = r.Sp 98 pbase = pbase + nb 99 pctab = append(pctab, encodeVariant(int(nb))...) 100 } 101 102 /* pin the find function bucket */ 103 ftab := &ffunc[0] 104 pctab = append(pctab, 0) 105 bucketList = append(bucketList, ftab) 106 107 /* pin the pointer maps */ 108 argptrs := frame.ArgPtrs.Pin() 109 localptrs := frame.LocalPtrs.Pin() 110 111 /* find the lower base */ 112 if argptrs < localptrs { 113 pbase = argptrs 114 } else { 115 pbase = localptrs 116 } 117 118 /* function entry */ 119 fn := _Func { 120 entryOff : 0, 121 nameoff : 1, 122 args : int32(frame.ArgSize), 123 pcsp : 1, 124 npcdata : 2, 125 cuOffset : 1, 126 nfuncdata : 2, 127 argptrs : uint32(argptrs - pbase), 128 localptrs : uint32(localptrs - pbase), 129 } 130 131 /* mark the entire function as a single line of code */ 132 fn.pcln = uint32(len(pctab)) 133 fn.pcfile = uint32(len(pctab)) 134 pctab = append(pctab, encodeFirst(1)...) 135 pctab = append(pctab, encodeVariant(int(size))...) 136 pctab = append(pctab, 0) 137 138 /* set the entire function to use stack map 0 */ 139 fn.pcdata[_PCDATA_StackMapIndex] = uint32(len(pctab)) 140 pctab = append(pctab, encodeFirst(0)...) 141 pctab = append(pctab, encodeVariant(int(size))...) 142 pctab = append(pctab, 0) 143 144 /* mark the entire function as unsafe to async-preempt */ 145 fn.pcdata[_PCDATA_UnsafePoint] = uint32(len(pctab)) 146 pctab = append(pctab, encodeFirst(_PCDATA_UnsafePointUnsafe)...) 147 pctab = append(pctab, encodeVariant(int(size))...) 148 pctab = append(pctab, 0) 149 150 /* module header */ 151 hdr := &_PCHeader { 152 magic : _ModuleMagic, 153 minLC : 1, 154 nfunc : 1, 155 ptrSize : 4 << (^uintptr(0) >> 63), 156 textStart : minpc, 157 } 158 159 /* function table */ 160 tab := []_FuncTab { 161 { entry: 0 }, 162 { entry: uint32(size) }, 163 } 164 165 /* module data */ 166 mod := &_ModuleData { 167 pcHeader : hdr, 168 funcnametab : append(append([]byte{0}, name...), 0), 169 cutab : []uint32{0, 0, 1}, 170 filetab : []byte("\x00(jit-generated)\x00"), 171 pctab : pctab, 172 pclntable : ((*[unsafe.Sizeof(_Func{})]byte)(unsafe.Pointer(&fn)))[:], 173 ftab : tab, 174 findfunctab : uintptr(unsafe.Pointer(ftab)), 175 minpc : minpc, 176 maxpc : maxpc, 177 text : minpc, 178 etext : maxpc, 179 modulename : name, 180 gcdata : uintptr(unsafe.Pointer(&emptyByte)), 181 gcbss : uintptr(unsafe.Pointer(&emptyByte)), 182 gofunc : pbase, 183 } 184 185 /* verify and register the new module */ 186 moduledataverify1(mod) 187 registerModule(mod) 188 }