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