Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: test/unittests/compiler/js-type-feedback-unittest.cc

Issue 1145143002: [turbofan] Pass deoptimization mode to type feedback specializer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/pipeline.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler.h" 5 #include "src/compiler.h"
6 6
7 #include "src/compiler/access-builder.h" 7 #include "src/compiler/access-builder.h"
8 #include "src/compiler/js-graph.h" 8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/js-operator.h" 9 #include "src/compiler/js-operator.h"
10 #include "src/compiler/js-type-feedback.h" 10 #include "src/compiler/js-type-feedback.h"
(...skipping 16 matching lines...) Expand all
27 27
28 class JSTypeFeedbackTest : public TypedGraphTest { 28 class JSTypeFeedbackTest : public TypedGraphTest {
29 public: 29 public:
30 JSTypeFeedbackTest() 30 JSTypeFeedbackTest()
31 : TypedGraphTest(3), 31 : TypedGraphTest(3),
32 javascript_(zone()), 32 javascript_(zone()),
33 dependencies_(isolate(), zone()) {} 33 dependencies_(isolate(), zone()) {}
34 ~JSTypeFeedbackTest() override { dependencies_.Rollback(); } 34 ~JSTypeFeedbackTest() override { dependencies_.Rollback(); }
35 35
36 protected: 36 protected:
37 Reduction Reduce(Node* node) { 37 Reduction Reduce(Node* node,
38 JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
38 Handle<GlobalObject> global_object( 39 Handle<GlobalObject> global_object(
39 isolate()->native_context()->global_object(), isolate()); 40 isolate()->native_context()->global_object(), isolate());
40 41
41 MachineOperatorBuilder machine(zone()); 42 MachineOperatorBuilder machine(zone());
42 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); 43 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
43 JSTypeFeedbackTable table(zone()); 44 JSTypeFeedbackTable table(zone());
44 // TODO(titzer): mock the GraphReducer here for better unit testing. 45 // TODO(titzer): mock the GraphReducer here for better unit testing.
45 GraphReducer graph_reducer(graph(), zone()); 46 GraphReducer graph_reducer(graph(), zone());
46 JSTypeFeedbackSpecializer reducer(&graph_reducer, &jsgraph, &table, nullptr, 47 JSTypeFeedbackSpecializer reducer(&graph_reducer, &jsgraph, &table, nullptr,
47 global_object, &dependencies_); 48 global_object, mode, &dependencies_);
48 return reducer.Reduce(node); 49 return reducer.Reduce(node);
49 } 50 }
50 51
51 Node* EmptyFrameState() { 52 Node* EmptyFrameState() {
52 MachineOperatorBuilder machine(zone()); 53 MachineOperatorBuilder machine(zone());
53 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); 54 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine);
54 return jsgraph.EmptyFrameState(); 55 return jsgraph.EmptyFrameState();
55 } 56 }
56 57
57 JSOperatorBuilder* javascript() { return &javascript_; } 58 JSOperatorBuilder* javascript() { return &javascript_; }
58 59
59 void SetGlobalProperty(const char* string, int value) { 60 void SetGlobalProperty(const char* string, int value) {
60 SetGlobalProperty(string, Handle<Smi>(Smi::FromInt(value), isolate())); 61 SetGlobalProperty(string, Handle<Smi>(Smi::FromInt(value), isolate()));
61 } 62 }
62 63
63 void SetGlobalProperty(const char* string, double value) { 64 void SetGlobalProperty(const char* string, double value) {
64 SetGlobalProperty(string, isolate()->factory()->NewNumber(value)); 65 SetGlobalProperty(string, isolate()->factory()->NewNumber(value));
65 } 66 }
66 67
67 void SetGlobalProperty(const char* string, Handle<Object> value) { 68 void SetGlobalProperty(const char* string, Handle<Object> value) {
68 Handle<JSObject> global(isolate()->context()->global_object(), isolate()); 69 Handle<JSObject> global(isolate()->context()->global_object(), isolate());
69 Handle<String> name = 70 Handle<String> name =
70 isolate()->factory()->NewStringFromAsciiChecked(string); 71 isolate()->factory()->NewStringFromAsciiChecked(string);
71 MaybeHandle<Object> result = 72 MaybeHandle<Object> result =
72 JSReceiver::SetProperty(global, name, value, SLOPPY); 73 JSReceiver::SetProperty(global, name, value, SLOPPY);
73 result.Assert(); 74 result.Assert();
74 } 75 }
75 76
76 Node* ReturnLoadNamedFromGlobal(const char* string, Node* effect, 77 Node* ReturnLoadNamedFromGlobal(
77 Node* control) { 78 const char* string, Node* effect, Node* control,
79 JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
78 VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(), 80 VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
79 FeedbackVectorICSlot::Invalid()); 81 FeedbackVectorICSlot::Invalid());
80 Node* global = Parameter(Type::GlobalObject()); 82 Node* global = Parameter(Type::GlobalObject());
81 Node* context = UndefinedConstant(); 83 Node* context = UndefinedConstant();
82 84
83 Unique<Name> name = Unique<Name>::CreateUninitialized( 85 Unique<Name> name = Unique<Name>::CreateUninitialized(
84 isolate()->factory()->NewStringFromAsciiChecked(string)); 86 isolate()->factory()->NewStringFromAsciiChecked(string));
85 const Operator* op = javascript()->LoadNamed(name, feedback); 87 const Operator* op = javascript()->LoadNamed(name, feedback);
86 Node* load = graph()->NewNode(op, global, context); 88 Node* load = graph()->NewNode(op, global, context);
87 if (FLAG_turbo_deoptimization) { 89 if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) {
88 for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); 90 for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op);
89 i++) { 91 i++) {
90 load->AppendInput(zone(), EmptyFrameState()); 92 load->AppendInput(zone(), EmptyFrameState());
91 } 93 }
92 } 94 }
93 load->AppendInput(zone(), effect); 95 load->AppendInput(zone(), effect);
94 load->AppendInput(zone(), control); 96 load->AppendInput(zone(), control);
95 Node* if_success = graph()->NewNode(common()->IfSuccess(), load); 97 Node* if_success = graph()->NewNode(common()->IfSuccess(), load);
96 return graph()->NewNode(common()->Return(), load, load, if_success); 98 return graph()->NewNode(common()->Return(), load, load, if_success);
97 } 99 }
98 100
99 CompilationDependencies* dependencies() { return &dependencies_; } 101 CompilationDependencies* dependencies() { return &dependencies_; }
100 102
101 private: 103 private:
102 JSOperatorBuilder javascript_; 104 JSOperatorBuilder javascript_;
103 CompilationDependencies dependencies_; 105 CompilationDependencies dependencies_;
104 }; 106 };
105 107
106 #define WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION \ 108
107 for (int i = FLAG_turbo_deoptimization = 0; i < 2; \ 109 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) {
108 FLAG_turbo_deoptimization = ++i) 110 const int kValue = 111;
109 111 const char* kName = "banana";
110 112 SetGlobalProperty(kName, kValue);
111 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_smi) { 113
112 const int const_value = 111; 114 Node* ret = ReturnLoadNamedFromGlobal(
113 const char* property_name = "banana"; 115 kName, graph()->start(), graph()->start(),
114 SetGlobalProperty(property_name, const_value); 116 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
115 117 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
116 WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { 118
117 Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), 119 Reduction r = Reduce(ret->InputAt(0),
118 graph()->start()); 120 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
119 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); 121 EXPECT_FALSE(r.Changed());
120 122 EXPECT_TRUE(dependencies()->IsEmpty());
121 Reduction r = Reduce(ret->InputAt(0)); 123 }
122 124
123 if (FLAG_turbo_deoptimization) { 125
124 // Check LoadNamed(global) => HeapConstant[const_value] 126 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) {
125 ASSERT_TRUE(r.Changed()); 127 const int kValue = 111;
126 EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); 128 const char* kName = "banana";
127 129 SetGlobalProperty(kName, kValue);
128 EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), 130
129 graph()->start())); 131 Node* ret = ReturnLoadNamedFromGlobal(
130 EXPECT_THAT(graph()->end(), IsEnd(ret)); 132 kName, graph()->start(), graph()->start(),
131 133 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
132 EXPECT_FALSE(dependencies()->IsEmpty()); 134 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
133 dependencies()->Rollback(); 135
134 } else { 136 Reduction r = Reduce(ret->InputAt(0),
135 ASSERT_FALSE(r.Changed()); 137 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
136 EXPECT_TRUE(dependencies()->IsEmpty()); 138
137 } 139 // Check LoadNamed(global) => HeapConstant[kValue]
138 } 140 ASSERT_TRUE(r.Changed());
139 } 141 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue));
140 142
141 143 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(),
142 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_derble) { 144 graph()->start()));
143 const double const_value = -11.25; 145 EXPECT_THAT(graph()->end(), IsEnd(ret));
144 const char* property_name = "kiwi"; 146
145 SetGlobalProperty(property_name, const_value); 147 EXPECT_FALSE(dependencies()->IsEmpty());
146 148 dependencies()->Rollback();
147 WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { 149 }
148 Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), 150
149 graph()->start()); 151
150 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); 152 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) {
151 153 const double kValue = -11.25;
152 Reduction r = Reduce(ret->InputAt(0)); 154 const char* kName = "kiwi";
153 155 SetGlobalProperty(kName, kValue);
154 if (FLAG_turbo_deoptimization) { 156
155 // Check LoadNamed(global) => HeapConstant[const_value] 157 Node* ret = ReturnLoadNamedFromGlobal(
156 ASSERT_TRUE(r.Changed()); 158 kName, graph()->start(), graph()->start(),
157 EXPECT_THAT(r.replacement(), IsNumberConstant(const_value)); 159 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
158 160 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
159 EXPECT_THAT(ret, IsReturn(IsNumberConstant(const_value), graph()->start(), 161
160 graph()->start())); 162 Reduction r = Reduce(ret->InputAt(0),
161 EXPECT_THAT(graph()->end(), IsEnd(ret)); 163 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
162 164
163 EXPECT_FALSE(dependencies()->IsEmpty()); 165 EXPECT_FALSE(r.Changed());
164 } else { 166 EXPECT_TRUE(dependencies()->IsEmpty());
165 ASSERT_FALSE(r.Changed()); 167 }
166 EXPECT_TRUE(dependencies()->IsEmpty()); 168
167 } 169
168 } 170 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) {
169 } 171 const double kValue = -11.25;
170 172 const char* kName = "kiwi";
171 173 SetGlobalProperty(kName, kValue);
172 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConst_string) { 174
173 Unique<HeapObject> const_value = Unique<HeapObject>::CreateImmovable( 175 Node* ret = ReturnLoadNamedFromGlobal(
176 kName, graph()->start(), graph()->start(),
177 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
178 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
179
180 Reduction r = Reduce(ret->InputAt(0),
181 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
182
183 // Check LoadNamed(global) => HeapConstant[kValue]
184 ASSERT_TRUE(r.Changed());
185 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue));
186
187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(),
188 graph()->start()));
189 EXPECT_THAT(graph()->end(), IsEnd(ret));
190
191 EXPECT_FALSE(dependencies()->IsEmpty());
192 }
193
194
195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) {
196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable(
174 isolate()->factory()->undefined_string()); 197 isolate()->factory()->undefined_string());
175 const char* property_name = "mango"; 198 const char* kName = "mango";
176 SetGlobalProperty(property_name, const_value.handle()); 199 SetGlobalProperty(kName, kValue.handle());
177 200
178 WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { 201 Node* ret = ReturnLoadNamedFromGlobal(
179 Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), 202 kName, graph()->start(), graph()->start(),
180 graph()->start()); 203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
181 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); 204 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
182 205
183 Reduction r = Reduce(ret->InputAt(0)); 206 Reduction r = Reduce(ret->InputAt(0),
184 207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
185 if (FLAG_turbo_deoptimization) { 208 ASSERT_FALSE(r.Changed());
186 // Check LoadNamed(global) => HeapConstant[const_value] 209 EXPECT_TRUE(dependencies()->IsEmpty());
187 ASSERT_TRUE(r.Changed()); 210 }
188 EXPECT_THAT(r.replacement(), IsHeapConstant(const_value)); 211
189 212
190 EXPECT_THAT(ret, IsReturn(IsHeapConstant(const_value), graph()->start(), 213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) {
191 graph()->start())); 214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable(
192 EXPECT_THAT(graph()->end(), IsEnd(ret)); 215 isolate()->factory()->undefined_string());
193 216 const char* kName = "mango";
194 EXPECT_FALSE(dependencies()->IsEmpty()); 217 SetGlobalProperty(kName, kValue.handle());
195 dependencies()->Rollback(); 218
196 } else { 219 Node* ret = ReturnLoadNamedFromGlobal(
197 ASSERT_FALSE(r.Changed()); 220 kName, graph()->start(), graph()->start(),
198 EXPECT_TRUE(dependencies()->IsEmpty()); 221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
199 } 222 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
200 } 223
201 } 224 Reduction r = Reduce(ret->InputAt(0),
202 225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
203 226
204 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_smi) { 227 // Check LoadNamed(global) => HeapConstant[kValue]
205 const char* property_name = "melon"; 228 ASSERT_TRUE(r.Changed());
206 SetGlobalProperty(property_name, 123); 229 EXPECT_THAT(r.replacement(), IsHeapConstant(kValue));
207 SetGlobalProperty(property_name, 124); 230
208 231 EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(),
209 WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { 232 graph()->start()));
210 Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), 233 EXPECT_THAT(graph()->end(), IsEnd(ret));
211 graph()->start()); 234
212 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); 235 EXPECT_FALSE(dependencies()->IsEmpty());
213 236 dependencies()->Rollback();
214 Reduction r = Reduce(ret->InputAt(0)); 237 }
215 238
216 if (FLAG_turbo_deoptimization) { 239
217 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) 240 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) {
218 ASSERT_TRUE(r.Changed()); 241 const char* kName = "melon";
219 FieldAccess access = AccessBuilder::ForPropertyCellValue(); 242 SetGlobalProperty(kName, 123);
220 Capture<Node*> cell_capture; 243 SetGlobalProperty(kName, 124);
221 Matcher<Node*> load_field_match = IsLoadField( 244
222 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); 245 Node* ret = ReturnLoadNamedFromGlobal(
223 EXPECT_THAT(r.replacement(), load_field_match); 246 kName, graph()->start(), graph()->start(),
224 247 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
225 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); 248 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
226 EXPECT_TRUE(cell.HasValue()); 249
227 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); 250 Reduction r = Reduce(ret->InputAt(0),
228 251 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
229 EXPECT_THAT( 252 ASSERT_FALSE(r.Changed());
230 ret, IsReturn(load_field_match, load_field_match, graph()->start())); 253 EXPECT_TRUE(dependencies()->IsEmpty());
231 EXPECT_THAT(graph()->end(), IsEnd(ret)); 254 }
232 255
233 EXPECT_FALSE(dependencies()->IsEmpty()); 256
234 dependencies()->Rollback(); 257 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) {
235 } else { 258 const char* kName = "melon";
236 ASSERT_FALSE(r.Changed()); 259 SetGlobalProperty(kName, 123);
237 EXPECT_TRUE(dependencies()->IsEmpty()); 260 SetGlobalProperty(kName, 124);
238 } 261
239 } 262 Node* ret = ReturnLoadNamedFromGlobal(
240 } 263 kName, graph()->start(), graph()->start(),
241 264 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
242 265 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
243 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCell_string) { 266
244 const char* property_name = "pineapple"; 267 Reduction r = Reduce(ret->InputAt(0),
245 SetGlobalProperty(property_name, isolate()->factory()->undefined_string()); 268 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
246 SetGlobalProperty(property_name, isolate()->factory()->undefined_value()); 269
247 270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
248 WITH_AND_WITHOUT_TURBO_DEOPTIMIZATION { 271 ASSERT_TRUE(r.Changed());
249 Node* ret = ReturnLoadNamedFromGlobal(property_name, graph()->start(), 272 FieldAccess access = AccessBuilder::ForPropertyCellValue();
250 graph()->start()); 273 Capture<Node*> cell_capture;
251 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); 274 Matcher<Node*> load_field_match = IsLoadField(
252 275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
253 Reduction r = Reduce(ret->InputAt(0)); 276 EXPECT_THAT(r.replacement(), load_field_match);
254 277
255 if (FLAG_turbo_deoptimization) { 278 HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
256 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) 279 EXPECT_TRUE(cell.HasValue());
257 ASSERT_TRUE(r.Changed()); 280 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
258 FieldAccess access = AccessBuilder::ForPropertyCellValue(); 281
259 Capture<Node*> cell_capture; 282 EXPECT_THAT(ret,
260 Matcher<Node*> load_field_match = IsLoadField( 283 IsReturn(load_field_match, load_field_match, graph()->start()));
261 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); 284 EXPECT_THAT(graph()->end(), IsEnd(ret));
262 EXPECT_THAT(r.replacement(), load_field_match); 285
263 286 EXPECT_FALSE(dependencies()->IsEmpty());
264 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); 287 dependencies()->Rollback();
265 EXPECT_TRUE(cell.HasValue()); 288 }
266 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); 289
267 290
268 EXPECT_THAT( 291 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) {
269 ret, IsReturn(load_field_match, load_field_match, graph()->start())); 292 const char* kName = "pineapple";
270 EXPECT_THAT(graph()->end(), IsEnd(ret)); 293 SetGlobalProperty(kName, isolate()->factory()->undefined_string());
271 294 SetGlobalProperty(kName, isolate()->factory()->undefined_value());
272 EXPECT_FALSE(dependencies()->IsEmpty()); 295
273 dependencies()->Rollback(); 296 Node* ret = ReturnLoadNamedFromGlobal(
274 } else { 297 kName, graph()->start(), graph()->start(),
275 ASSERT_FALSE(r.Changed()); 298 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
276 EXPECT_TRUE(dependencies()->IsEmpty()); 299 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
277 } 300
278 } 301 Reduction r = Reduce(ret->InputAt(0),
279 } 302 JSTypeFeedbackSpecializer::kDeoptimizationDisabled);
280 } 303 ASSERT_FALSE(r.Changed());
281 } 304 EXPECT_TRUE(dependencies()->IsEmpty());
282 } 305 }
306
307
308 TEST_F(JSTypeFeedbackTest,
309 JSLoadNamedGlobalPropertyCellStringWithDeoptimization) {
310 const char* kName = "pineapple";
311 SetGlobalProperty(kName, isolate()->factory()->undefined_string());
312 SetGlobalProperty(kName, isolate()->factory()->undefined_value());
313
314 Node* ret = ReturnLoadNamedFromGlobal(
315 kName, graph()->start(), graph()->start(),
316 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
317 graph()->SetEnd(graph()->NewNode(common()->End(), ret));
318
319 Reduction r = Reduce(ret->InputAt(0),
320 JSTypeFeedbackSpecializer::kDeoptimizationEnabled);
321
322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell)
323 ASSERT_TRUE(r.Changed());
324 FieldAccess access = AccessBuilder::ForPropertyCellValue();
325 Capture<Node*> cell_capture;
326 Matcher<Node*> load_field_match = IsLoadField(
327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start());
328 EXPECT_THAT(r.replacement(), load_field_match);
329
330 HeapObjectMatcher<PropertyCell> cell(cell_capture.value());
331 EXPECT_TRUE(cell.HasValue());
332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell());
333
334 EXPECT_THAT(ret,
335 IsReturn(load_field_match, load_field_match, graph()->start()));
336 EXPECT_THAT(graph()->end(), IsEnd(ret));
337
338 EXPECT_FALSE(dependencies()->IsEmpty());
339 dependencies()->Rollback();
340 }
341
342 } // namespace compiler
343 } // namespace internal
344 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/pipeline.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698