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/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 stack_dirty_ = false; | 231 stack_dirty_ = false; |
232 } | 232 } |
233 | 233 |
234 Operator* op = common()->FrameState(ast_id); | 234 Operator* op = common()->FrameState(ast_id); |
235 | 235 |
236 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); | 236 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, | 240 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, |
241 Expression::Context kind, | 241 Expression::Context kind) |
242 BailoutId bailout_id) | 242 : kind_(kind), owner_(own), outer_(own->ast_context()) { |
243 : bailout_id_(bailout_id), | |
244 kind_(kind), | |
245 owner_(own), | |
246 outer_(own->ast_context()) { | |
247 owner()->set_ast_context(this); // Push. | 243 owner()->set_ast_context(this); // Push. |
248 #ifdef DEBUG | 244 #ifdef DEBUG |
249 original_height_ = environment()->stack_height(); | 245 original_height_ = environment()->stack_height(); |
250 #endif | 246 #endif |
251 } | 247 } |
252 | 248 |
253 | 249 |
254 AstGraphBuilder::AstContext::~AstContext() { | 250 AstGraphBuilder::AstContext::~AstContext() { |
255 owner()->set_ast_context(outer_); // Pop. | 251 owner()->set_ast_context(outer_); // Pop. |
256 } | 252 } |
257 | 253 |
258 | 254 |
259 AstGraphBuilder::AstEffectContext::~AstEffectContext() { | 255 AstGraphBuilder::AstEffectContext::~AstEffectContext() { |
260 DCHECK(environment()->stack_height() == original_height_); | 256 DCHECK(environment()->stack_height() == original_height_); |
261 } | 257 } |
262 | 258 |
263 | 259 |
264 AstGraphBuilder::AstValueContext::~AstValueContext() { | 260 AstGraphBuilder::AstValueContext::~AstValueContext() { |
265 DCHECK(environment()->stack_height() == original_height_ + 1); | 261 DCHECK(environment()->stack_height() == original_height_ + 1); |
266 } | 262 } |
267 | 263 |
268 | 264 |
269 AstGraphBuilder::AstTestContext::~AstTestContext() { | 265 AstGraphBuilder::AstTestContext::~AstTestContext() { |
270 DCHECK(environment()->stack_height() == original_height_ + 1); | 266 DCHECK(environment()->stack_height() == original_height_ + 1); |
271 } | 267 } |
272 | 268 |
273 | 269 |
274 void AstGraphBuilder::AstEffectContext::ProduceValueWithLazyBailout( | |
275 Node* value) { | |
276 ProduceValue(value); | |
277 owner()->BuildLazyBailout(value, bailout_id_); | |
278 } | |
279 | |
280 | |
281 void AstGraphBuilder::AstValueContext::ProduceValueWithLazyBailout( | |
282 Node* value) { | |
283 ProduceValue(value); | |
284 owner()->BuildLazyBailout(value, bailout_id_); | |
285 } | |
286 | |
287 | |
288 void AstGraphBuilder::AstTestContext::ProduceValueWithLazyBailout(Node* value) { | |
289 environment()->Push(value); | |
290 owner()->BuildLazyBailout(value, bailout_id_); | |
291 environment()->Pop(); | |
292 ProduceValue(value); | |
293 } | |
294 | |
295 | |
296 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { | 270 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { |
297 // The value is ignored. | 271 // The value is ignored. |
298 } | 272 } |
299 | 273 |
300 | 274 |
301 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { | 275 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { |
302 environment()->Push(value); | 276 environment()->Push(value); |
303 } | 277 } |
304 | 278 |
305 | 279 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 326 |
353 | 327 |
354 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { | 328 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { |
355 for (int i = 0; i < exprs->length(); ++i) { | 329 for (int i = 0; i < exprs->length(); ++i) { |
356 VisitForValue(exprs->at(i)); | 330 VisitForValue(exprs->at(i)); |
357 } | 331 } |
358 } | 332 } |
359 | 333 |
360 | 334 |
361 void AstGraphBuilder::VisitForValue(Expression* expr) { | 335 void AstGraphBuilder::VisitForValue(Expression* expr) { |
362 AstValueContext for_value(this, expr->id()); | 336 AstValueContext for_value(this); |
363 if (!HasStackOverflow()) { | 337 if (!HasStackOverflow()) { |
364 expr->Accept(this); | 338 expr->Accept(this); |
365 } | 339 } |
366 } | 340 } |
367 | 341 |
368 | 342 |
369 void AstGraphBuilder::VisitForEffect(Expression* expr) { | 343 void AstGraphBuilder::VisitForEffect(Expression* expr) { |
370 AstEffectContext for_effect(this, expr->id()); | 344 AstEffectContext for_effect(this); |
371 if (!HasStackOverflow()) { | 345 if (!HasStackOverflow()) { |
372 expr->Accept(this); | 346 expr->Accept(this); |
373 } | 347 } |
374 } | 348 } |
375 | 349 |
376 | 350 |
377 void AstGraphBuilder::VisitForTest(Expression* expr) { | 351 void AstGraphBuilder::VisitForTest(Expression* expr) { |
378 AstTestContext for_condition(this, expr->id()); | 352 AstTestContext for_condition(this); |
379 if (!HasStackOverflow()) { | 353 if (!HasStackOverflow()) { |
380 expr->Accept(this); | 354 expr->Accept(this); |
381 } | 355 } |
382 } | 356 } |
383 | 357 |
384 | 358 |
385 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { | 359 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { |
386 Variable* variable = decl->proxy()->var(); | 360 Variable* variable = decl->proxy()->var(); |
387 VariableMode mode = decl->mode(); | 361 VariableMode mode = decl->mode(); |
388 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; | 362 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 environment()->Push(cache_length); | 680 environment()->Push(cache_length); |
707 environment()->Push(jsgraph()->ZeroConstant()); | 681 environment()->Push(jsgraph()->ZeroConstant()); |
708 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 682 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
709 LoopBuilder for_loop(this); | 683 LoopBuilder for_loop(this); |
710 for_loop.BeginLoop(); | 684 for_loop.BeginLoop(); |
711 // Check loop termination condition. | 685 // Check loop termination condition. |
712 Node* index = environment()->Peek(0); | 686 Node* index = environment()->Peek(0); |
713 Node* exit_cond = | 687 Node* exit_cond = |
714 NewNode(javascript()->LessThan(), index, cache_length); | 688 NewNode(javascript()->LessThan(), index, cache_length); |
715 // TODO(jarin): provide real bailout id. | 689 // TODO(jarin): provide real bailout id. |
716 BuildLazyBailout(exit_cond, BailoutId::None()); | 690 PrepareFrameState(exit_cond, BailoutId::None()); |
717 for_loop.BreakUnless(exit_cond); | 691 for_loop.BreakUnless(exit_cond); |
718 // TODO(dcarney): this runtime call should be a handful of | 692 // TODO(dcarney): this runtime call should be a handful of |
719 // simplified instructions that | 693 // simplified instructions that |
720 // basically produce | 694 // basically produce |
721 // value = array[index] | 695 // value = array[index] |
722 environment()->Push(obj); | 696 environment()->Push(obj); |
723 environment()->Push(cache_array); | 697 environment()->Push(cache_array); |
724 environment()->Push(cache_type); | 698 environment()->Push(cache_type); |
725 environment()->Push(index); | 699 environment()->Push(index); |
726 Node* pair = | 700 Node* pair = |
(...skipping 19 matching lines...) Expand all Loading... |
746 environment()->Push(jsgraph()->HeapConstant(function)); | 720 environment()->Push(jsgraph()->HeapConstant(function)); |
747 // Receiver. | 721 // Receiver. |
748 environment()->Push(obj); | 722 environment()->Push(obj); |
749 // Args. | 723 // Args. |
750 environment()->Push(value); | 724 environment()->Push(value); |
751 // result is either the string key or Smi(0) indicating the property | 725 // result is either the string key or Smi(0) indicating the property |
752 // is gone. | 726 // is gone. |
753 Node* res = ProcessArguments( | 727 Node* res = ProcessArguments( |
754 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); | 728 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); |
755 // TODO(jarin): provide real bailout id. | 729 // TODO(jarin): provide real bailout id. |
756 BuildLazyBailout(res, BailoutId::None()); | 730 PrepareFrameState(res, BailoutId::None()); |
757 Node* property_missing = NewNode(javascript()->StrictEqual(), res, | 731 Node* property_missing = NewNode(javascript()->StrictEqual(), res, |
758 jsgraph()->ZeroConstant()); | 732 jsgraph()->ZeroConstant()); |
759 { | 733 { |
760 IfBuilder is_property_missing(this); | 734 IfBuilder is_property_missing(this); |
761 is_property_missing.If(property_missing); | 735 is_property_missing.If(property_missing); |
762 is_property_missing.Then(); | 736 is_property_missing.Then(); |
763 // Inc counter and continue. | 737 // Inc counter and continue. |
764 Node* index_inc = | 738 Node* index_inc = |
765 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 739 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
766 environment()->Poke(0, index_inc); | 740 environment()->Poke(0, index_inc); |
767 // TODO(jarin): provide real bailout id. | 741 // TODO(jarin): provide real bailout id. |
768 BuildLazyBailout(index_inc, BailoutId::None()); | 742 PrepareFrameState(index_inc, BailoutId::None()); |
769 for_loop.Continue(); | 743 for_loop.Continue(); |
770 is_property_missing.Else(); | 744 is_property_missing.Else(); |
771 is_property_missing.End(); | 745 is_property_missing.End(); |
772 } | 746 } |
773 // Replace 'value' in environment. | 747 // Replace 'value' in environment. |
774 environment()->Push(res); | 748 environment()->Push(res); |
775 test_should_filter.Else(); | 749 test_should_filter.Else(); |
776 test_should_filter.End(); | 750 test_should_filter.End(); |
777 } | 751 } |
778 value = environment()->Pop(); | 752 value = environment()->Pop(); |
779 // Bind value and do loop body. | 753 // Bind value and do loop body. |
780 VisitForInAssignment(stmt->each(), value); | 754 VisitForInAssignment(stmt->each(), value); |
781 VisitIterationBody(stmt, &for_loop, 5); | 755 VisitIterationBody(stmt, &for_loop, 5); |
782 // Inc counter and continue. | 756 // Inc counter and continue. |
783 Node* index_inc = | 757 Node* index_inc = |
784 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 758 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
785 environment()->Poke(0, index_inc); | 759 environment()->Poke(0, index_inc); |
786 // TODO(jarin): provide real bailout id. | 760 // TODO(jarin): provide real bailout id. |
787 BuildLazyBailout(index_inc, BailoutId::None()); | 761 PrepareFrameState(index_inc, BailoutId::None()); |
788 for_loop.EndBody(); | 762 for_loop.EndBody(); |
789 for_loop.EndLoop(); | 763 for_loop.EndLoop(); |
790 environment()->Drop(5); | 764 environment()->Drop(5); |
791 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 765 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
792 } | 766 } |
793 have_no_properties.End(); | 767 have_no_properties.End(); |
794 } | 768 } |
795 is_null.End(); | 769 is_null.End(); |
796 } | 770 } |
797 is_undefined.End(); | 771 is_undefined.End(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 case ObjectLiteral::Property::COMPUTED: { | 899 case ObjectLiteral::Property::COMPUTED: { |
926 // It is safe to use [[Put]] here because the boilerplate already | 900 // It is safe to use [[Put]] here because the boilerplate already |
927 // contains computed properties with an uninitialized value. | 901 // contains computed properties with an uninitialized value. |
928 if (key->value()->IsInternalizedString()) { | 902 if (key->value()->IsInternalizedString()) { |
929 if (property->emit_store()) { | 903 if (property->emit_store()) { |
930 VisitForValue(property->value()); | 904 VisitForValue(property->value()); |
931 Node* value = environment()->Pop(); | 905 Node* value = environment()->Pop(); |
932 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); | 906 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); |
933 Node* store = | 907 Node* store = |
934 NewNode(javascript()->StoreNamed(name), literal, value); | 908 NewNode(javascript()->StoreNamed(name), literal, value); |
935 BuildLazyBailout(store, key->id()); | 909 PrepareFrameState(store, key->id()); |
936 } else { | 910 } else { |
937 VisitForEffect(property->value()); | 911 VisitForEffect(property->value()); |
938 } | 912 } |
939 break; | 913 break; |
940 } | 914 } |
941 environment()->Push(literal); // Duplicate receiver. | 915 environment()->Push(literal); // Duplicate receiver. |
942 VisitForValue(property->key()); | 916 VisitForValue(property->key()); |
943 VisitForValue(property->value()); | 917 VisitForValue(property->value()); |
944 Node* value = environment()->Pop(); | 918 Node* value = environment()->Pop(); |
945 Node* key = environment()->Pop(); | 919 Node* key = environment()->Pop(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 // Create nodes to evaluate all the non-constant subexpressions and to store | 991 // Create nodes to evaluate all the non-constant subexpressions and to store |
1018 // them into the newly cloned array. | 992 // them into the newly cloned array. |
1019 for (int i = 0; i < expr->values()->length(); i++) { | 993 for (int i = 0; i < expr->values()->length(); i++) { |
1020 Expression* subexpr = expr->values()->at(i); | 994 Expression* subexpr = expr->values()->at(i); |
1021 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 995 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1022 | 996 |
1023 VisitForValue(subexpr); | 997 VisitForValue(subexpr); |
1024 Node* value = environment()->Pop(); | 998 Node* value = environment()->Pop(); |
1025 Node* index = jsgraph()->Constant(i); | 999 Node* index = jsgraph()->Constant(i); |
1026 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value); | 1000 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value); |
1027 BuildLazyBailout(store, expr->GetIdForElement(i)); | 1001 PrepareFrameState(store, expr->GetIdForElement(i)); |
1028 } | 1002 } |
1029 | 1003 |
1030 environment()->Pop(); // Array literal index. | 1004 environment()->Pop(); // Array literal index. |
1031 ast_context()->ProduceValue(environment()->Pop()); | 1005 ast_context()->ProduceValue(environment()->Pop()); |
1032 } | 1006 } |
1033 | 1007 |
1034 | 1008 |
1035 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { | 1009 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { |
1036 DCHECK(expr->IsValidReferenceExpression()); | 1010 DCHECK(expr->IsValidReferenceExpression()); |
1037 | 1011 |
(...skipping 11 matching lines...) Expand all Loading... |
1049 } | 1023 } |
1050 case NAMED_PROPERTY: { | 1024 case NAMED_PROPERTY: { |
1051 environment()->Push(value); | 1025 environment()->Push(value); |
1052 VisitForValue(property->obj()); | 1026 VisitForValue(property->obj()); |
1053 Node* object = environment()->Pop(); | 1027 Node* object = environment()->Pop(); |
1054 value = environment()->Pop(); | 1028 value = environment()->Pop(); |
1055 PrintableUnique<Name> name = | 1029 PrintableUnique<Name> name = |
1056 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1030 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1057 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1031 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
1058 // TODO(jarin) Fill in the correct bailout id. | 1032 // TODO(jarin) Fill in the correct bailout id. |
1059 BuildLazyBailout(store, BailoutId::None()); | 1033 PrepareFrameState(store, BailoutId::None()); |
1060 break; | 1034 break; |
1061 } | 1035 } |
1062 case KEYED_PROPERTY: { | 1036 case KEYED_PROPERTY: { |
1063 environment()->Push(value); | 1037 environment()->Push(value); |
1064 VisitForValue(property->obj()); | 1038 VisitForValue(property->obj()); |
1065 VisitForValue(property->key()); | 1039 VisitForValue(property->key()); |
1066 Node* key = environment()->Pop(); | 1040 Node* key = environment()->Pop(); |
1067 Node* object = environment()->Pop(); | 1041 Node* object = environment()->Pop(); |
1068 value = environment()->Pop(); | 1042 value = environment()->Pop(); |
1069 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1043 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
1070 // TODO(jarin) Fill in the correct bailout id. | 1044 // TODO(jarin) Fill in the correct bailout id. |
1071 BuildLazyBailout(store, BailoutId::None()); | 1045 PrepareFrameState(store, BailoutId::None()); |
1072 break; | 1046 break; |
1073 } | 1047 } |
1074 } | 1048 } |
1075 } | 1049 } |
1076 | 1050 |
1077 | 1051 |
1078 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1052 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
1079 DCHECK(expr->target()->IsValidReferenceExpression()); | 1053 DCHECK(expr->target()->IsValidReferenceExpression()); |
1080 | 1054 |
1081 // Left-hand side can only be a property, a global or a variable slot. | 1055 // Left-hand side can only be a property, a global or a variable slot. |
(...skipping 23 matching lines...) Expand all Loading... |
1105 case VARIABLE: { | 1079 case VARIABLE: { |
1106 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1080 Variable* variable = expr->target()->AsVariableProxy()->var(); |
1107 old_value = BuildVariableLoad(variable, expr->target()->id()); | 1081 old_value = BuildVariableLoad(variable, expr->target()->id()); |
1108 break; | 1082 break; |
1109 } | 1083 } |
1110 case NAMED_PROPERTY: { | 1084 case NAMED_PROPERTY: { |
1111 Node* object = environment()->Top(); | 1085 Node* object = environment()->Top(); |
1112 PrintableUnique<Name> name = | 1086 PrintableUnique<Name> name = |
1113 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1087 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1114 old_value = NewNode(javascript()->LoadNamed(name), object); | 1088 old_value = NewNode(javascript()->LoadNamed(name), object); |
1115 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1089 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
1116 break; | 1090 break; |
1117 } | 1091 } |
1118 case KEYED_PROPERTY: { | 1092 case KEYED_PROPERTY: { |
1119 Node* key = environment()->Top(); | 1093 Node* key = environment()->Top(); |
1120 Node* object = environment()->Peek(1); | 1094 Node* object = environment()->Peek(1); |
1121 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1095 old_value = NewNode(javascript()->LoadProperty(), object, key); |
1122 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1096 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
1123 break; | 1097 break; |
1124 } | 1098 } |
1125 } | 1099 } |
1126 environment()->Push(old_value); | 1100 environment()->Push(old_value); |
1127 VisitForValue(expr->value()); | 1101 VisitForValue(expr->value()); |
1128 Node* right = environment()->Pop(); | 1102 Node* right = environment()->Pop(); |
1129 Node* left = environment()->Pop(); | 1103 Node* left = environment()->Pop(); |
1130 Node* value = BuildBinaryOp(left, right, expr->binary_op()); | 1104 Node* value = BuildBinaryOp(left, right, expr->binary_op()); |
1131 environment()->Push(value); | 1105 environment()->Push(value); |
1132 BuildLazyBailout(value, expr->binary_operation()->id()); | 1106 PrepareFrameState(value, expr->binary_operation()->id()); |
1133 } else { | 1107 } else { |
1134 VisitForValue(expr->value()); | 1108 VisitForValue(expr->value()); |
1135 } | 1109 } |
1136 | 1110 |
1137 // Store the value. | 1111 // Store the value. |
1138 Node* value = environment()->Pop(); | 1112 Node* value = environment()->Pop(); |
1139 switch (assign_type) { | 1113 switch (assign_type) { |
1140 case VARIABLE: { | 1114 case VARIABLE: { |
1141 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1115 Variable* variable = expr->target()->AsVariableProxy()->var(); |
1142 BuildVariableAssignment(variable, value, expr->op(), | 1116 BuildVariableAssignment(variable, value, expr->op(), |
1143 expr->AssignmentId()); | 1117 expr->AssignmentId()); |
1144 break; | 1118 break; |
1145 } | 1119 } |
1146 case NAMED_PROPERTY: { | 1120 case NAMED_PROPERTY: { |
1147 Node* object = environment()->Pop(); | 1121 Node* object = environment()->Pop(); |
1148 PrintableUnique<Name> name = | 1122 PrintableUnique<Name> name = |
1149 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1123 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1150 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1124 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
1151 BuildLazyBailout(store, expr->AssignmentId()); | 1125 PrepareFrameState(store, expr->AssignmentId()); |
1152 break; | 1126 break; |
1153 } | 1127 } |
1154 case KEYED_PROPERTY: { | 1128 case KEYED_PROPERTY: { |
1155 Node* key = environment()->Pop(); | 1129 Node* key = environment()->Pop(); |
1156 Node* object = environment()->Pop(); | 1130 Node* object = environment()->Pop(); |
1157 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1131 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
1158 BuildLazyBailout(store, expr->AssignmentId()); | 1132 PrepareFrameState(store, expr->AssignmentId()); |
1159 break; | 1133 break; |
1160 } | 1134 } |
1161 } | 1135 } |
1162 | 1136 |
1163 ast_context()->ProduceValue(value); | 1137 ast_context()->ProduceValue(value); |
1164 } | 1138 } |
1165 | 1139 |
1166 | 1140 |
1167 void AstGraphBuilder::VisitYield(Yield* expr) { | 1141 void AstGraphBuilder::VisitYield(Yield* expr) { |
1168 VisitForValue(expr->generator_object()); | 1142 VisitForValue(expr->generator_object()); |
(...skipping 22 matching lines...) Expand all Loading... |
1191 PrintableUnique<Name> name = | 1165 PrintableUnique<Name> name = |
1192 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); | 1166 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); |
1193 value = NewNode(javascript()->LoadNamed(name), object); | 1167 value = NewNode(javascript()->LoadNamed(name), object); |
1194 } else { | 1168 } else { |
1195 VisitForValue(expr->obj()); | 1169 VisitForValue(expr->obj()); |
1196 VisitForValue(expr->key()); | 1170 VisitForValue(expr->key()); |
1197 Node* key = environment()->Pop(); | 1171 Node* key = environment()->Pop(); |
1198 Node* object = environment()->Pop(); | 1172 Node* object = environment()->Pop(); |
1199 value = NewNode(javascript()->LoadProperty(), object, key); | 1173 value = NewNode(javascript()->LoadProperty(), object, key); |
1200 } | 1174 } |
1201 ast_context()->ProduceValueWithLazyBailout(value); | 1175 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1176 ast_context()->ProduceValue(value); |
1202 } | 1177 } |
1203 | 1178 |
1204 | 1179 |
1205 void AstGraphBuilder::VisitCall(Call* expr) { | 1180 void AstGraphBuilder::VisitCall(Call* expr) { |
1206 Expression* callee = expr->expression(); | 1181 Expression* callee = expr->expression(); |
1207 Call::CallType call_type = expr->GetCallType(isolate()); | 1182 Call::CallType call_type = expr->GetCallType(isolate()); |
1208 | 1183 |
1209 // Prepare the callee and the receiver to the function call. This depends on | 1184 // Prepare the callee and the receiver to the function call. This depends on |
1210 // the semantics of the underlying call type. | 1185 // the semantics of the underlying call type. |
1211 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1186 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
(...skipping 23 matching lines...) Expand all Loading... |
1235 Node* object = environment()->Top(); | 1210 Node* object = environment()->Top(); |
1236 if (property->key()->IsPropertyName()) { | 1211 if (property->key()->IsPropertyName()) { |
1237 PrintableUnique<Name> name = | 1212 PrintableUnique<Name> name = |
1238 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1213 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1239 callee_value = NewNode(javascript()->LoadNamed(name), object); | 1214 callee_value = NewNode(javascript()->LoadNamed(name), object); |
1240 } else { | 1215 } else { |
1241 VisitForValue(property->key()); | 1216 VisitForValue(property->key()); |
1242 Node* key = environment()->Pop(); | 1217 Node* key = environment()->Pop(); |
1243 callee_value = NewNode(javascript()->LoadProperty(), object, key); | 1218 callee_value = NewNode(javascript()->LoadProperty(), object, key); |
1244 } | 1219 } |
1245 BuildLazyBailoutWithPushedNode(callee_value, property->LoadId()); | 1220 PrepareFrameState(callee_value, property->LoadId(), PUSH_OUTPUT); |
1246 receiver_value = environment()->Pop(); | 1221 receiver_value = environment()->Pop(); |
1247 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an | 1222 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an |
1248 // object for sloppy callees. This could also be modeled explicitly here, | 1223 // object for sloppy callees. This could also be modeled explicitly here, |
1249 // thereby obsoleting the need for a flag to the call operator. | 1224 // thereby obsoleting the need for a flag to the call operator. |
1250 flags = CALL_AS_METHOD; | 1225 flags = CALL_AS_METHOD; |
1251 break; | 1226 break; |
1252 } | 1227 } |
1253 case Call::POSSIBLY_EVAL_CALL: | 1228 case Call::POSSIBLY_EVAL_CALL: |
1254 possibly_eval = true; | 1229 possibly_eval = true; |
1255 // Fall through. | 1230 // Fall through. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 Node* new_receiver = NewNode(common()->Projection(1), pair); | 1265 Node* new_receiver = NewNode(common()->Projection(1), pair); |
1291 | 1266 |
1292 // Patch callee and receiver on the environment. | 1267 // Patch callee and receiver on the environment. |
1293 environment()->Poke(arg_count + 1, new_callee); | 1268 environment()->Poke(arg_count + 1, new_callee); |
1294 environment()->Poke(arg_count + 0, new_receiver); | 1269 environment()->Poke(arg_count + 0, new_receiver); |
1295 } | 1270 } |
1296 | 1271 |
1297 // Create node to perform the function call. | 1272 // Create node to perform the function call. |
1298 Operator* call = javascript()->Call(args->length() + 2, flags); | 1273 Operator* call = javascript()->Call(args->length() + 2, flags); |
1299 Node* value = ProcessArguments(call, args->length() + 2); | 1274 Node* value = ProcessArguments(call, args->length() + 2); |
1300 ast_context()->ProduceValueWithLazyBailout(value); | 1275 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1276 ast_context()->ProduceValue(value); |
1301 } | 1277 } |
1302 | 1278 |
1303 | 1279 |
1304 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 1280 void AstGraphBuilder::VisitCallNew(CallNew* expr) { |
1305 VisitForValue(expr->expression()); | 1281 VisitForValue(expr->expression()); |
1306 | 1282 |
1307 // Evaluate all arguments to the construct call. | 1283 // Evaluate all arguments to the construct call. |
1308 ZoneList<Expression*>* args = expr->arguments(); | 1284 ZoneList<Expression*>* args = expr->arguments(); |
1309 VisitForValues(args); | 1285 VisitForValues(args); |
1310 | 1286 |
1311 // Create node to perform the construct call. | 1287 // Create node to perform the construct call. |
1312 Operator* call = javascript()->CallNew(args->length() + 1); | 1288 Operator* call = javascript()->CallNew(args->length() + 1); |
1313 Node* value = ProcessArguments(call, args->length() + 1); | 1289 Node* value = ProcessArguments(call, args->length() + 1); |
1314 ast_context()->ProduceValueWithLazyBailout(value); | 1290 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1291 ast_context()->ProduceValue(value); |
1315 } | 1292 } |
1316 | 1293 |
1317 | 1294 |
1318 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { | 1295 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { |
1319 Handle<String> name = expr->name(); | 1296 Handle<String> name = expr->name(); |
1320 | 1297 |
1321 // The callee and the receiver both have to be pushed onto the operand stack | 1298 // The callee and the receiver both have to be pushed onto the operand stack |
1322 // before arguments are being evaluated. | 1299 // before arguments are being evaluated. |
1323 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; | 1300 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; |
1324 Node* receiver_value = BuildLoadBuiltinsObject(); | 1301 Node* receiver_value = BuildLoadBuiltinsObject(); |
1325 PrintableUnique<String> unique = MakeUnique(name); | 1302 PrintableUnique<String> unique = MakeUnique(name); |
1326 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); | 1303 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); |
1327 environment()->Push(callee_value); | 1304 environment()->Push(callee_value); |
1328 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft | 1305 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft |
1329 // refuses to optimize functions with jsruntime calls). | 1306 // refuses to optimize functions with jsruntime calls). |
1330 BuildLazyBailout(callee_value, BailoutId::None()); | 1307 PrepareFrameState(callee_value, BailoutId::None()); |
1331 environment()->Push(receiver_value); | 1308 environment()->Push(receiver_value); |
1332 | 1309 |
1333 // Evaluate all arguments to the JS runtime call. | 1310 // Evaluate all arguments to the JS runtime call. |
1334 ZoneList<Expression*>* args = expr->arguments(); | 1311 ZoneList<Expression*>* args = expr->arguments(); |
1335 VisitForValues(args); | 1312 VisitForValues(args); |
1336 | 1313 |
1337 // Create node to perform the JS runtime call. | 1314 // Create node to perform the JS runtime call. |
1338 Operator* call = javascript()->Call(args->length() + 2, flags); | 1315 Operator* call = javascript()->Call(args->length() + 2, flags); |
1339 Node* value = ProcessArguments(call, args->length() + 2); | 1316 Node* value = ProcessArguments(call, args->length() + 2); |
1340 ast_context()->ProduceValueWithLazyBailout(value); | 1317 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1318 ast_context()->ProduceValue(value); |
1341 } | 1319 } |
1342 | 1320 |
1343 | 1321 |
1344 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 1322 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
1345 const Runtime::Function* function = expr->function(); | 1323 const Runtime::Function* function = expr->function(); |
1346 | 1324 |
1347 // Handle calls to runtime functions implemented in JavaScript separately as | 1325 // Handle calls to runtime functions implemented in JavaScript separately as |
1348 // the call follows JavaScript ABI and the callee is statically unknown. | 1326 // the call follows JavaScript ABI and the callee is statically unknown. |
1349 if (expr->is_jsruntime()) { | 1327 if (expr->is_jsruntime()) { |
1350 DCHECK(function == NULL && expr->name()->length() > 0); | 1328 DCHECK(function == NULL && expr->name()->length() > 0); |
1351 return VisitCallJSRuntime(expr); | 1329 return VisitCallJSRuntime(expr); |
1352 } | 1330 } |
1353 | 1331 |
1354 // Evaluate all arguments to the runtime call. | 1332 // Evaluate all arguments to the runtime call. |
1355 ZoneList<Expression*>* args = expr->arguments(); | 1333 ZoneList<Expression*>* args = expr->arguments(); |
1356 VisitForValues(args); | 1334 VisitForValues(args); |
1357 | 1335 |
1358 // Create node to perform the runtime call. | 1336 // Create node to perform the runtime call. |
1359 Runtime::FunctionId functionId = function->function_id; | 1337 Runtime::FunctionId functionId = function->function_id; |
1360 Operator* call = javascript()->Runtime(functionId, args->length()); | 1338 Operator* call = javascript()->Runtime(functionId, args->length()); |
1361 Node* value = ProcessArguments(call, args->length()); | 1339 Node* value = ProcessArguments(call, args->length()); |
1362 ast_context()->ProduceValueWithLazyBailout(value); | 1340 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1341 ast_context()->ProduceValue(value); |
1363 } | 1342 } |
1364 | 1343 |
1365 | 1344 |
1366 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 1345 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
1367 switch (expr->op()) { | 1346 switch (expr->op()) { |
1368 case Token::DELETE: | 1347 case Token::DELETE: |
1369 return VisitDelete(expr); | 1348 return VisitDelete(expr); |
1370 case Token::VOID: | 1349 case Token::VOID: |
1371 return VisitVoid(expr); | 1350 return VisitVoid(expr); |
1372 case Token::TYPEOF: | 1351 case Token::TYPEOF: |
(...skipping 26 matching lines...) Expand all Loading... |
1399 old_value = BuildVariableLoad(variable, expr->expression()->id()); | 1378 old_value = BuildVariableLoad(variable, expr->expression()->id()); |
1400 stack_depth = 0; | 1379 stack_depth = 0; |
1401 break; | 1380 break; |
1402 } | 1381 } |
1403 case NAMED_PROPERTY: { | 1382 case NAMED_PROPERTY: { |
1404 VisitForValue(property->obj()); | 1383 VisitForValue(property->obj()); |
1405 Node* object = environment()->Top(); | 1384 Node* object = environment()->Top(); |
1406 PrintableUnique<Name> name = | 1385 PrintableUnique<Name> name = |
1407 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1386 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1408 old_value = NewNode(javascript()->LoadNamed(name), object); | 1387 old_value = NewNode(javascript()->LoadNamed(name), object); |
1409 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1388 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
1410 stack_depth = 1; | 1389 stack_depth = 1; |
1411 break; | 1390 break; |
1412 } | 1391 } |
1413 case KEYED_PROPERTY: { | 1392 case KEYED_PROPERTY: { |
1414 VisitForValue(property->obj()); | 1393 VisitForValue(property->obj()); |
1415 VisitForValue(property->key()); | 1394 VisitForValue(property->key()); |
1416 Node* key = environment()->Top(); | 1395 Node* key = environment()->Top(); |
1417 Node* object = environment()->Peek(1); | 1396 Node* object = environment()->Peek(1); |
1418 old_value = NewNode(javascript()->LoadProperty(), object, key); | 1397 old_value = NewNode(javascript()->LoadProperty(), object, key); |
1419 BuildLazyBailoutWithPushedNode(old_value, property->LoadId()); | 1398 PrepareFrameState(old_value, property->LoadId(), PUSH_OUTPUT); |
1420 stack_depth = 2; | 1399 stack_depth = 2; |
1421 break; | 1400 break; |
1422 } | 1401 } |
1423 } | 1402 } |
1424 | 1403 |
1425 // Convert old value into a number. | 1404 // Convert old value into a number. |
1426 old_value = NewNode(javascript()->ToNumber(), old_value); | 1405 old_value = NewNode(javascript()->ToNumber(), old_value); |
1427 | 1406 |
1428 // Save result for postfix expressions at correct stack depth. | 1407 // Save result for postfix expressions at correct stack depth. |
1429 if (is_postfix) environment()->Poke(stack_depth, old_value); | 1408 if (is_postfix) environment()->Poke(stack_depth, old_value); |
1430 | 1409 |
1431 // Create node to perform +1/-1 operation. | 1410 // Create node to perform +1/-1 operation. |
1432 Node* value = | 1411 Node* value = |
1433 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 1412 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
1434 // TODO(jarin) Insert proper bailout id here (will need to change | 1413 // TODO(jarin) Insert proper bailout id here (will need to change |
1435 // full code generator). | 1414 // full code generator). |
1436 BuildLazyBailout(value, BailoutId::None()); | 1415 PrepareFrameState(value, BailoutId::None()); |
1437 | 1416 |
1438 // Store the value. | 1417 // Store the value. |
1439 switch (assign_type) { | 1418 switch (assign_type) { |
1440 case VARIABLE: { | 1419 case VARIABLE: { |
1441 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 1420 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
1442 BuildVariableAssignment(variable, value, expr->op(), | 1421 BuildVariableAssignment(variable, value, expr->op(), |
1443 expr->AssignmentId()); | 1422 expr->AssignmentId()); |
1444 break; | 1423 break; |
1445 } | 1424 } |
1446 case NAMED_PROPERTY: { | 1425 case NAMED_PROPERTY: { |
1447 Node* object = environment()->Pop(); | 1426 Node* object = environment()->Pop(); |
1448 PrintableUnique<Name> name = | 1427 PrintableUnique<Name> name = |
1449 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); | 1428 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); |
1450 Node* store = NewNode(javascript()->StoreNamed(name), object, value); | 1429 Node* store = NewNode(javascript()->StoreNamed(name), object, value); |
1451 BuildLazyBailout(store, expr->AssignmentId()); | 1430 PrepareFrameState(store, expr->AssignmentId()); |
1452 break; | 1431 break; |
1453 } | 1432 } |
1454 case KEYED_PROPERTY: { | 1433 case KEYED_PROPERTY: { |
1455 Node* key = environment()->Pop(); | 1434 Node* key = environment()->Pop(); |
1456 Node* object = environment()->Pop(); | 1435 Node* object = environment()->Pop(); |
1457 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); | 1436 Node* store = NewNode(javascript()->StoreProperty(), object, key, value); |
1458 BuildLazyBailout(store, expr->AssignmentId()); | 1437 PrepareFrameState(store, expr->AssignmentId()); |
1459 break; | 1438 break; |
1460 } | 1439 } |
1461 } | 1440 } |
1462 | 1441 |
1463 // Restore old value for postfix expressions. | 1442 // Restore old value for postfix expressions. |
1464 if (is_postfix) value = environment()->Pop(); | 1443 if (is_postfix) value = environment()->Pop(); |
1465 | 1444 |
1466 ast_context()->ProduceValue(value); | 1445 ast_context()->ProduceValue(value); |
1467 } | 1446 } |
1468 | 1447 |
1469 | 1448 |
1470 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 1449 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
1471 switch (expr->op()) { | 1450 switch (expr->op()) { |
1472 case Token::COMMA: | 1451 case Token::COMMA: |
1473 return VisitComma(expr); | 1452 return VisitComma(expr); |
1474 case Token::OR: | 1453 case Token::OR: |
1475 case Token::AND: | 1454 case Token::AND: |
1476 return VisitLogicalExpression(expr); | 1455 return VisitLogicalExpression(expr); |
1477 default: { | 1456 default: { |
1478 VisitForValue(expr->left()); | 1457 VisitForValue(expr->left()); |
1479 VisitForValue(expr->right()); | 1458 VisitForValue(expr->right()); |
1480 Node* right = environment()->Pop(); | 1459 Node* right = environment()->Pop(); |
1481 Node* left = environment()->Pop(); | 1460 Node* left = environment()->Pop(); |
1482 Node* value = BuildBinaryOp(left, right, expr->op()); | 1461 Node* value = BuildBinaryOp(left, right, expr->op()); |
1483 ast_context()->ProduceValueWithLazyBailout(value); | 1462 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
| 1463 ast_context()->ProduceValue(value); |
1484 } | 1464 } |
1485 } | 1465 } |
1486 } | 1466 } |
1487 | 1467 |
1488 | 1468 |
1489 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 1469 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
1490 Operator* op; | 1470 Operator* op; |
1491 switch (expr->op()) { | 1471 switch (expr->op()) { |
1492 case Token::EQ: | 1472 case Token::EQ: |
1493 op = javascript()->Equal(); | 1473 op = javascript()->Equal(); |
(...skipping 29 matching lines...) Expand all Loading... |
1523 op = NULL; | 1503 op = NULL; |
1524 UNREACHABLE(); | 1504 UNREACHABLE(); |
1525 } | 1505 } |
1526 VisitForValue(expr->left()); | 1506 VisitForValue(expr->left()); |
1527 VisitForValue(expr->right()); | 1507 VisitForValue(expr->right()); |
1528 Node* right = environment()->Pop(); | 1508 Node* right = environment()->Pop(); |
1529 Node* left = environment()->Pop(); | 1509 Node* left = environment()->Pop(); |
1530 Node* value = NewNode(op, left, right); | 1510 Node* value = NewNode(op, left, right); |
1531 ast_context()->ProduceValue(value); | 1511 ast_context()->ProduceValue(value); |
1532 | 1512 |
1533 BuildLazyBailout(value, expr->id()); | 1513 PrepareFrameState(value, expr->id()); |
1534 } | 1514 } |
1535 | 1515 |
1536 | 1516 |
1537 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 1517 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
1538 Node* value = GetFunctionClosure(); | 1518 Node* value = GetFunctionClosure(); |
1539 ast_context()->ProduceValue(value); | 1519 ast_context()->ProduceValue(value); |
1540 } | 1520 } |
1541 | 1521 |
1542 | 1522 |
1543 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } | 1523 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 ContextualMode contextual_mode) { | 1733 ContextualMode contextual_mode) { |
1754 Node* the_hole = jsgraph()->TheHoleConstant(); | 1734 Node* the_hole = jsgraph()->TheHoleConstant(); |
1755 VariableMode mode = variable->mode(); | 1735 VariableMode mode = variable->mode(); |
1756 switch (variable->location()) { | 1736 switch (variable->location()) { |
1757 case Variable::UNALLOCATED: { | 1737 case Variable::UNALLOCATED: { |
1758 // Global var, const, or let variable. | 1738 // Global var, const, or let variable. |
1759 Node* global = BuildLoadGlobalObject(); | 1739 Node* global = BuildLoadGlobalObject(); |
1760 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1740 PrintableUnique<Name> name = MakeUnique(variable->name()); |
1761 Operator* op = javascript()->LoadNamed(name, contextual_mode); | 1741 Operator* op = javascript()->LoadNamed(name, contextual_mode); |
1762 Node* node = NewNode(op, global); | 1742 Node* node = NewNode(op, global); |
1763 BuildLazyBailoutWithPushedNode(node, bailout_id); | 1743 PrepareFrameState(node, bailout_id, PUSH_OUTPUT); |
1764 return node; | 1744 return node; |
1765 } | 1745 } |
1766 case Variable::PARAMETER: | 1746 case Variable::PARAMETER: |
1767 case Variable::LOCAL: { | 1747 case Variable::LOCAL: { |
1768 // Local var, const, or let variable. | 1748 // Local var, const, or let variable. |
1769 Node* value = environment()->Lookup(variable); | 1749 Node* value = environment()->Lookup(variable); |
1770 if (mode == CONST_LEGACY) { | 1750 if (mode == CONST_LEGACY) { |
1771 // Perform check for uninitialized legacy const variables. | 1751 // Perform check for uninitialized legacy const variables. |
1772 if (value->op() == the_hole->op()) { | 1752 if (value->op() == the_hole->op()) { |
1773 value = jsgraph()->UndefinedConstant(); | 1753 value = jsgraph()->UndefinedConstant(); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1854 BailoutId bailout_id) { | 1834 BailoutId bailout_id) { |
1855 Node* the_hole = jsgraph()->TheHoleConstant(); | 1835 Node* the_hole = jsgraph()->TheHoleConstant(); |
1856 VariableMode mode = variable->mode(); | 1836 VariableMode mode = variable->mode(); |
1857 switch (variable->location()) { | 1837 switch (variable->location()) { |
1858 case Variable::UNALLOCATED: { | 1838 case Variable::UNALLOCATED: { |
1859 // Global var, const, or let variable. | 1839 // Global var, const, or let variable. |
1860 Node* global = BuildLoadGlobalObject(); | 1840 Node* global = BuildLoadGlobalObject(); |
1861 PrintableUnique<Name> name = MakeUnique(variable->name()); | 1841 PrintableUnique<Name> name = MakeUnique(variable->name()); |
1862 Operator* op = javascript()->StoreNamed(name); | 1842 Operator* op = javascript()->StoreNamed(name); |
1863 Node* store = NewNode(op, global, value); | 1843 Node* store = NewNode(op, global, value); |
1864 BuildLazyBailout(store, bailout_id); | 1844 PrepareFrameState(store, bailout_id); |
1865 return store; | 1845 return store; |
1866 } | 1846 } |
1867 case Variable::PARAMETER: | 1847 case Variable::PARAMETER: |
1868 case Variable::LOCAL: | 1848 case Variable::LOCAL: |
1869 // Local var, const, or let variable. | 1849 // Local var, const, or let variable. |
1870 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 1850 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
1871 // Perform an initialization check for legacy const variables. | 1851 // Perform an initialization check for legacy const variables. |
1872 Node* current = environment()->Lookup(variable); | 1852 Node* current = environment()->Lookup(variable); |
1873 if (current->op() != the_hole->op()) { | 1853 if (current->op() != the_hole->op()) { |
1874 value = BuildHoleCheckSilent(current, value, current); | 1854 value = BuildHoleCheckSilent(current, value, current); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 js_op = javascript()->Modulus(); | 1986 js_op = javascript()->Modulus(); |
2007 break; | 1987 break; |
2008 default: | 1988 default: |
2009 UNREACHABLE(); | 1989 UNREACHABLE(); |
2010 js_op = NULL; | 1990 js_op = NULL; |
2011 } | 1991 } |
2012 return NewNode(js_op, left, right); | 1992 return NewNode(js_op, left, right); |
2013 } | 1993 } |
2014 | 1994 |
2015 | 1995 |
2016 void AstGraphBuilder::BuildLazyBailout(Node* node, BailoutId ast_id) { | 1996 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id, |
| 1997 OutputFrameStateCombine combine) { |
2017 if (OperatorProperties::CanLazilyDeoptimize(node->op())) { | 1998 if (OperatorProperties::CanLazilyDeoptimize(node->op())) { |
2018 // The deopting node should have an outgoing control dependency. | 1999 // The deopting node should have an outgoing control dependency. |
2019 DCHECK(environment()->GetControlDependency() == node); | 2000 DCHECK(environment()->GetControlDependency() == node); |
2020 | 2001 |
| 2002 if (combine == PUSH_OUTPUT) { |
| 2003 environment()->Push(node); |
| 2004 } |
| 2005 |
2021 StructuredGraphBuilder::Environment* continuation_env = environment(); | 2006 StructuredGraphBuilder::Environment* continuation_env = environment(); |
2022 // Create environment for the deoptimization block, and build the block. | 2007 // Create environment for the deoptimization block, and build the block. |
2023 StructuredGraphBuilder::Environment* deopt_env = | 2008 StructuredGraphBuilder::Environment* deopt_env = |
2024 CopyEnvironment(continuation_env); | 2009 CopyEnvironment(continuation_env); |
2025 set_environment(deopt_env); | 2010 set_environment(deopt_env); |
2026 | 2011 |
2027 NewNode(common()->LazyDeoptimization()); | 2012 NewNode(common()->LazyDeoptimization()); |
2028 | 2013 |
2029 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty | 2014 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty |
2030 // deopt block and make sure there is no patch entry for this (so | 2015 // deopt block and make sure there is no patch entry for this (so |
2031 // that the deoptimizer dies when trying to deoptimize here). | 2016 // that the deoptimizer dies when trying to deoptimize here). |
2032 | 2017 |
2033 Node* state_node = environment()->Checkpoint(ast_id); | 2018 Node* state_node = environment()->Checkpoint(ast_id); |
2034 | 2019 |
2035 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); | 2020 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); |
2036 | 2021 |
2037 UpdateControlDependencyToLeaveFunction(deoptimize_node); | 2022 UpdateControlDependencyToLeaveFunction(deoptimize_node); |
2038 | 2023 |
2039 // Continue with the original environment. | 2024 // Continue with the original environment. |
2040 set_environment(continuation_env); | 2025 set_environment(continuation_env); |
2041 | 2026 |
| 2027 if (combine == PUSH_OUTPUT) { |
| 2028 environment()->Pop(); |
| 2029 } |
| 2030 |
2042 NewNode(common()->Continuation()); | 2031 NewNode(common()->Continuation()); |
2043 } | 2032 } |
2044 } | 2033 } |
2045 | 2034 |
2046 | |
2047 void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node, | |
2048 BailoutId ast_id) { | |
2049 environment()->Push(node); | |
2050 BuildLazyBailout(node, ast_id); | |
2051 environment()->Pop(); | |
2052 } | |
2053 } | 2035 } |
2054 } | 2036 } |
2055 } // namespace v8::internal::compiler | 2037 } // namespace v8::internal::compiler |
OLD | NEW |