blob: 7aa0c6447a731db53c7bd4279bafbbfb674ae1b7 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/js-operator.h"
6#include "src/compiler/opcodes.h"
7#include "src/compiler/operator.h"
8#include "src/compiler/operator-properties.h"
9#include "test/unittests/test-utils.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
15// -----------------------------------------------------------------------------
16// Shared operators.
17
18
19namespace {
20
21struct SharedOperator {
22 const Operator* (JSOperatorBuilder::*constructor)();
23 IrOpcode::Value opcode;
24 Operator::Properties properties;
25 int value_input_count;
26 int frame_state_input_count;
27 int effect_input_count;
28 int control_input_count;
29 int value_output_count;
30 int effect_output_count;
31};
32
33
34std::ostream& operator<<(std::ostream& os, const SharedOperator& sop) {
35 return os << IrOpcode::Mnemonic(sop.opcode);
36}
37
38
39const SharedOperator kSharedOperators[] = {
40#define SHARED(Name, properties, value_input_count, frame_state_input_count, \
41 effect_input_count, control_input_count, value_output_count, \
42 effect_output_count) \
43 { \
44 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \
45 value_input_count, frame_state_input_count, effect_input_count, \
46 control_input_count, value_output_count, effect_output_count \
47 }
48 SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
49 SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
50 SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0),
51 SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0),
52 SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
53 SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
54 SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
55 SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
56 SHARED(BitwiseOr, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
57 SHARED(BitwiseXor, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
58 SHARED(BitwiseAnd, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
59 SHARED(ShiftLeft, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
60 SHARED(ShiftRight, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
61 SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
62 SHARED(Add, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
63 SHARED(Subtract, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
64 SHARED(Multiply, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
65 SHARED(Divide, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
66 SHARED(Modulus, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
67 SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0),
68 SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0),
69 SHARED(ToNumber, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
70 SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
71 SHARED(ToName, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
72 SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
73 SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
74 SHARED(Create, Operator::kEliminatable, 0, 0, 1, 1, 1, 1),
75 SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
76 SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0),
77 SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
78 SHARED(Debugger, Operator::kNoProperties, 0, 0, 1, 1, 0, 1),
79 SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
80 SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
81 SHARED(CreateBlockContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
82 SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
83 SHARED(CreateScriptContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1)
84#undef SHARED
85};
86
87} // namespace
88
89
90class JSSharedOperatorTest
91 : public TestWithZone,
92 public ::testing::WithParamInterface<SharedOperator> {};
93
94
95TEST_P(JSSharedOperatorTest, InstancesAreGloballyShared) {
96 const SharedOperator& sop = GetParam();
97 JSOperatorBuilder javascript1(zone());
98 JSOperatorBuilder javascript2(zone());
99 EXPECT_EQ((javascript1.*sop.constructor)(), (javascript2.*sop.constructor)());
100}
101
102
103TEST_P(JSSharedOperatorTest, NumberOfInputsAndOutputs) {
104 JSOperatorBuilder javascript(zone());
105 const SharedOperator& sop = GetParam();
106 const Operator* op = (javascript.*sop.constructor)();
107
108 const int context_input_count = 1;
109 // TODO(jarin): Get rid of this hack.
110 const int frame_state_input_count =
111 FLAG_turbo_deoptimization ? sop.frame_state_input_count : 0;
112 EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
113 EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op));
114 EXPECT_EQ(frame_state_input_count,
115 OperatorProperties::GetFrameStateInputCount(op));
116 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
117 EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
118 EXPECT_EQ(sop.value_input_count + context_input_count +
119 frame_state_input_count + sop.effect_input_count +
120 sop.control_input_count,
121 OperatorProperties::GetTotalInputCount(op));
122
123 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
124 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
125 EXPECT_EQ(0, op->ControlOutputCount());
126}
127
128
129TEST_P(JSSharedOperatorTest, OpcodeIsCorrect) {
130 JSOperatorBuilder javascript(zone());
131 const SharedOperator& sop = GetParam();
132 const Operator* op = (javascript.*sop.constructor)();
133 EXPECT_EQ(sop.opcode, op->opcode());
134}
135
136
137TEST_P(JSSharedOperatorTest, Properties) {
138 JSOperatorBuilder javascript(zone());
139 const SharedOperator& sop = GetParam();
140 const Operator* op = (javascript.*sop.constructor)();
141 EXPECT_EQ(sop.properties, op->properties());
142}
143
144
145INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorTest,
146 ::testing::ValuesIn(kSharedOperators));
147
148
149// -----------------------------------------------------------------------------
150// JSStoreProperty.
151
152
153class JSStorePropertyOperatorTest
154 : public TestWithZone,
155 public ::testing::WithParamInterface<StrictMode> {};
156
157
158TEST_P(JSStorePropertyOperatorTest, InstancesAreGloballyShared) {
159 const StrictMode mode = GetParam();
160 JSOperatorBuilder javascript1(zone());
161 JSOperatorBuilder javascript2(zone());
162 EXPECT_EQ(javascript1.StoreProperty(mode), javascript2.StoreProperty(mode));
163}
164
165
166TEST_P(JSStorePropertyOperatorTest, NumberOfInputsAndOutputs) {
167 JSOperatorBuilder javascript(zone());
168 const StrictMode mode = GetParam();
169 const Operator* op = javascript.StoreProperty(mode);
170
171 // TODO(jarin): Get rid of this hack.
172 const int frame_state_input_count = FLAG_turbo_deoptimization ? 1 : 0;
173 EXPECT_EQ(3, op->ValueInputCount());
174 EXPECT_EQ(1, OperatorProperties::GetContextInputCount(op));
175 EXPECT_EQ(frame_state_input_count,
176 OperatorProperties::GetFrameStateInputCount(op));
177 EXPECT_EQ(1, op->EffectInputCount());
178 EXPECT_EQ(1, op->ControlInputCount());
179 EXPECT_EQ(6 + frame_state_input_count,
180 OperatorProperties::GetTotalInputCount(op));
181
182 EXPECT_EQ(0, op->ValueOutputCount());
183 EXPECT_EQ(1, op->EffectOutputCount());
184 EXPECT_EQ(0, op->ControlOutputCount());
185}
186
187
188TEST_P(JSStorePropertyOperatorTest, OpcodeIsCorrect) {
189 JSOperatorBuilder javascript(zone());
190 const StrictMode mode = GetParam();
191 const Operator* op = javascript.StoreProperty(mode);
192 EXPECT_EQ(IrOpcode::kJSStoreProperty, op->opcode());
193}
194
195
196TEST_P(JSStorePropertyOperatorTest, OpParameter) {
197 JSOperatorBuilder javascript(zone());
198 const StrictMode mode = GetParam();
199 const Operator* op = javascript.StoreProperty(mode);
200 EXPECT_EQ(mode, OpParameter<StrictMode>(op));
201}
202
203
204TEST_P(JSStorePropertyOperatorTest, Properties) {
205 JSOperatorBuilder javascript(zone());
206 const StrictMode mode = GetParam();
207 const Operator* op = javascript.StoreProperty(mode);
208 EXPECT_EQ(Operator::kNoProperties, op->properties());
209}
210
211
212INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSStorePropertyOperatorTest,
213 ::testing::Values(SLOPPY, STRICT));
214
215} // namespace compiler
216} // namespace internal
217} // namespace v8