| OLD | NEW |
| 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 3313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3324 const VectorSlotPair& feedback, | 3324 const VectorSlotPair& feedback, |
| 3325 OutputFrameStateCombine combine, | 3325 OutputFrameStateCombine combine, |
| 3326 TypeofMode typeof_mode) { | 3326 TypeofMode typeof_mode) { |
| 3327 Node* the_hole = jsgraph()->TheHoleConstant(); | 3327 Node* the_hole = jsgraph()->TheHoleConstant(); |
| 3328 VariableMode mode = variable->mode(); | 3328 VariableMode mode = variable->mode(); |
| 3329 switch (variable->location()) { | 3329 switch (variable->location()) { |
| 3330 case VariableLocation::GLOBAL: | 3330 case VariableLocation::GLOBAL: |
| 3331 case VariableLocation::UNALLOCATED: { | 3331 case VariableLocation::UNALLOCATED: { |
| 3332 // Global var, const, or let variable. | 3332 // Global var, const, or let variable. |
| 3333 Handle<Name> name = variable->name(); | 3333 Handle<Name> name = variable->name(); |
| 3334 Handle<Object> constant_value = | 3334 if (Node* node = TryLoadGlobalConstant(name)) return node; |
| 3335 jsgraph()->isolate()->factory()->GlobalConstantFor(name); | |
| 3336 if (!constant_value.is_null()) { | |
| 3337 // Optimize global constants like "undefined", "Infinity", and "NaN". | |
| 3338 return jsgraph()->Constant(constant_value); | |
| 3339 } | |
| 3340 Node* value = BuildGlobalLoad(name, feedback, typeof_mode); | 3335 Node* value = BuildGlobalLoad(name, feedback, typeof_mode); |
| 3341 states.AddToNode(value, bailout_id, combine); | 3336 states.AddToNode(value, bailout_id, combine); |
| 3342 return value; | 3337 return value; |
| 3343 } | 3338 } |
| 3344 case VariableLocation::PARAMETER: | 3339 case VariableLocation::PARAMETER: |
| 3345 case VariableLocation::LOCAL: { | 3340 case VariableLocation::LOCAL: { |
| 3346 // Local var, const, or let variable. | 3341 // Local var, const, or let variable. |
| 3347 Node* value = environment()->Lookup(variable); | 3342 Node* value = environment()->Lookup(variable); |
| 3348 if (mode == CONST_LEGACY) { | 3343 if (mode == CONST_LEGACY) { |
| 3349 // Perform check for uninitialized legacy const variables. | 3344 // Perform check for uninitialized legacy const variables. |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3747 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference, | 3742 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference, |
| 3748 MachineType type, Node* value) { | 3743 MachineType type, Node* value) { |
| 3749 StoreRepresentation representation(type, kNoWriteBarrier); | 3744 StoreRepresentation representation(type, kNoWriteBarrier); |
| 3750 return NewNode(jsgraph()->machine()->Store(representation), | 3745 return NewNode(jsgraph()->machine()->Store(representation), |
| 3751 jsgraph()->ExternalConstant(reference), | 3746 jsgraph()->ExternalConstant(reference), |
| 3752 jsgraph()->IntPtrConstant(0), value); | 3747 jsgraph()->IntPtrConstant(0), value); |
| 3753 } | 3748 } |
| 3754 | 3749 |
| 3755 | 3750 |
| 3756 Node* AstGraphBuilder::BuildToBoolean(Node* input) { | 3751 Node* AstGraphBuilder::BuildToBoolean(Node* input) { |
| 3757 // TODO(bmeurer, mstarzinger): Refactor this into a separate optimization | 3752 if (Node* node = TryFastToBoolean(input)) return node; |
| 3758 // method. | |
| 3759 switch (input->opcode()) { | |
| 3760 case IrOpcode::kNumberConstant: { | |
| 3761 NumberMatcher m(input); | |
| 3762 return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN()); | |
| 3763 } | |
| 3764 case IrOpcode::kHeapConstant: { | |
| 3765 Handle<HeapObject> object = HeapObjectMatcher(input).Value(); | |
| 3766 return jsgraph_->BooleanConstant(object->BooleanValue()); | |
| 3767 } | |
| 3768 case IrOpcode::kJSEqual: | |
| 3769 case IrOpcode::kJSNotEqual: | |
| 3770 case IrOpcode::kJSStrictEqual: | |
| 3771 case IrOpcode::kJSStrictNotEqual: | |
| 3772 case IrOpcode::kJSLessThan: | |
| 3773 case IrOpcode::kJSLessThanOrEqual: | |
| 3774 case IrOpcode::kJSGreaterThan: | |
| 3775 case IrOpcode::kJSGreaterThanOrEqual: | |
| 3776 case IrOpcode::kJSUnaryNot: | |
| 3777 case IrOpcode::kJSToBoolean: | |
| 3778 case IrOpcode::kJSDeleteProperty: | |
| 3779 case IrOpcode::kJSHasProperty: | |
| 3780 case IrOpcode::kJSInstanceOf: | |
| 3781 return input; | |
| 3782 default: | |
| 3783 break; | |
| 3784 } | |
| 3785 return NewNode(javascript()->ToBoolean(), input); | 3753 return NewNode(javascript()->ToBoolean(), input); |
| 3786 } | 3754 } |
| 3787 | 3755 |
| 3788 | 3756 |
| 3789 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { | 3757 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { |
| 3790 // TODO(turbofan): Possible optimization is to NOP on name constants. But the | 3758 if (Node* node = TryFastToName(input)) return node; |
| 3791 // same caveat as with BuildToBoolean applies, and it should be factored out | |
| 3792 // into a JSOperatorReducer. | |
| 3793 Node* name = NewNode(javascript()->ToName(), input); | 3759 Node* name = NewNode(javascript()->ToName(), input); |
| 3794 PrepareFrameState(name, bailout_id); | 3760 PrepareFrameState(name, bailout_id); |
| 3795 return name; | 3761 return name; |
| 3796 } | 3762 } |
| 3797 | 3763 |
| 3798 | 3764 |
| 3799 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) { | 3765 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) { |
| 3800 Node* object = NewNode(javascript()->ToObject(), input); | 3766 Node* object = NewNode(javascript()->ToObject(), input); |
| 3801 PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push()); | 3767 PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push()); |
| 3802 return object; | 3768 return object; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3926 js_op = javascript()->Modulus(language_mode()); | 3892 js_op = javascript()->Modulus(language_mode()); |
| 3927 break; | 3893 break; |
| 3928 default: | 3894 default: |
| 3929 UNREACHABLE(); | 3895 UNREACHABLE(); |
| 3930 js_op = NULL; | 3896 js_op = NULL; |
| 3931 } | 3897 } |
| 3932 return NewNode(js_op, left, right); | 3898 return NewNode(js_op, left, right); |
| 3933 } | 3899 } |
| 3934 | 3900 |
| 3935 | 3901 |
| 3902 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { |
| 3903 // Optimize global constants like "undefined", "Infinity", and "NaN". |
| 3904 Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name); |
| 3905 if (!constant_value.is_null()) return jsgraph()->Constant(constant_value); |
| 3906 return nullptr; |
| 3907 } |
| 3908 |
| 3909 |
| 3910 Node* AstGraphBuilder::TryFastToBoolean(Node* input) { |
| 3911 switch (input->opcode()) { |
| 3912 case IrOpcode::kNumberConstant: { |
| 3913 NumberMatcher m(input); |
| 3914 return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN()); |
| 3915 } |
| 3916 case IrOpcode::kHeapConstant: { |
| 3917 Handle<HeapObject> object = HeapObjectMatcher(input).Value(); |
| 3918 return jsgraph_->BooleanConstant(object->BooleanValue()); |
| 3919 } |
| 3920 case IrOpcode::kJSEqual: |
| 3921 case IrOpcode::kJSNotEqual: |
| 3922 case IrOpcode::kJSStrictEqual: |
| 3923 case IrOpcode::kJSStrictNotEqual: |
| 3924 case IrOpcode::kJSLessThan: |
| 3925 case IrOpcode::kJSLessThanOrEqual: |
| 3926 case IrOpcode::kJSGreaterThan: |
| 3927 case IrOpcode::kJSGreaterThanOrEqual: |
| 3928 case IrOpcode::kJSUnaryNot: |
| 3929 case IrOpcode::kJSToBoolean: |
| 3930 case IrOpcode::kJSDeleteProperty: |
| 3931 case IrOpcode::kJSHasProperty: |
| 3932 case IrOpcode::kJSInstanceOf: |
| 3933 return input; |
| 3934 default: |
| 3935 break; |
| 3936 } |
| 3937 return nullptr; |
| 3938 } |
| 3939 |
| 3940 |
| 3941 Node* AstGraphBuilder::TryFastToName(Node* input) { |
| 3942 switch (input->opcode()) { |
| 3943 case IrOpcode::kHeapConstant: { |
| 3944 Handle<HeapObject> object = HeapObjectMatcher(input).Value(); |
| 3945 if (object->IsName()) return input; |
| 3946 break; |
| 3947 } |
| 3948 case IrOpcode::kJSToString: |
| 3949 case IrOpcode::kJSToName: |
| 3950 case IrOpcode::kJSTypeOf: |
| 3951 return input; |
| 3952 default: |
| 3953 break; |
| 3954 } |
| 3955 return nullptr; |
| 3956 } |
| 3957 |
| 3958 |
| 3936 bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) { | 3959 bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) { |
| 3937 if (info()->osr_ast_id() == stmt->OsrEntryId()) { | 3960 if (info()->osr_ast_id() == stmt->OsrEntryId()) { |
| 3938 info()->set_osr_expr_stack_height(std::max( | 3961 info()->set_osr_expr_stack_height(std::max( |
| 3939 environment()->stack_height(), info()->osr_expr_stack_height())); | 3962 environment()->stack_height(), info()->osr_expr_stack_height())); |
| 3940 return true; | 3963 return true; |
| 3941 } | 3964 } |
| 3942 return false; | 3965 return false; |
| 3943 } | 3966 } |
| 3944 | 3967 |
| 3945 | 3968 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4259 // Phi does not exist yet, introduce one. | 4282 // Phi does not exist yet, introduce one. |
| 4260 value = NewPhi(inputs, value, control); | 4283 value = NewPhi(inputs, value, control); |
| 4261 value->ReplaceInput(inputs - 1, other); | 4284 value->ReplaceInput(inputs - 1, other); |
| 4262 } | 4285 } |
| 4263 return value; | 4286 return value; |
| 4264 } | 4287 } |
| 4265 | 4288 |
| 4266 } // namespace compiler | 4289 } // namespace compiler |
| 4267 } // namespace internal | 4290 } // namespace internal |
| 4268 } // namespace v8 | 4291 } // namespace v8 |
| OLD | NEW |