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/compiler/gate_accessor.h" 16#include "ecmascript/compiler/share_opcodes.h" 17#include "ecmascript/compiler/verifier.h" 18#include "ecmascript/compiler/typed_bytecode_lowering.h" 19#include "ecmascript/compiler/typed_hcr_lowering.h" 20#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 21#include "ecmascript/elements.h" 22#include "ecmascript/mem/concurrent_marker.h" 23#include "ecmascript/mem/native_area_allocator.h" 24#include "ecmascript/tests/test_helper.h" 25#include "gtest/gtest.h" 26#include <cstddef> 27 28namespace panda::test { 29class MetaDataEqualTests : public testing::Test {}; 30 31using ecmascript::kungfu::Circuit; 32using ecmascript::kungfu::CircuitBuilder; 33using ecmascript::kungfu::EcmaOpcode; 34using ecmascript::kungfu::ElementsKind; 35using ecmascript::kungfu::Environment; 36using ecmascript::kungfu::GateAccessor; 37using ecmascript::kungfu::GateMetaData; 38using ecmascript::kungfu::GateType; 39using ecmascript::kungfu::JSBytecodeMetaData; 40using ecmascript::kungfu::MachineType; 41using ecmascript::kungfu::PGOTypeRef; 42using ecmascript::kungfu::PGOSampleType; 43using ecmascript::kungfu::TypedBinOp; 44using ecmascript::kungfu::TypedCallTargetCheckOp; 45using ecmascript::kungfu::ParamType; 46using ecmascript::kungfu::TypedCallTargetCheckAccessor; 47 48HWTEST_F_L0(MetaDataEqualTests, StringMetaDataEqualTest) 49{ 50 // construct a circuit 51 ecmascript::NativeAreaAllocator allocator; 52 Circuit circuit(&allocator); 53 ecmascript::Chunk chunk(&allocator); 54 GateAccessor acc(&circuit); 55 CircuitBuilder builder(&circuit); 56 Environment env(0, &builder); 57 builder.SetEnvironment(&env); 58 59 auto stringGate1 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue()); 60 61 62 auto stringGate2 = circuit.GetConstantStringGate(MachineType::ARCH, "test2", GateType::NJSValue()); 63 64 EXPECT_FALSE(acc.MetaDataValueEqu(stringGate1, stringGate2)); 65 66 auto stringGate3 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue()); 67 68 EXPECT_TRUE(acc.MetaDataValueEqu(stringGate1, stringGate3)); 69} 70 71HWTEST_F_L0(MetaDataEqualTests, ConstantMetaDataEqualTest) 72{ 73 // construct a circuit 74 ecmascript::NativeAreaAllocator allocator; 75 Circuit circuit(&allocator); 76 ecmascript::Chunk chunk(&allocator); 77 GateAccessor acc(&circuit); 78 CircuitBuilder builder(&circuit); 79 Environment env(0, &builder); 80 builder.SetEnvironment(&env); 81 82 83 auto constantValue1 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 84 85 auto constantValue2 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 86 87 EXPECT_TRUE(acc.MetaDataValueEqu(constantValue1, constantValue2)); 88 89 auto constantValue3 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 90 91 auto constantValue4 = circuit.GetConstantGate(MachineType::I64, 3, GateType::NJSValue()); 92 93 EXPECT_FALSE(acc.MetaDataValueEqu(constantValue3, constantValue4)); 94 95 96 // MetaData is equal, but Gate is not equal 97 auto constantValue5 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 98 99 auto constantValue6 = circuit.GetConstantGate(MachineType::I32, 2, GateType::NJSValue()); 100 101 EXPECT_TRUE(acc.MetaDataValueEqu(constantValue5, constantValue6)); 102 103 // MetaData is equal, but Gate is not equal 104 auto ConstGateNJSValue2 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 105 106 auto ConstGateUndefined = 107 circuit.GetConstantGate(MachineType::I64, JSTaggedValue::VALUE_UNDEFINED, GateType::UndefinedType()); 108 109 EXPECT_TRUE(acc.MetaDataValueEqu(ConstGateNJSValue2, ConstGateUndefined)); 110} 111 112HWTEST_F_L0(MetaDataEqualTests, TypeErrorMetaDataEqualTest) 113{ 114 // construct a circuit 115 ecmascript::NativeAreaAllocator allocator; 116 Circuit circuit(&allocator); 117 ecmascript::Chunk chunk(&allocator); 118 GateAccessor acc(&circuit); 119 CircuitBuilder builder(&circuit); 120 Environment env(0, &builder); 121 builder.SetEnvironment(&env); 122 123 auto constantValue1 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue()); 124 auto stringGate1 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue()); 125 EXPECT_FALSE(acc.MetaDataValueEqu(constantValue1, stringGate1)); 126 EXPECT_FALSE(acc.MetaDataValueEqu(stringGate1, constantValue1)); 127} 128 129HWTEST_F_L0(MetaDataEqualTests, HCRMetaDataEqualTest) 130{ 131 // construct a circuit 132 ecmascript::NativeAreaAllocator allocator; 133 Circuit circuit(&allocator); 134 ecmascript::Chunk chunk(&allocator); 135 GateAccessor acc(&circuit); 136 CircuitBuilder builder(&circuit); 137 Environment env(0, &builder); 138 builder.SetEnvironment(&env); 139 140 // JSBytecodeMetaData 141 auto meta = circuit.JSBytecode(0, 0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); 142 auto gate = 143 circuit.NewGate(meta, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); 144 auto meta2 = circuit.JSBytecode(0, 0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false); 145 auto gate2 = 146 circuit.NewGate(meta2, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); 147 148 EXPECT_TRUE(acc.MetaDataValueEqu(gate, gate2)); 149 150 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))->SetElementsKind(ElementsKind::NUMBER); 151 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))->SetElementsKind(ElementsKind::NUMBER); 152 EXPECT_TRUE(acc.MetaDataValueEqu(gate, gate2)); 153 154 PGOSampleType type = PGOSampleType::CreateProfileType(0, 0); 155 PGOSampleType type2 = PGOSampleType::CreateProfileType(0, 0); 156 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta)) 157 ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type))); 158 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2)) 159 ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type2))); 160 EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2)); 161 162 PGOSampleType type3 = PGOSampleType::CreateProfileType(0, 1); 163 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta)) 164 ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type))); 165 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2)) 166 ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type3))); 167 EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2)); 168 169 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))->SetElementsKind(ElementsKind::NUMBER); 170 static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))->SetElementsKind(ElementsKind::HOLE_NUMBER); 171 EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2)); 172} 173 174HWTEST_F_L0(MetaDataEqualTests, MCRMetaDataEqualTest) 175{ 176 // construct a circuit 177 ecmascript::NativeAreaAllocator allocator; 178 Circuit circuit(&allocator); 179 ecmascript::Chunk chunk(&allocator); 180 GateAccessor acc(&circuit); 181 CircuitBuilder builder(&circuit); 182 Environment env(0, &builder); 183 builder.SetEnvironment(&env); 184 185 // TypedCallMetaData 186 auto callGate = 187 circuit.NewGate(circuit.TypedCall(0, 0, true), MachineType::I64, 188 {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); 189 190 auto callGate2 = 191 circuit.NewGate(circuit.TypedCall(0, 0, true), MachineType::I64, 192 {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType()); 193 194 EXPECT_TRUE(acc.MetaDataValueEqu(callGate, callGate2)); 195 EXPECT_TRUE(acc.MetaDataValueEqu(callGate2, callGate)); 196 197 // TypedCallTargetCheckMetaData 198 auto callGate3 = 199 circuit.NewGate(circuit.TypedCallTargetCheckOp( 200 TypedCallTargetCheckAccessor::ToValue(TypedCallTargetCheckOp::JSCALLTHIS_FAST)), MachineType::I64, 201 {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, 202 GateType::AnyType()); 203 auto callGate4 = 204 circuit.NewGate(circuit.TypedCallTargetCheckOp( 205 TypedCallTargetCheckAccessor::ToValue(TypedCallTargetCheckOp::JSCALLTHIS_FAST)), MachineType::I64, 206 {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, 207 GateType::AnyType()); 208 209 EXPECT_TRUE(acc.MetaDataValueEqu(callGate3, callGate4)); 210 EXPECT_TRUE(acc.MetaDataValueEqu(callGate4, callGate3)); 211 212 // TypedBinaryMetaData 213 uint64_t valueForType5 = ecmascript::kungfu::TypedBinaryAccessor::ToValue(ParamType::IntType(), 214 TypedBinOp::TYPED_ADD); 215 auto callGate5 = circuit.NewGate( 216 circuit.TypedBinaryOp(valueForType5), 217 MachineType::I64, { Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate() }, 218 GateType::AnyType()); 219 220 // TypedBinaryMetaData 221 uint64_t valueForType6 = ecmascript::kungfu::TypedBinaryAccessor::ToValue(ParamType::IntType(), 222 TypedBinOp::TYPED_ADD); 223 auto callGate6 = circuit.NewGate( 224 circuit.TypedBinaryOp(valueForType6), 225 MachineType::I64, { Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate() }, 226 GateType::AnyType()); 227 228 EXPECT_TRUE(acc.MetaDataValueEqu(callGate5, callGate6)); 229 EXPECT_TRUE(acc.MetaDataValueEqu(callGate6, callGate5)); 230} 231 232 233} // namespace panda::test 234