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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 1178153004: [turbofan] Fix throwing conversion inserted by JSTypedLowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 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 | « no previous file | src/compiler/node-properties.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // 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 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/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/compiler/access-builder.h" 6 #include "src/compiler/access-builder.h"
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/linkage.h" 9 #include "src/compiler/linkage.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 100
101 void ConvertInputsToNumber(Node* frame_state) { 101 void ConvertInputsToNumber(Node* frame_state) {
102 // To convert the inputs to numbers, we have to provide frame states 102 // To convert the inputs to numbers, we have to provide frame states
103 // for lazy bailouts in the ToNumber conversions. 103 // for lazy bailouts in the ToNumber conversions.
104 // We use a little hack here: we take the frame state before the binary 104 // We use a little hack here: we take the frame state before the binary
105 // operation and use it to construct the frame states for the conversion 105 // operation and use it to construct the frame states for the conversion
106 // so that after the deoptimization, the binary operation IC gets 106 // so that after the deoptimization, the binary operation IC gets
107 // already converted values from full code. This way we are sure that we 107 // already converted values from full code. This way we are sure that we
108 // will not re-do any of the side effects. 108 // will not re-do any of the side effects.
109 109
110 Node* left_input = 110 Node* left_input = nullptr;
111 left_type()->Is(Type::PlainPrimitive()) 111 Node* right_input = nullptr;
112 ? ConvertPlainPrimitiveToNumber(left()) 112 bool left_is_primitive = left_type()->Is(Type::PlainPrimitive());
113 : ConvertToNumber(left(), 113 bool right_is_primitive = right_type()->Is(Type::PlainPrimitive());
114 CreateFrameStateForLeftInput(frame_state)); 114 bool handles_exception = NodeProperties::IsExceptionalCall(node_);
115 115
116 Node* right_input = 116 if (!left_is_primitive && !right_is_primitive && handles_exception) {
117 right_type()->Is(Type::PlainPrimitive()) 117 ConvertBothInputsToNumber(&left_input, &right_input, frame_state);
118 ? ConvertPlainPrimitiveToNumber(right()) 118 } else {
119 : ConvertToNumber(right(), CreateFrameStateForRightInput( 119 left_input = left_is_primitive
120 ? ConvertPlainPrimitiveToNumber(left())
121 : ConvertSingleInputToNumber(
122 left(), CreateFrameStateForLeftInput(frame_state));
123 right_input = right_is_primitive
124 ? ConvertPlainPrimitiveToNumber(right())
125 : ConvertSingleInputToNumber(
126 right(), CreateFrameStateForRightInput(
120 frame_state, left_input)); 127 frame_state, left_input));
128 }
121 129
122 node_->ReplaceInput(0, left_input); 130 node_->ReplaceInput(0, left_input);
123 node_->ReplaceInput(1, right_input); 131 node_->ReplaceInput(1, right_input);
124 } 132 }
125 133
126 void ConvertInputsToUI32(Signedness left_signedness, 134 void ConvertInputsToUI32(Signedness left_signedness,
127 Signedness right_signedness) { 135 Signedness right_signedness) {
128 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); 136 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
129 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); 137 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
130 } 138 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 227 }
220 Type* right_type() { 228 Type* right_type() {
221 return NodeProperties::GetBounds(node_->InputAt(1)).upper; 229 return NodeProperties::GetBounds(node_->InputAt(1)).upper;
222 } 230 }
223 231
224 SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); } 232 SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
225 Graph* graph() const { return lowering_->graph(); } 233 Graph* graph() const { return lowering_->graph(); }
226 JSGraph* jsgraph() { return lowering_->jsgraph(); } 234 JSGraph* jsgraph() { return lowering_->jsgraph(); }
227 JSOperatorBuilder* javascript() { return lowering_->javascript(); } 235 JSOperatorBuilder* javascript() { return lowering_->javascript(); }
228 MachineOperatorBuilder* machine() { return lowering_->machine(); } 236 MachineOperatorBuilder* machine() { return lowering_->machine(); }
237 CommonOperatorBuilder* common() { return jsgraph()->common(); }
229 Zone* zone() const { return graph()->zone(); } 238 Zone* zone() const { return graph()->zone(); }
230 239
231 private: 240 private:
232 JSTypedLowering* lowering_; // The containing lowering instance. 241 JSTypedLowering* lowering_; // The containing lowering instance.
233 Node* node_; // The original node. 242 Node* node_; // The original node.
234 243
235 Node* ConvertToString(Node* node) { 244 Node* ConvertToString(Node* node) {
236 // Avoid introducing too many eager ToString() operations. 245 // Avoid introducing too many eager ToString() operations.
237 Reduction reduced = lowering_->ReduceJSToStringInput(node); 246 Reduction reduced = lowering_->ReduceJSToStringInput(node);
238 if (reduced.Changed()) return reduced.replacement(); 247 if (reduced.Changed()) return reduced.replacement();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())); 326 DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive()));
318 // Avoid inserting too many eager ToNumber() operations. 327 // Avoid inserting too many eager ToNumber() operations.
319 Reduction const reduction = lowering_->ReduceJSToNumberInput(node); 328 Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
320 if (reduction.Changed()) return reduction.replacement(); 329 if (reduction.Changed()) return reduction.replacement();
321 // TODO(jarin) Use PlainPrimitiveToNumber once we have it. 330 // TODO(jarin) Use PlainPrimitiveToNumber once we have it.
322 return graph()->NewNode( 331 return graph()->NewNode(
323 javascript()->ToNumber(), node, jsgraph()->NoContextConstant(), 332 javascript()->ToNumber(), node, jsgraph()->NoContextConstant(),
324 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start()); 333 jsgraph()->EmptyFrameState(), graph()->start(), graph()->start());
325 } 334 }
326 335
327 Node* ConvertToNumber(Node* node, Node* frame_state) { 336 Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) {
328 if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) { 337 DCHECK(!NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive()));
329 return ConvertPlainPrimitiveToNumber(node); 338 Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(),
330 } else { 339 frame_state, effect(), control());
331 Node* const n = 340 NodeProperties::ReplaceUses(node_, node_, node_, n, n);
332 graph()->NewNode(javascript()->ToNumber(), node, context(), 341 update_effect(n);
333 frame_state, effect(), control()); 342 return n;
334 update_effect(n); 343 }
335 return n; 344
345 void ConvertBothInputsToNumber(Node** left_result, Node** right_result,
346 Node* frame_state) {
347 Node* projections[2];
348
349 // Find {IfSuccess} and {IfException} continuations of the operation.
350 NodeProperties::CollectControlProjections(node_, projections, 2);
351 IfExceptionHint hint = OpParameter<IfExceptionHint>(projections[1]);
352 Node* if_exception = projections[1];
353 Node* if_success = projections[0];
354
355 // Insert two ToNumber() operations that both potentially throw.
356 Node* left_state = CreateFrameStateForLeftInput(frame_state);
357 Node* left_conv =
358 graph()->NewNode(javascript()->ToNumber(), left(), context(),
359 left_state, effect(), control());
360 Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv);
361 Node* right_state = CreateFrameStateForRightInput(frame_state, left_conv);
362 Node* right_conv =
363 graph()->NewNode(javascript()->ToNumber(), right(), context(),
364 right_state, left_conv, left_success);
365 Node* left_exception =
366 graph()->NewNode(common()->IfException(hint), left_conv, left_conv);
367 Node* right_exception =
368 graph()->NewNode(common()->IfException(hint), right_conv, right_conv);
369 NodeProperties::ReplaceControlInput(if_success, right_conv);
370 update_effect(right_conv);
371
372 // Wire conversions to existing {IfException} continuation.
373 Node* exception_merge = if_exception;
374 Node* exception_value =
375 graph()->NewNode(common()->Phi(kMachAnyTagged, 2), left_exception,
376 right_exception, exception_merge);
377 Node* exception_effect =
378 graph()->NewNode(common()->EffectPhi(2), left_exception,
379 right_exception, exception_merge);
380 for (Edge edge : exception_merge->use_edges()) {
381 if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect);
382 if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value);
336 } 383 }
384 NodeProperties::RemoveBounds(exception_merge);
385 exception_merge->ReplaceInput(0, left_exception);
386 exception_merge->ReplaceInput(1, right_exception);
387 exception_merge->set_op(common()->Merge(2));
388
389 *left_result = left_conv;
390 *right_result = right_conv;
337 } 391 }
338 392
339 Node* ConvertToUI32(Node* node, Signedness signedness) { 393 Node* ConvertToUI32(Node* node, Signedness signedness) {
340 // Avoid introducing too many eager NumberToXXnt32() operations. 394 // Avoid introducing too many eager NumberToXXnt32() operations.
341 Type* type = NodeProperties::GetBounds(node).upper; 395 Type* type = NodeProperties::GetBounds(node).upper;
342 if (signedness == kSigned) { 396 if (signedness == kSigned) {
343 if (!type->Is(Type::Signed32())) { 397 if (!type->Is(Type::Signed32())) {
344 node = graph()->NewNode(simplified()->NumberToInt32(), node); 398 node = graph()->NewNode(simplified()->NumberToInt32(), node);
345 } 399 }
346 } else { 400 } else {
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1618 } 1672 }
1619 1673
1620 1674
1621 MachineOperatorBuilder* JSTypedLowering::machine() const { 1675 MachineOperatorBuilder* JSTypedLowering::machine() const {
1622 return jsgraph()->machine(); 1676 return jsgraph()->machine();
1623 } 1677 }
1624 1678
1625 } // namespace compiler 1679 } // namespace compiler
1626 } // namespace internal 1680 } // namespace internal
1627 } // namespace v8 1681 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/node-properties.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698