pcdata.go (2560B)
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 const ( 20 _N_PCDATA = 4 21 22 _PCDATA_UnsafePoint = 0 23 _PCDATA_StackMapIndex = 1 24 _PCDATA_InlTreeIndex = 2 25 _PCDATA_ArgLiveIndex = 3 26 27 _PCDATA_INVALID_OFFSET = 0 28 ) 29 30 const ( 31 // PCDATA_UnsafePoint values. 32 PCDATA_UnsafePointSafe = -1 // Safe for async preemption 33 PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption 34 35 // PCDATA_Restart1(2) apply on a sequence of instructions, within 36 // which if an async preemption happens, we should back off the PC 37 // to the start of the sequence when resume. 38 // We need two so we can distinguish the start/end of the sequence 39 // in case that two sequences are next to each other. 40 PCDATA_Restart1 = -3 41 PCDATA_Restart2 = -4 42 43 // Like PCDATA_RestartAtEntry, but back to function entry if async 44 // preempted. 45 PCDATA_RestartAtEntry = -5 46 47 _PCDATA_START_VAL = -1 48 ) 49 50 var emptyByte byte 51 52 func encodeValue(v int) []byte { 53 return encodeVariant(toZigzag(v)) 54 } 55 56 func toZigzag(v int) int { 57 return (v << 1) ^ (v >> 31) 58 } 59 60 func encodeVariant(v int) []byte { 61 var u int 62 var r []byte 63 64 /* split every 7 bits */ 65 for v > 127 { 66 u = v & 0x7f 67 v = v >> 7 68 r = append(r, byte(u) | 0x80) 69 } 70 71 /* check for last one */ 72 if v == 0 { 73 return r 74 } 75 76 /* add the last one */ 77 r = append(r, byte(v)) 78 return r 79 } 80 81 type Pcvalue struct { 82 PC uint32 // PC offset from func entry 83 Val int32 84 } 85 86 type Pcdata []Pcvalue 87 88 // see https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub 89 func (self Pcdata) MarshalBinary() (data []byte, err error) { 90 // delta value always starts from -1 91 sv := int32(_PCDATA_START_VAL) 92 sp := uint32(0) 93 for _, v := range self { 94 data = append(data, encodeVariant(toZigzag(int(v.Val - sv)))...) 95 data = append(data, encodeVariant(int(v.PC - sp))...) 96 sp = v.PC 97 sv = v.Val 98 } 99 return 100 }