pcdata.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. package loader
  17. import (
  18. `encoding/binary`
  19. )
  20. const (
  21. _N_PCDATA = 4
  22. _PCDATA_UnsafePoint = 0
  23. _PCDATA_StackMapIndex = 1
  24. _PCDATA_InlTreeIndex = 2
  25. _PCDATA_ArgLiveIndex = 3
  26. _PCDATA_INVALID_OFFSET = 0
  27. )
  28. const (
  29. // PCDATA_UnsafePoint values.
  30. PCDATA_UnsafePointSafe = -1 // Safe for async preemption
  31. PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
  32. // PCDATA_Restart1(2) apply on a sequence of instructions, within
  33. // which if an async preemption happens, we should back off the PC
  34. // to the start of the sequence when resume.
  35. // We need two so we can distinguish the start/end of the sequence
  36. // in case that two sequences are next to each other.
  37. PCDATA_Restart1 = -3
  38. PCDATA_Restart2 = -4
  39. // Like PCDATA_RestartAtEntry, but back to function entry if async
  40. // preempted.
  41. PCDATA_RestartAtEntry = -5
  42. _PCDATA_START_VAL = -1
  43. )
  44. var emptyByte byte
  45. // Pcvalue is the program count corresponding to the value Val
  46. // WARN: we use relative value here (to function entry)
  47. type Pcvalue struct {
  48. PC uint32 // program count relative to function entry
  49. Val int32 // value relative to the value in function entry
  50. }
  51. // Pcdata represents pc->value mapping table.
  52. // WARN: we use ** [Pcdata[i].PC, Pcdata[i+1].PC) **
  53. // as the range where the Pcdata[i].Val is effective.
  54. type Pcdata []Pcvalue
  55. // see https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub
  56. func (self Pcdata) MarshalBinary() (data []byte, err error) {
  57. // delta value always starts from -1
  58. sv := int32(_PCDATA_START_VAL)
  59. sp := uint32(0)
  60. buf := make([]byte, binary.MaxVarintLen32)
  61. for _, v := range self {
  62. if v.PC < sp {
  63. panic("PC must be in ascending order!")
  64. }
  65. dp := uint64(v.PC - sp)
  66. dv := int64(v.Val - sv)
  67. if dv == 0 || dp == 0 {
  68. continue
  69. }
  70. n := binary.PutVarint(buf, dv)
  71. data = append(data, buf[:n]...)
  72. n2 := binary.PutUvarint(buf, dp)
  73. data = append(data, buf[:n2]...)
  74. sp = v.PC
  75. sv = v.Val
  76. }
  77. // put 0 to indicate ends
  78. data = append(data, 0)
  79. return
  80. }