1/* 2 * Copyright (c) 2022 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_GATE_META_DATA_CACHE_H 17#define ECMASCRIPT_COMPILER_GATE_META_DATA_CACHE_H 18 19#include <string> 20 21#include "ecmascript/compiler/bytecodes.h" 22#include "ecmascript/compiler/share_opcodes.h" 23#include "ecmascript/compiler/share_gate_meta_data.h" 24#include "ecmascript/compiler/lcr_gate_meta_data.h" 25#include "ecmascript/compiler/mcr_gate_meta_data.h" 26#include "ecmascript/compiler/hcr_gate_meta_data.h" 27#include "ecmascript/compiler/type.h" 28#include "ecmascript/mem/chunk.h" 29#include "ecmascript/mem/chunk_containers.h" 30 31#include "libpandabase/macros.h" 32 33namespace panda::ecmascript::kungfu { 34 35#define CACHED_VALUE_LIST(V) \ 36 V(1) \ 37 V(2) \ 38 V(3) \ 39 V(4) \ 40 V(5) \ 41 42// cached ARG list 43#define CACHED_ARG_LIST(V) \ 44 V(0) \ 45 V(1) \ 46 V(2) \ 47 V(3) \ 48 V(4) \ 49 V(5) \ 50 V(6) \ 51 V(7) \ 52 V(8) \ 53 V(9) \ 54 V(10) \ 55 56struct GateMetaDataChache { 57static constexpr size_t ONE_VALUE = 1; 58static constexpr size_t TWO_VALUE = 2; 59static constexpr size_t THREE_VALUE = 3; 60static constexpr size_t FOUR_VALUE = 4; 61static constexpr size_t FIVE_VALUE = 5; 62 63#define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 64 GateMetaData cached##NAME##_ { OpCode::OP, R, S, D, V }; 65 IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_CACHED_GATE_META) 66#undef DECLARE_CACHED_GATE_META 67 68#define DECLARE_CACHED_VALUE_META(VALUE) \ 69GateMetaData cachedMerge##VALUE##_ { OpCode::MERGE, GateFlags::CONTROL, VALUE, 0, 0 }; \ 70GateMetaData cachedLoopBegin##VALUE##_ { OpCode::LOOP_BEGIN, GateFlags::CONTROL, VALUE, 0, 0 }; \ 71GateMetaData cachedDependSelector##VALUE##_ { OpCode::DEPEND_SELECTOR, GateFlags::FIXED, 1, VALUE, 0 }; 72CACHED_VALUE_LIST(DECLARE_CACHED_VALUE_META) 73#undef DECLARE_CACHED_VALUE_META 74 75#define DECLARE_CACHED_VALUE_META(VALUE) \ 76OneParameterMetaData cachedArg##VALUE##_ { OpCode::ARG, GateFlags::HAS_ROOT, 0, 0, 0, VALUE }; 77CACHED_ARG_LIST(DECLARE_CACHED_VALUE_META) 78#undef DECLARE_CACHED_VALUE_META 79 80#define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 81 GateMetaData cached##NAME##1_{ OpCode::OP, R, S, D, ONE_VALUE }; \ 82 GateMetaData cached##NAME##2_{ OpCode::OP, R, S, D, TWO_VALUE }; \ 83 GateMetaData cached##NAME##3_{ OpCode::OP, R, S, D, THREE_VALUE }; \ 84 GateMetaData cached##NAME##4_{ OpCode::OP, R, S, D, FOUR_VALUE }; \ 85 GateMetaData cached##NAME##5_{ OpCode::OP, R, S, D, FIVE_VALUE }; 86GATE_META_DATA_LIST_WITH_VALUE_IN(DECLARE_CACHED_GATE_META) 87#undef DECLARE_CACHED_GATE_META 88 89#define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 90 OneParameterMetaData cached##NAME##1_{ OpCode::OP, R, S, D, V, ONE_VALUE }; \ 91 OneParameterMetaData cached##NAME##2_{ OpCode::OP, R, S, D, V, TWO_VALUE }; \ 92 OneParameterMetaData cached##NAME##3_{ OpCode::OP, R, S, D, V, THREE_VALUE }; \ 93 OneParameterMetaData cached##NAME##4_{ OpCode::OP, R, S, D, V, FOUR_VALUE }; \ 94 OneParameterMetaData cached##NAME##5_{ OpCode::OP, R, S, D, V, FIVE_VALUE }; 95GATE_META_DATA_LIST_WITH_VALUE(DECLARE_CACHED_GATE_META) 96#undef DECLARE_CACHED_GATE_META 97}; 98 99class GateMetaBuilder { 100public: 101#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 102 const GateMetaData* NAME(); 103 IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_META) 104#undef DECLARE_GATE_META 105 106#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 107 const GateMetaData* NAME(size_t value); 108 GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_META) 109#undef DECLARE_GATE_META 110 111#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 112 const GateMetaData* NAME(uint64_t value); 113 GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_META) 114#undef DECLARE_GATE_META 115 116#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 117 const GateMetaData* NAME(uint64_t value, uint64_t pcOffset); 118 GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_GATE_META) 119#undef DECLARE_GATE_META 120 121#define DECLARE_GATE_META_FOR_CALL(NAME, OP, R, S, D, V) \ 122 const GateMetaData* NAME(uint64_t value, uint64_t pcOffset, bool noGC); 123 GATE_META_DATA_LIST_FOR_CALL(DECLARE_GATE_META_FOR_CALL) 124#undef DECLARE_GATE_META_FOR_CALL 125 126#define DECLARE_GATE_META_FOR_NEW(NAME, OP, R, S, D, V) \ 127 const GateMetaData* NAME(uint64_t value, uint64_t pcOffset, \ 128 bool isFastCall); 129 GATE_META_DATA_LIST_FOR_NEW(DECLARE_GATE_META_FOR_NEW) 130#undef DECLARE_GATE_META_FOR_NEW 131 132#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 133 const GateMetaData* NAME(uint64_t pcOffset) const; 134 GATE_META_DATA_LIST_WITH_PC_OFFSET_FIXED_VALUE(DECLARE_GATE_META) 135#undef DECLARE_GATE_META 136 137#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 138 const GateMetaData* NAME(bool value); 139 GATE_META_DATA_LIST_WITH_BOOL(DECLARE_GATE_META) 140#undef DECLARE_GATE_META 141 142#define DECLARE_GATE_META_WITH_BOOL_VALUE_IN(NAME, OP, R, S, D, V) \ 143 const GateMetaData* NAME(size_t value, bool flag); 144 GATE_META_DATA_LIST_WITH_BOOL_VALUE_IN(DECLARE_GATE_META_WITH_BOOL_VALUE_IN) 145#undef DECLARE_GATE_META_WITH_BOOL_VALUE_IN 146 147 explicit GateMetaBuilder(Chunk* chunk); 148 149 const GateMetaData *JSBytecode( 150 size_t valuesIn, uint32_t methodId, EcmaOpcode opcode, uint32_t pcOffset, uint32_t bcIndex, GateFlags flags) 151 { 152 return new (chunk_) JSBytecodeMetaData(valuesIn, methodId, opcode, pcOffset, bcIndex, flags); 153 } 154 155 const GateMetaData* Nop() 156 { 157 return &cachedNop_; 158 } 159 160 GateMetaData* NewGateMetaData(const GateMetaData* other) 161 { 162 auto meta = new (chunk_) GateMetaData(other->opcode_, other->GetFlags(), 163 other->statesIn_, other->dependsIn_, other->valuesIn_); 164 meta->SetKind(GateMetaData::Kind::MUTABLE_WITH_SIZE); 165 return meta; 166 } 167 168 const GateMetaData* ConstString(std::string_view str) 169 { 170 return new (chunk_) StringMetaData(chunk_, str); 171 } 172 173private: 174 const GateMetaDataChache cache_; 175 const GateMetaData cachedNop_ { OpCode::NOP, GateFlags::NONE_FLAG, 0, 0, 0 }; 176 Chunk* chunk_; 177}; 178} // namespace panda::ecmascript::kungfu 179#endif // ECMASCRIPT_COMPILER_GATE_META_DATA_CACHE_H 180