1/* 2 * Copyright (c) 2024 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 16#ifndef ECMASCRIPT_COMPILER_BASELINE_BASELINE_COMPILER_H 17#define ECMASCRIPT_COMPILER_BASELINE_BASELINE_COMPILER_H 18 19#include <unordered_map> 20#include "ecmascript/ecma_vm.h" 21#include "ecmascript/mem/machine_code.h" 22#include "ecmascript/compiler/baseline/baseline_assembler.h" 23#include "ecmascript/compiler/ecma_opcode_des.h" 24#include "ecmascript/compiler/jit_compilation_env.h" 25 26namespace panda::ecmascript::kungfu { 27 28class BytecodeNativePcOffsetTable { 29public: 30 BytecodeNativePcOffsetTable() = default; 31 ~BytecodeNativePcOffsetTable() = default; 32 33 void AddPosition(uint64_t nativePc) 34 { 35 ASSERT(nativePc - prevNativePc < 256); // 256: the max number can be presented by uint8_t 36 auto nativePcDiff = static_cast<uint8_t>(nativePc - prevNativePc); 37 nativePcDiffInfo.emplace_back(static_cast<uint8_t>(nativePcDiff)); 38 prevNativePc = nativePc; 39 } 40 41 uint8_t *GetData() 42 { 43 return nativePcDiffInfo.data(); 44 } 45 46 size_t GetSize() const 47 { 48 return nativePcDiffInfo.size(); 49 } 50 51 uint64_t GetPrevNativePc() const 52 { 53 return prevNativePc; 54 } 55 56private: 57 uint64_t prevNativePc = 0; 58 std::vector<uint8_t> nativePcDiffInfo; 59}; 60 61class BaselineCompiler { 62public: 63 explicit BaselineCompiler(EcmaVM *inputVM, CompilationEnv *inputEnv) 64 : vm(inputVM), compilationEnv(inputEnv), baselineAssembler(vm->GetJSOptions().GetTargetTriple()) {} 65 66 ~BaselineCompiler() 67 { 68 for (auto elem : jumpMap) { 69 if (elem.second != nullptr) { 70 delete elem.second; 71 elem.second = nullptr; 72 } 73 } 74 jumpMap.clear(); 75 } 76 77 void Compile(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral); 78 79 BaselineAssembler &GetBaselineAssembler() 80 { 81 return baselineAssembler; 82 } 83 84 bool CollectMemoryCodeInfos(MachineCodeDesc &codeDesc); 85 86 void SetPfHeaderAddr(const JSPandaFile *jsPandaFile); 87 88 void GetJumpToOffsets(const uint8_t *start, const uint8_t *end, std::unordered_set<size_t> &jumpToOffsets) const; 89private: 90 EcmaVM *vm = nullptr; 91 CompilationEnv *compilationEnv = nullptr; 92 BaselineAssembler baselineAssembler; 93 size_t bytecodeOffset = 0; 94 std::unordered_map<size_t, JumpLabel*> jumpMap; 95 96#define BYTECODE_BASELINE_HANDLER(name) void Handle##name(const uint8_t *bytecodeArray); 97 ECMA_OPCODE_LIST(BYTECODE_BASELINE_HANDLER) 98#undef BYTECODE_BASELINE_HANDLER 99 const uint8_t *pfHeaderAddr = nullptr; 100 const uint8_t *firstPC = nullptr; 101 static constexpr uint32_t ONE_BYTE_SIZE = 8; 102 static constexpr uint32_t TWO_BYTE_SIZE = 16; 103 static constexpr uint32_t THREE_BYTE_SIZE = 24; 104 BytecodeNativePcOffsetTable nativePcOffsetTable; 105}; 106} // namespace panda::ecmascript::kungfu 107#endif // ECMASCRIPT_COMPILER_BASELINE_BASELINE_COMPILER_H 108