| OLD | NEW | 
|---|
| 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" | 
| 6 | 6 | 
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" | 
| 8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" | 
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" | 
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" | 
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 719       break; | 719       break; | 
| 720     case IrOpcode::kPlainPrimitiveToWord32: | 720     case IrOpcode::kPlainPrimitiveToWord32: | 
| 721       state = LowerPlainPrimitiveToWord32(node, *effect, *control); | 721       state = LowerPlainPrimitiveToWord32(node, *effect, *control); | 
| 722       break; | 722       break; | 
| 723     case IrOpcode::kPlainPrimitiveToFloat64: | 723     case IrOpcode::kPlainPrimitiveToFloat64: | 
| 724       state = LowerPlainPrimitiveToFloat64(node, *effect, *control); | 724       state = LowerPlainPrimitiveToFloat64(node, *effect, *control); | 
| 725       break; | 725       break; | 
| 726     case IrOpcode::kEnsureWritableFastElements: | 726     case IrOpcode::kEnsureWritableFastElements: | 
| 727       state = LowerEnsureWritableFastElements(node, *effect, *control); | 727       state = LowerEnsureWritableFastElements(node, *effect, *control); | 
| 728       break; | 728       break; | 
|  | 729     case IrOpcode::kMaybeGrowFastElements: | 
|  | 730       state = LowerMaybeGrowFastElements(node, frame_state, *effect, *control); | 
|  | 731       break; | 
| 729     case IrOpcode::kTransitionElementsKind: | 732     case IrOpcode::kTransitionElementsKind: | 
| 730       state = LowerTransitionElementsKind(node, *effect, *control); | 733       state = LowerTransitionElementsKind(node, *effect, *control); | 
| 731       break; | 734       break; | 
| 732     case IrOpcode::kLoadTypedElement: | 735     case IrOpcode::kLoadTypedElement: | 
| 733       state = LowerLoadTypedElement(node, *effect, *control); | 736       state = LowerLoadTypedElement(node, *effect, *control); | 
| 734       break; | 737       break; | 
| 735     case IrOpcode::kStoreTypedElement: | 738     case IrOpcode::kStoreTypedElement: | 
| 736       state = LowerStoreTypedElement(node, *effect, *control); | 739       state = LowerStoreTypedElement(node, *effect, *control); | 
| 737       break; | 740       break; | 
| 738     case IrOpcode::kFloat64RoundUp: | 741     case IrOpcode::kFloat64RoundUp: | 
| (...skipping 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2625   Node* etrue = effect; | 2628   Node* etrue = effect; | 
| 2626   Node* vtrue = elements; | 2629   Node* vtrue = elements; | 
| 2627 | 2630 | 
| 2628   // We need to take a copy of the {elements} and set them up for {object}. | 2631   // We need to take a copy of the {elements} and set them up for {object}. | 
| 2629   Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 2632   Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 
| 2630   Node* efalse = effect; | 2633   Node* efalse = effect; | 
| 2631   Node* vfalse; | 2634   Node* vfalse; | 
| 2632   { | 2635   { | 
| 2633     // We need to create a copy of the {elements} for {object}. | 2636     // We need to create a copy of the {elements} for {object}. | 
| 2634     Operator::Properties properties = Operator::kEliminatable; | 2637     Operator::Properties properties = Operator::kEliminatable; | 
| 2635     Callable callable = CodeFactory::CopyFixedArray(isolate()); | 2638     Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate()); | 
| 2636     CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 2639     CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 
| 2637     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 2640     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 
| 2638         isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 2641         isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 
| 2639         properties); | 2642         properties); | 
| 2640     vfalse = efalse = graph()->NewNode( | 2643     vfalse = efalse = graph()->NewNode( | 
| 2641         common()->Call(desc), jsgraph()->HeapConstant(callable.code()), | 2644         common()->Call(desc), jsgraph()->HeapConstant(callable.code()), object, | 
| 2642         elements, jsgraph()->NoContextConstant(), efalse); | 2645         jsgraph()->NoContextConstant(), efalse); | 
| 2643 |  | 
| 2644     // Store the new {elements} into {object}. |  | 
| 2645     efalse = graph()->NewNode( |  | 
| 2646         simplified()->StoreField(AccessBuilder::ForJSObjectElements()), object, |  | 
| 2647         vfalse, efalse, if_false); |  | 
| 2648   } | 2646   } | 
| 2649 | 2647 | 
| 2650   control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 2648   control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 
| 2651   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 2649   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 
| 2652   Node* value = graph()->NewNode( | 2650   Node* value = graph()->NewNode( | 
| 2653       common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control); | 2651       common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control); | 
| 2654 | 2652 | 
| 2655   return ValueEffectControl(value, effect, control); | 2653   return ValueEffectControl(value, effect, control); | 
| 2656 } | 2654 } | 
| 2657 | 2655 | 
| 2658 EffectControlLinearizer::ValueEffectControl | 2656 EffectControlLinearizer::ValueEffectControl | 
|  | 2657 EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, | 
|  | 2658                                                     Node* frame_state, | 
|  | 2659                                                     Node* effect, | 
|  | 2660                                                     Node* control) { | 
|  | 2661   GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op()); | 
|  | 2662   Node* object = node->InputAt(0); | 
|  | 2663   Node* elements = node->InputAt(1); | 
|  | 2664   Node* index = node->InputAt(2); | 
|  | 2665   Node* length = node->InputAt(3); | 
|  | 2666 | 
|  | 2667   Node* check0 = graph()->NewNode((flags & GrowFastElementsFlag::kHoleyElements) | 
|  | 2668                                       ? machine()->Uint32LessThanOrEqual() | 
|  | 2669                                       : machine()->Word32Equal(), | 
|  | 2670                                   length, index); | 
|  | 2671   Node* branch0 = graph()->NewNode(common()->Branch(), check0, control); | 
|  | 2672 | 
|  | 2673   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 
|  | 2674   Node* etrue0 = effect; | 
|  | 2675   Node* vtrue0 = elements; | 
|  | 2676   { | 
|  | 2677     // Load the length of the {elements} backing store. | 
|  | 2678     Node* elements_length = etrue0 = graph()->NewNode( | 
|  | 2679         simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), elements, | 
|  | 2680         etrue0, if_true0); | 
|  | 2681     elements_length = ChangeSmiToInt32(elements_length); | 
|  | 2682 | 
|  | 2683     // Check if we need to grow the {elements} backing store. | 
|  | 2684     Node* check1 = | 
|  | 2685         graph()->NewNode(machine()->Uint32LessThan(), index, elements_length); | 
|  | 2686     Node* branch1 = | 
|  | 2687         graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); | 
|  | 2688 | 
|  | 2689     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | 
|  | 2690     Node* etrue1 = etrue0; | 
|  | 2691     Node* vtrue1 = vtrue0; | 
|  | 2692 | 
|  | 2693     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | 
|  | 2694     Node* efalse1 = etrue0; | 
|  | 2695     Node* vfalse1 = vtrue0; | 
|  | 2696     { | 
|  | 2697       // We need to grow the {elements} for {object}. | 
|  | 2698       Operator::Properties properties = Operator::kEliminatable; | 
|  | 2699       Callable callable = | 
|  | 2700           (flags & GrowFastElementsFlag::kDoubleElements) | 
|  | 2701               ? CodeFactory::GrowFastDoubleElements(isolate()) | 
|  | 2702               : CodeFactory::GrowFastSmiOrObjectElements(isolate()); | 
|  | 2703       CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 
|  | 2704       CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 
|  | 2705           isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 
|  | 2706           properties); | 
|  | 2707       vfalse1 = efalse1 = graph()->NewNode( | 
|  | 2708           common()->Call(desc), jsgraph()->HeapConstant(callable.code()), | 
|  | 2709           object, ChangeInt32ToSmi(index), jsgraph()->NoContextConstant(), | 
|  | 2710           efalse1); | 
|  | 2711 | 
|  | 2712       // Ensure that we were able to grow the {elements}. | 
|  | 2713       // TODO(turbofan): We use kSmi as reason here similar to Crankshaft, | 
|  | 2714       // but maybe we should just introduce a reason that makes sense. | 
|  | 2715       efalse1 = if_false1 = graph()->NewNode( | 
|  | 2716           common()->DeoptimizeIf(DeoptimizeReason::kSmi), ObjectIsSmi(vfalse1), | 
|  | 2717           frame_state, efalse1, if_false1); | 
|  | 2718     } | 
|  | 2719 | 
|  | 2720     if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | 
|  | 2721     etrue0 = | 
|  | 2722         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0); | 
|  | 2723     vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | 
|  | 2724                               vtrue1, vfalse1, if_true0); | 
|  | 2725 | 
|  | 2726     // For JSArray {object}s we also need to update the "length". | 
|  | 2727     if (flags & GrowFastElementsFlag::kArrayObject) { | 
|  | 2728       // Compute the new {length}. | 
|  | 2729       Node* object_length = ChangeInt32ToSmi(graph()->NewNode( | 
|  | 2730           machine()->Int32Add(), index, jsgraph()->Int32Constant(1))); | 
|  | 2731 | 
|  | 2732       // Update the "length" property of the {object}. | 
|  | 2733       etrue0 = | 
|  | 2734           graph()->NewNode(simplified()->StoreField( | 
|  | 2735                                AccessBuilder::ForJSArrayLength(FAST_ELEMENTS)), | 
|  | 2736                            object, object_length, etrue0, if_true0); | 
|  | 2737     } | 
|  | 2738   } | 
|  | 2739 | 
|  | 2740   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 
|  | 2741   Node* efalse0 = effect; | 
|  | 2742   Node* vfalse0 = elements; | 
|  | 2743   { | 
|  | 2744     // In case of non-holey {elements}, we need to verify that the {index} is | 
|  | 2745     // in-bounds, otherwise for holey {elements}, the check above already | 
|  | 2746     // guards the index (and the operator forces {index} to be unsigned). | 
|  | 2747     if (!(flags & GrowFastElementsFlag::kHoleyElements)) { | 
|  | 2748       Node* check1 = | 
|  | 2749           graph()->NewNode(machine()->Uint32LessThan(), index, length); | 
|  | 2750       efalse0 = if_false0 = graph()->NewNode( | 
|  | 2751           common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check1, | 
|  | 2752           frame_state, efalse0, if_false0); | 
|  | 2753     } | 
|  | 2754   } | 
|  | 2755 | 
|  | 2756   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | 
|  | 2757   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); | 
|  | 2758   Node* value = | 
|  | 2759       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), vtrue0, | 
|  | 2760                        vfalse0, control); | 
|  | 2761 | 
|  | 2762   return ValueEffectControl(value, effect, control); | 
|  | 2763 } | 
|  | 2764 | 
|  | 2765 EffectControlLinearizer::ValueEffectControl | 
| 2659 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, | 2766 EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, | 
| 2660                                                      Node* control) { | 2767                                                      Node* control) { | 
| 2661   ElementsTransition const transition = ElementsTransitionOf(node->op()); | 2768   ElementsTransition const transition = ElementsTransitionOf(node->op()); | 
| 2662   Node* object = node->InputAt(0); | 2769   Node* object = node->InputAt(0); | 
| 2663   Node* source_map = node->InputAt(1); | 2770   Node* source_map = node->InputAt(1); | 
| 2664   Node* target_map = node->InputAt(2); | 2771   Node* target_map = node->InputAt(2); | 
| 2665 | 2772 | 
| 2666   // Load the current map of {object}. | 2773   // Load the current map of {object}. | 
| 2667   Node* object_map = effect = | 2774   Node* object_map = effect = | 
| 2668       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, | 2775       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, | 
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3167         isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3274         isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 
| 3168         Operator::kNoThrow); | 3275         Operator::kNoThrow); | 
| 3169     to_number_operator_.set(common()->Call(desc)); | 3276     to_number_operator_.set(common()->Call(desc)); | 
| 3170   } | 3277   } | 
| 3171   return to_number_operator_.get(); | 3278   return to_number_operator_.get(); | 
| 3172 } | 3279 } | 
| 3173 | 3280 | 
| 3174 }  // namespace compiler | 3281 }  // namespace compiler | 
| 3175 }  // namespace internal | 3282 }  // namespace internal | 
| 3176 }  // namespace v8 | 3283 }  // namespace v8 | 
| OLD | NEW | 
|---|