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/control-builders.h" | 8 #include "src/compiler/control-builders.h" |
9 #include "src/compiler/machine-operator.h" | 9 #include "src/compiler/machine-operator.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 { | 635 { |
636 IfBuilder is_null(this); | 636 IfBuilder is_null(this); |
637 Node* is_null_cond = | 637 Node* is_null_cond = |
638 NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant()); | 638 NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant()); |
639 is_null.If(is_null_cond); | 639 is_null.If(is_null_cond); |
640 is_null.Then(); | 640 is_null.Then(); |
641 is_null.Else(); | 641 is_null.Else(); |
642 // Convert object to jsobject. | 642 // Convert object to jsobject. |
643 // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 643 // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
644 obj = NewNode(javascript()->ToObject(), obj); | 644 obj = NewNode(javascript()->ToObject(), obj); |
| 645 PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push()); |
645 environment()->Push(obj); | 646 environment()->Push(obj); |
646 // TODO(dcarney): should do a fast enum cache check here to skip runtime. | 647 // TODO(dcarney): should do a fast enum cache check here to skip runtime. |
647 environment()->Push(obj); | 648 environment()->Push(obj); |
648 Node* cache_type = ProcessArguments( | 649 Node* cache_type = ProcessArguments( |
649 javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1); | 650 javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1); |
| 651 PrepareFrameState(cache_type, stmt->EnumId(), |
| 652 OutputFrameStateCombine::Push()); |
650 // TODO(dcarney): these next runtime calls should be removed in favour of | 653 // TODO(dcarney): these next runtime calls should be removed in favour of |
651 // a few simplified instructions. | 654 // a few simplified instructions. |
652 environment()->Push(obj); | 655 environment()->Push(obj); |
653 environment()->Push(cache_type); | 656 environment()->Push(cache_type); |
654 Node* cache_pair = | 657 Node* cache_pair = |
655 ProcessArguments(javascript()->CallRuntime(Runtime::kForInInit, 2), 2); | 658 ProcessArguments(javascript()->CallRuntime(Runtime::kForInInit, 2), 2); |
656 // cache_type may have been replaced. | 659 // cache_type may have been replaced. |
657 Node* cache_array = NewNode(common()->Projection(0), cache_pair); | 660 Node* cache_array = NewNode(common()->Projection(0), cache_pair); |
658 cache_type = NewNode(common()->Projection(1), cache_pair); | 661 cache_type = NewNode(common()->Projection(1), cache_pair); |
659 environment()->Push(cache_type); | 662 environment()->Push(cache_type); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 // Create node to deep-copy the literal boilerplate. | 878 // Create node to deep-copy the literal boilerplate. |
876 expr->BuildConstantProperties(isolate()); | 879 expr->BuildConstantProperties(isolate()); |
877 Node* literals_array = | 880 Node* literals_array = |
878 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); | 881 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); |
879 Node* literal_index = jsgraph()->Constant(expr->literal_index()); | 882 Node* literal_index = jsgraph()->Constant(expr->literal_index()); |
880 Node* constants = jsgraph()->Constant(expr->constant_properties()); | 883 Node* constants = jsgraph()->Constant(expr->constant_properties()); |
881 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); | 884 Node* flags = jsgraph()->Constant(expr->ComputeFlags()); |
882 const Operator* op = | 885 const Operator* op = |
883 javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4); | 886 javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4); |
884 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); | 887 Node* literal = NewNode(op, literals_array, literal_index, constants, flags); |
| 888 PrepareFrameState(literal, expr->CreateLiteralId(), |
| 889 OutputFrameStateCombine::Push()); |
885 | 890 |
886 // The object is expected on the operand stack during computation of the | 891 // The object is expected on the operand stack during computation of the |
887 // property values and is the value of the entire expression. | 892 // property values and is the value of the entire expression. |
888 environment()->Push(literal); | 893 environment()->Push(literal); |
889 | 894 |
890 // Mark all computed expressions that are bound to a key that is shadowed by | 895 // Mark all computed expressions that are bound to a key that is shadowed by |
891 // a later occurrence of the same key. For the marked expressions, no store | 896 // a later occurrence of the same key. For the marked expressions, no store |
892 // code is emitted. | 897 // code is emitted. |
893 expr->CalculateEmitStore(zone()); | 898 expr->CalculateEmitStore(zone()); |
894 | 899 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 break; | 941 break; |
937 } | 942 } |
938 case ObjectLiteral::Property::PROTOTYPE: { | 943 case ObjectLiteral::Property::PROTOTYPE: { |
939 environment()->Push(literal); // Duplicate receiver. | 944 environment()->Push(literal); // Duplicate receiver. |
940 VisitForValue(property->value()); | 945 VisitForValue(property->value()); |
941 Node* value = environment()->Pop(); | 946 Node* value = environment()->Pop(); |
942 Node* receiver = environment()->Pop(); | 947 Node* receiver = environment()->Pop(); |
943 if (property->emit_store()) { | 948 if (property->emit_store()) { |
944 const Operator* op = | 949 const Operator* op = |
945 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); | 950 javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2); |
946 NewNode(op, receiver, value); | 951 Node* set_prototype = NewNode(op, receiver, value); |
| 952 // SetPrototype should not lazy deopt on an object |
| 953 // literal. |
| 954 PrepareFrameState(set_prototype, BailoutId::None()); |
947 } | 955 } |
948 break; | 956 break; |
949 } | 957 } |
950 case ObjectLiteral::Property::GETTER: | 958 case ObjectLiteral::Property::GETTER: |
951 accessor_table.lookup(key)->second->getter = property->value(); | 959 accessor_table.lookup(key)->second->getter = property->value(); |
952 break; | 960 break; |
953 case ObjectLiteral::Property::SETTER: | 961 case ObjectLiteral::Property::SETTER: |
954 accessor_table.lookup(key)->second->setter = property->value(); | 962 accessor_table.lookup(key)->second->setter = property->value(); |
955 break; | 963 break; |
956 } | 964 } |
957 } | 965 } |
958 | 966 |
959 // Create nodes to define accessors, using only a single call to the runtime | 967 // Create nodes to define accessors, using only a single call to the runtime |
960 // for each pair of corresponding getters and setters. | 968 // for each pair of corresponding getters and setters. |
961 for (AccessorTable::Iterator it = accessor_table.begin(); | 969 for (AccessorTable::Iterator it = accessor_table.begin(); |
962 it != accessor_table.end(); ++it) { | 970 it != accessor_table.end(); ++it) { |
963 VisitForValue(it->first); | 971 VisitForValue(it->first); |
964 VisitForValueOrNull(it->second->getter); | 972 VisitForValueOrNull(it->second->getter); |
965 VisitForValueOrNull(it->second->setter); | 973 VisitForValueOrNull(it->second->setter); |
966 Node* setter = environment()->Pop(); | 974 Node* setter = environment()->Pop(); |
967 Node* getter = environment()->Pop(); | 975 Node* getter = environment()->Pop(); |
968 Node* name = environment()->Pop(); | 976 Node* name = environment()->Pop(); |
969 Node* attr = jsgraph()->Constant(NONE); | 977 Node* attr = jsgraph()->Constant(NONE); |
970 const Operator* op = | 978 const Operator* op = |
971 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 979 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
972 Node* call = NewNode(op, literal, name, getter, setter, attr); | 980 Node* call = NewNode(op, literal, name, getter, setter, attr); |
973 PrepareFrameState(call, it->first->id()); | 981 // This should not lazy deopt on a new literal. |
| 982 PrepareFrameState(call, BailoutId::None()); |
974 } | 983 } |
975 | 984 |
976 // Transform literals that contain functions to fast properties. | 985 // Transform literals that contain functions to fast properties. |
977 if (expr->has_function()) { | 986 if (expr->has_function()) { |
978 const Operator* op = | 987 const Operator* op = |
979 javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 988 javascript()->CallRuntime(Runtime::kToFastProperties, 1); |
980 NewNode(op, literal); | 989 NewNode(op, literal); |
981 } | 990 } |
982 | 991 |
983 ast_context()->ProduceValue(environment()->Pop()); | 992 ast_context()->ProduceValue(environment()->Pop()); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 Variable* variable = callee->AsVariableProxy()->var(); | 1239 Variable* variable = callee->AsVariableProxy()->var(); |
1231 DCHECK(variable->location() == Variable::LOOKUP); | 1240 DCHECK(variable->location() == Variable::LOOKUP); |
1232 Node* name = jsgraph()->Constant(variable->name()); | 1241 Node* name = jsgraph()->Constant(variable->name()); |
1233 const Operator* op = | 1242 const Operator* op = |
1234 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); | 1243 javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2); |
1235 Node* pair = NewNode(op, current_context(), name); | 1244 Node* pair = NewNode(op, current_context(), name); |
1236 callee_value = NewNode(common()->Projection(0), pair); | 1245 callee_value = NewNode(common()->Projection(0), pair); |
1237 receiver_value = NewNode(common()->Projection(1), pair); | 1246 receiver_value = NewNode(common()->Projection(1), pair); |
1238 | 1247 |
1239 PrepareFrameState(pair, expr->EvalOrLookupId(), | 1248 PrepareFrameState(pair, expr->EvalOrLookupId(), |
1240 OutputFrameStateCombine::Push()); | 1249 OutputFrameStateCombine::Push(2)); |
1241 break; | 1250 break; |
1242 } | 1251 } |
1243 case Call::PROPERTY_CALL: { | 1252 case Call::PROPERTY_CALL: { |
1244 Property* property = callee->AsProperty(); | 1253 Property* property = callee->AsProperty(); |
1245 VisitForValue(property->obj()); | 1254 VisitForValue(property->obj()); |
1246 Node* object = environment()->Top(); | 1255 Node* object = environment()->Top(); |
1247 VectorSlotPair pair = | 1256 VectorSlotPair pair = |
1248 CreateVectorSlotPair(property->PropertyFeedbackSlot()); | 1257 CreateVectorSlotPair(property->PropertyFeedbackSlot()); |
1249 if (property->key()->IsPropertyName()) { | 1258 if (property->key()->IsPropertyName()) { |
1250 Unique<Name> name = | 1259 Unique<Name> name = |
(...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == | 2128 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == |
2120 IrOpcode::kDead); | 2129 IrOpcode::kDead); |
2121 NodeProperties::ReplaceFrameStateInput( | 2130 NodeProperties::ReplaceFrameStateInput( |
2122 node, environment()->Checkpoint(ast_id, combine)); | 2131 node, environment()->Checkpoint(ast_id, combine)); |
2123 } | 2132 } |
2124 } | 2133 } |
2125 | 2134 |
2126 } | 2135 } |
2127 } | 2136 } |
2128 } // namespace v8::internal::compiler | 2137 } // namespace v8::internal::compiler |
OLD | NEW |