• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ecmascript/stackmap/litecg/litecg_stackmap_type.h"
16 
17 namespace panda::ecmascript::kungfu {
DecodeSLEB128(const std::vector<uint8_t> & bytes,size_t & index)18 static int64_t DecodeSLEB128(const std::vector<uint8_t> &bytes, size_t &index)
19 {
20     uint64_t res = 0;
21     uint64_t shift = 0;
22     constexpr uint8_t FLAG_MASK = 0x40;
23     constexpr uint8_t LOW_7_BITS_MASK = 0x7f;
24     constexpr uint8_t NEXT_BYTE_FLAG_MASK = 0x80;
25     constexpr uint8_t DATA_BITS_SHIFT = 7;
26     constexpr uint64_t BIT_SIZE_64 = 64;
27     bool needDecodeNextByte = false;
28     uint8_t byte = 0;
29     do {
30         byte = bytes[index];
31         needDecodeNextByte = ((byte & NEXT_BYTE_FLAG_MASK) != 0);
32         uint8_t low7Bit = (byte & LOW_7_BITS_MASK);
33         res |= (static_cast<uint64_t>(low7Bit) << shift);
34         shift += DATA_BITS_SHIFT;
35         index++;
36     } while (needDecodeNextByte);
37 
38     if (shift < BIT_SIZE_64 && (byte & FLAG_MASK) != 0) {
39         res |= UINT64_MAX << shift;
40     }
41     return static_cast<int64_t>(res);
42 }
43 
ConvertToLLVMStackMapInfo(std::vector<LLVMStackMapType::Pc2CallSiteInfo> & pc2StackMapsVec,std::vector<LLVMStackMapType::Pc2Deopt> & pc2DeoptInfoVec,Triple triple) const44 void LiteCGStackMapInfo::ConvertToLLVMStackMapInfo(
45     std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2StackMapsVec,
46     std::vector<LLVMStackMapType::Pc2Deopt> &pc2DeoptInfoVec, Triple triple) const
47 {
48     auto fpReg = GCStackMapRegisters::GetFpRegByTriple(triple);
49     for (const auto &callSiteInfo : pc2CallSiteInfoVec_) {
50         LLVMStackMapType::Pc2CallSiteInfo pc2CallSiteInfo;
51         for (const auto &elem : callSiteInfo) {
52             const std::vector<uint8_t> &litecgCallSiteInfo = elem.second;
53             LLVMStackMapType::CallSiteInfo llvmCallSiteInfo;
54             // parse std::vector<uint8_t>
55             size_t index = 0;
56             while (index < litecgCallSiteInfo.size()) {
57                 int64_t kind = DecodeSLEB128(litecgCallSiteInfo, index);
58                 int64_t value = DecodeSLEB128(litecgCallSiteInfo, index);
59                 if (kind == 2) {  // kind is 2 means register
60                     llvmCallSiteInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));
61                 } else if (kind == 1) { // stack
62                     llvmCallSiteInfo.push_back(std::pair<uint16_t, uint32_t>(fpReg, static_cast<int32_t>(value)));
63                 } else {
64                     LOG_ECMA(FATAL) << "only stack and reigster is supported currently";
65                     UNREACHABLE();
66                 }
67             }
68             uintptr_t pc = static_cast<uintptr_t>(elem.first);
69             pc2CallSiteInfo[pc] = llvmCallSiteInfo;
70         }
71         pc2StackMapsVec.push_back(pc2CallSiteInfo);
72     }
73     for (const auto &deoptInfo : pc2DeoptVec_) {
74         LLVMStackMapType::Pc2Deopt pc2DeoptInfo;
75         for (const auto &elem : deoptInfo) {
76             const std::vector<uint8_t> &litecgDeoptInfo = elem.second;
77             LLVMStackMapType::DeoptInfoType llvmDeoptInfo;
78             // parse std::vector<uint8_t>
79             size_t index = 0;
80             while (index < litecgDeoptInfo.size()) {
81                 int64_t deoptVreg = DecodeSLEB128(litecgDeoptInfo, index);
82                 int64_t kind = DecodeSLEB128(litecgDeoptInfo, index);
83                 int64_t value = DecodeSLEB128(litecgDeoptInfo, index);
84                 llvmDeoptInfo.push_back(static_cast<int32_t>(deoptVreg));
85                 if (kind == 2) { // kind is 2 means register
86                     llvmDeoptInfo.push_back(std::pair<uint16_t, uint32_t>(0xFFFFU, static_cast<int32_t>(value)));
87                 } else if (kind == 1) { // stack
88                     llvmDeoptInfo.push_back(std::pair<uint16_t, uint32_t>(fpReg, static_cast<int32_t>(value)));
89                 } else { // imm
90                     llvmDeoptInfo.push_back(static_cast<int32_t>(value));
91                 }
92             }
93             pc2DeoptInfo[elem.first] = llvmDeoptInfo;
94         }
95 
96         pc2DeoptInfoVec.push_back(pc2DeoptInfo);
97     }
98 }
99 }  // namespace panda::ecmascript::kungfu