github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/loader/pcdata.go (about) 1 /** 2 * Copyright 2023 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package loader 18 19 import ( 20 "encoding/binary" 21 ) 22 23 const ( 24 _N_PCDATA = 4 25 26 _PCDATA_UnsafePoint = 0 27 _PCDATA_StackMapIndex = 1 28 _PCDATA_InlTreeIndex = 2 29 _PCDATA_ArgLiveIndex = 3 30 31 _PCDATA_INVALID_OFFSET = 0 32 ) 33 34 const ( 35 // PCDATA_UnsafePoint values. 36 PCDATA_UnsafePointSafe = -1 // Safe for async preemption 37 PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption 38 39 // PCDATA_Restart1(2) apply on a sequence of instructions, within 40 // which if an async preemption happens, we should back off the PC 41 // to the start of the sequence when resume. 42 // We need two so we can distinguish the start/end of the sequence 43 // in case that two sequences are next to each other. 44 PCDATA_Restart1 = -3 45 PCDATA_Restart2 = -4 46 47 // Like PCDATA_RestartAtEntry, but back to function entry if async 48 // preempted. 49 PCDATA_RestartAtEntry = -5 50 51 _PCDATA_START_VAL = -1 52 ) 53 54 var emptyByte byte 55 56 // Pcvalue is the program count corresponding to the value Val 57 // 58 // WARN: we use relative value here (to function entry) 59 type Pcvalue struct { 60 PC uint32 // program count relative to function entry 61 Val int32 // value relative to the value in function entry 62 } 63 64 // Pcdata represents pc->value mapping table. 65 // 66 // WARN: we use ** [Pcdata[i].PC, Pcdata[i+1].PC) ** 67 // as the range where the Pcdata[i].Val is effective. 68 type Pcdata []Pcvalue 69 70 // see https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub 71 func (self Pcdata) MarshalBinary() (data []byte, err error) { 72 // delta value always starts from -1 73 sv := int32(_PCDATA_START_VAL) 74 sp := uint32(0) 75 buf := make([]byte, binary.MaxVarintLen32) 76 for _, v := range self { 77 if v.PC < sp { 78 panic("PC must be in ascending order!") 79 } 80 dp := uint64(v.PC - sp) 81 dv := int64(v.Val - sv) 82 if dv == 0 || dp == 0 { 83 continue 84 } 85 n := binary.PutVarint(buf, dv) 86 data = append(data, buf[:n]...) 87 n2 := binary.PutUvarint(buf, dp) 88 data = append(data, buf[:n2]...) 89 sp = v.PC 90 sv = v.Val 91 } 92 // put 0 to indicate ends 93 data = append(data, 0) 94 return 95 }