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/type.h" 23 #include "ecmascript/mem/chunk.h" 24 #include "ecmascript/mem/chunk_containers.h" 25 26 #include "libpandabase/macros.h" 27 28 namespace panda::ecmascript::kungfu { 29 30 #define CACHED_VALUE_LIST(V) \ 31 V(1) \ 32 V(2) \ 33 V(3) \ 34 V(4) \ 35 V(5) \ 36 37 // cached ARG list 38 #define CACHED_ARG_LIST(V) \ 39 V(0) \ 40 V(1) \ 41 V(2) \ 42 V(3) \ 43 V(4) \ 44 V(5) \ 45 V(6) \ 46 V(7) \ 47 V(8) \ 48 V(9) \ 49 V(10) \ 50 51 struct GateMetaDataChache { 52 static constexpr size_t ONE_VALUE = 1; 53 static constexpr size_t TWO_VALUE = 2; 54 static constexpr size_t THREE_VALUE = 3; 55 static constexpr size_t FOUR_VALUE = 4; 56 static constexpr size_t FIVE_VALUE = 5; 57 58 #define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 59 GateMetaData cached##NAME##_ { OpCode::OP, R, S, D, V }; 60 IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_CACHED_GATE_META) 61 #undef DECLARE_CACHED_GATE_META 62 63 #define DECLARE_CACHED_VALUE_META(VALUE) \ 64 GateMetaData cachedMerge##VALUE##_ { OpCode::MERGE, GateFlags::CONTROL, VALUE, 0, 0 }; \ 65 GateMetaData cachedDependSelector##VALUE##_ { OpCode::DEPEND_SELECTOR, GateFlags::FIXED, 1, VALUE, 0 }; 66 CACHED_VALUE_LIST(DECLARE_CACHED_VALUE_META) 67 #undef DECLARE_CACHED_VALUE_META 68 69 #define DECLARE_CACHED_VALUE_META(VALUE) \ 70 OneParameterMetaData cachedArg##VALUE##_ { OpCode::ARG, GateFlags::HAS_ROOT, 0, 0, 0, VALUE }; 71 CACHED_ARG_LIST(DECLARE_CACHED_VALUE_META) 72 #undef DECLARE_CACHED_VALUE_META 73 74 #define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 75 GateMetaData cached##NAME##1_{ OpCode::OP, R, S, D, ONE_VALUE }; \ 76 GateMetaData cached##NAME##2_{ OpCode::OP, R, S, D, TWO_VALUE }; \ 77 GateMetaData cached##NAME##3_{ OpCode::OP, R, S, D, THREE_VALUE }; \ 78 GateMetaData cached##NAME##4_{ OpCode::OP, R, S, D, FOUR_VALUE }; \ 79 GateMetaData cached##NAME##5_{ OpCode::OP, R, S, D, FIVE_VALUE }; 80 GATE_META_DATA_LIST_WITH_VALUE_IN(DECLARE_CACHED_GATE_META) 81 #undef DECLARE_CACHED_GATE_META 82 83 #define DECLARE_CACHED_GATE_META(NAME, OP, R, S, D, V) \ 84 OneParameterMetaData cached##NAME##1_{ OpCode::OP, R, S, D, V, ONE_VALUE }; \ 85 OneParameterMetaData cached##NAME##2_{ OpCode::OP, R, S, D, V, TWO_VALUE }; \ 86 OneParameterMetaData cached##NAME##3_{ OpCode::OP, R, S, D, V, THREE_VALUE }; \ 87 OneParameterMetaData cached##NAME##4_{ OpCode::OP, R, S, D, V, FOUR_VALUE }; \ 88 OneParameterMetaData cached##NAME##5_{ OpCode::OP, R, S, D, V, FIVE_VALUE }; 89 GATE_META_DATA_LIST_WITH_VALUE(DECLARE_CACHED_GATE_META) 90 #undef DECLARE_CACHED_GATE_META 91 }; 92 93 class GateMetaBuilder { 94 public: 95 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 96 const GateMetaData* NAME(); 97 IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_META) 98 #undef DECLARE_GATE_META 99 100 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 101 const GateMetaData* NAME(size_t value); 102 GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_META) 103 #undef DECLARE_GATE_META 104 105 #define DECLARE_GATE_META(NAME, OP, R, S, D, V) \ 106 const GateMetaData* NAME(uint64_t value); 107 GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_GATE_META) 108 #undef DECLARE_GATE_META 109 110 explicit GateMetaBuilder(Chunk* chunk); JSBytecode(size_t valuesIn,EcmaOpcode opcode,uint32_t bcIndex,GateFlags flags)111 const GateMetaData* JSBytecode(size_t valuesIn, EcmaOpcode opcode, uint32_t bcIndex, GateFlags flags) 112 { 113 return new (chunk_) JSBytecodeMetaData(valuesIn, opcode, bcIndex, flags); 114 } 115 TypedBinaryOp(uint64_t value,TypedBinOp binOp)116 const GateMetaData* TypedBinaryOp(uint64_t value, TypedBinOp binOp) 117 { 118 return new (chunk_) TypedBinaryMegaData(value, binOp); 119 } 120 Nop()121 const GateMetaData* Nop() 122 { 123 return &cachedNop_; 124 } 125 NewGateMetaData(const GateMetaData * other)126 GateMetaData* NewGateMetaData(const GateMetaData* other) 127 { 128 auto meta = new (chunk_) GateMetaData(other->opcode_, other->GetFlags(), 129 other->statesIn_, other->dependsIn_, other->valuesIn_); 130 meta->SetKind(GateMetaData::Kind::MUTABLE_WITH_SIZE); 131 return meta; 132 } 133 134 private: 135 const GateMetaDataChache cache_; 136 const GateMetaData cachedNop_ { OpCode::NOP, GateFlags::NONE_FLAG, 0, 0, 0 }; 137 Chunk* chunk_; 138 }; 139 } // namespace panda::ecmascript::kungfu 140 #endif // ECMASCRIPT_COMPILER_GATE_META_DATA_CACHE_H 141