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 33 namespace 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 56 struct GateMetaDataChache { 57 static constexpr size_t ONE_VALUE = 1; 58 static constexpr size_t TWO_VALUE = 2; 59 static constexpr size_t THREE_VALUE = 3; 60 static constexpr size_t FOUR_VALUE = 4; 61 static 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) \ 69 GateMetaData cachedMerge##VALUE##_ { OpCode::MERGE, GateFlags::CONTROL, VALUE, 0, 0 }; \ 70 GateMetaData cachedLoopBegin##VALUE##_ { OpCode::LOOP_BEGIN, GateFlags::CONTROL, VALUE, 0, 0 }; \ 71 GateMetaData cachedDependSelector##VALUE##_ { OpCode::DEPEND_SELECTOR, GateFlags::FIXED, 1, VALUE, 0 }; 72 CACHED_VALUE_LIST(DECLARE_CACHED_VALUE_META) 73 #undef DECLARE_CACHED_VALUE_META 74 75 #define DECLARE_CACHED_VALUE_META(VALUE) \ 76 OneParameterMetaData cachedArg##VALUE##_ { OpCode::ARG, GateFlags::HAS_ROOT, 0, 0, 0, VALUE }; 77 CACHED_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 }; 86 GATE_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 }; 95 GATE_META_DATA_LIST_WITH_VALUE(DECLARE_CACHED_GATE_META) 96 #undef DECLARE_CACHED_GATE_META 97 }; 98 99 class GateMetaBuilder { 100 public: 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 JSBytecode( size_t valuesIn, uint32_t methodId, EcmaOpcode opcode, uint32_t pcOffset, uint32_t bcIndex, GateFlags flags)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 Nop()155 const GateMetaData* Nop() 156 { 157 return &cachedNop_; 158 } 159 NewGateMetaData(const GateMetaData* other)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 ConstString(std::string_view str)168 const GateMetaData* ConstString(std::string_view str) 169 { 170 return new (chunk_) StringMetaData(chunk_, str); 171 } 172 173 private: 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