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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 453383002: More lazy deoptimization in Turbofan (binops, loads/stores) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Attempt to fix the 64-bit Windows build Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/code-generator.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/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
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 : kind_(kind), owner_(own), outer_(own->ast_context()) { 242 BailoutId bailout_id)
243 : bailout_id_(bailout_id),
244 kind_(kind),
245 owner_(own),
246 outer_(own->ast_context()) {
243 owner()->set_ast_context(this); // Push. 247 owner()->set_ast_context(this); // Push.
244 #ifdef DEBUG 248 #ifdef DEBUG
245 original_height_ = environment()->stack_height(); 249 original_height_ = environment()->stack_height();
246 #endif 250 #endif
247 } 251 }
248 252
249 253
250 AstGraphBuilder::AstContext::~AstContext() { 254 AstGraphBuilder::AstContext::~AstContext() {
251 owner()->set_ast_context(outer_); // Pop. 255 owner()->set_ast_context(outer_); // Pop.
252 } 256 }
253 257
254 258
255 AstGraphBuilder::AstEffectContext::~AstEffectContext() { 259 AstGraphBuilder::AstEffectContext::~AstEffectContext() {
256 DCHECK(environment()->stack_height() == original_height_); 260 DCHECK(environment()->stack_height() == original_height_);
257 } 261 }
258 262
259 263
260 AstGraphBuilder::AstValueContext::~AstValueContext() { 264 AstGraphBuilder::AstValueContext::~AstValueContext() {
261 DCHECK(environment()->stack_height() == original_height_ + 1); 265 DCHECK(environment()->stack_height() == original_height_ + 1);
262 } 266 }
263 267
264 268
265 AstGraphBuilder::AstTestContext::~AstTestContext() { 269 AstGraphBuilder::AstTestContext::~AstTestContext() {
266 DCHECK(environment()->stack_height() == original_height_ + 1); 270 DCHECK(environment()->stack_height() == original_height_ + 1);
267 } 271 }
268 272
269 273
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
270 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) { 296 void AstGraphBuilder::AstEffectContext::ProduceValue(Node* value) {
271 // The value is ignored. 297 // The value is ignored.
272 } 298 }
273 299
274 300
275 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) { 301 void AstGraphBuilder::AstValueContext::ProduceValue(Node* value) {
276 environment()->Push(value); 302 environment()->Push(value);
277 } 303 }
278 304
279 305
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 352
327 353
328 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) { 354 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
329 for (int i = 0; i < exprs->length(); ++i) { 355 for (int i = 0; i < exprs->length(); ++i) {
330 VisitForValue(exprs->at(i)); 356 VisitForValue(exprs->at(i));
331 } 357 }
332 } 358 }
333 359
334 360
335 void AstGraphBuilder::VisitForValue(Expression* expr) { 361 void AstGraphBuilder::VisitForValue(Expression* expr) {
336 AstValueContext for_value(this); 362 AstValueContext for_value(this, expr->id());
337 if (!HasStackOverflow()) { 363 if (!HasStackOverflow()) {
338 expr->Accept(this); 364 expr->Accept(this);
339 } 365 }
340 } 366 }
341 367
342 368
343 void AstGraphBuilder::VisitForEffect(Expression* expr) { 369 void AstGraphBuilder::VisitForEffect(Expression* expr) {
344 AstEffectContext for_effect(this); 370 AstEffectContext for_effect(this, expr->id());
345 if (!HasStackOverflow()) { 371 if (!HasStackOverflow()) {
346 expr->Accept(this); 372 expr->Accept(this);
347 } 373 }
348 } 374 }
349 375
350 376
351 void AstGraphBuilder::VisitForTest(Expression* expr) { 377 void AstGraphBuilder::VisitForTest(Expression* expr) {
352 AstTestContext for_condition(this); 378 AstTestContext for_condition(this, expr->id());
353 if (!HasStackOverflow()) { 379 if (!HasStackOverflow()) {
354 expr->Accept(this); 380 expr->Accept(this);
355 } 381 }
356 } 382 }
357 383
358 384
359 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) { 385 void AstGraphBuilder::VisitVariableDeclaration(VariableDeclaration* decl) {
360 Variable* variable = decl->proxy()->var(); 386 Variable* variable = decl->proxy()->var();
361 VariableMode mode = decl->mode(); 387 VariableMode mode = decl->mode();
362 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET; 388 bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 environment()->Push(cache_array); 705 environment()->Push(cache_array);
680 environment()->Push(cache_length); 706 environment()->Push(cache_length);
681 environment()->Push(jsgraph()->ZeroConstant()); 707 environment()->Push(jsgraph()->ZeroConstant());
682 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 708 // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
683 LoopBuilder for_loop(this); 709 LoopBuilder for_loop(this);
684 for_loop.BeginLoop(); 710 for_loop.BeginLoop();
685 // Check loop termination condition. 711 // Check loop termination condition.
686 Node* index = environment()->Peek(0); 712 Node* index = environment()->Peek(0);
687 Node* exit_cond = 713 Node* exit_cond =
688 NewNode(javascript()->LessThan(), index, cache_length); 714 NewNode(javascript()->LessThan(), index, cache_length);
715 // TODO(jarin): provide real bailout id.
716 BuildLazyBailout(exit_cond, BailoutId::None());
689 for_loop.BreakUnless(exit_cond); 717 for_loop.BreakUnless(exit_cond);
690 // TODO(dcarney): this runtime call should be a handful of 718 // TODO(dcarney): this runtime call should be a handful of
691 // simplified instructions that 719 // simplified instructions that
692 // basically produce 720 // basically produce
693 // value = array[index] 721 // value = array[index]
694 environment()->Push(obj); 722 environment()->Push(obj);
695 environment()->Push(cache_array); 723 environment()->Push(cache_array);
696 environment()->Push(cache_type); 724 environment()->Push(cache_type);
697 environment()->Push(index); 725 environment()->Push(index);
698 Node* pair = 726 Node* pair =
(...skipping 18 matching lines...) Expand all
717 // Callee. 745 // Callee.
718 environment()->Push(jsgraph()->HeapConstant(function)); 746 environment()->Push(jsgraph()->HeapConstant(function));
719 // Receiver. 747 // Receiver.
720 environment()->Push(obj); 748 environment()->Push(obj);
721 // Args. 749 // Args.
722 environment()->Push(value); 750 environment()->Push(value);
723 // result is either the string key or Smi(0) indicating the property 751 // result is either the string key or Smi(0) indicating the property
724 // is gone. 752 // is gone.
725 Node* res = ProcessArguments( 753 Node* res = ProcessArguments(
726 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3); 754 javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3);
755 // TODO(jarin): provide real bailout id.
756 BuildLazyBailout(res, BailoutId::None());
727 Node* property_missing = NewNode(javascript()->StrictEqual(), res, 757 Node* property_missing = NewNode(javascript()->StrictEqual(), res,
728 jsgraph()->ZeroConstant()); 758 jsgraph()->ZeroConstant());
729 { 759 {
730 IfBuilder is_property_missing(this); 760 IfBuilder is_property_missing(this);
731 is_property_missing.If(property_missing); 761 is_property_missing.If(property_missing);
732 is_property_missing.Then(); 762 is_property_missing.Then();
733 // Inc counter and continue. 763 // Inc counter and continue.
734 Node* index_inc = 764 Node* index_inc =
735 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); 765 NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
736 environment()->Poke(0, index_inc); 766 environment()->Poke(0, index_inc);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 compare_if.Then(); 852 compare_if.Then();
823 Visit(expr->then_expression()); 853 Visit(expr->then_expression());
824 compare_if.Else(); 854 compare_if.Else();
825 Visit(expr->else_expression()); 855 Visit(expr->else_expression());
826 compare_if.End(); 856 compare_if.End();
827 ast_context()->ReplaceValue(); 857 ast_context()->ReplaceValue();
828 } 858 }
829 859
830 860
831 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 861 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
832 Node* value = BuildVariableLoad(expr->var()); 862 Node* value = BuildVariableLoad(expr->var(), expr->id());
833 ast_context()->ProduceValue(value); 863 ast_context()->ProduceValue(value);
834 } 864 }
835 865
836 866
837 void AstGraphBuilder::VisitLiteral(Literal* expr) { 867 void AstGraphBuilder::VisitLiteral(Literal* expr) {
838 Node* value = jsgraph()->Constant(expr->value()); 868 Node* value = jsgraph()->Constant(expr->value());
839 ast_context()->ProduceValue(value); 869 ast_context()->ProduceValue(value);
840 } 870 }
841 871
842 872
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 919 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
890 // Fall through. 920 // Fall through.
891 case ObjectLiteral::Property::COMPUTED: { 921 case ObjectLiteral::Property::COMPUTED: {
892 // It is safe to use [[Put]] here because the boilerplate already 922 // It is safe to use [[Put]] here because the boilerplate already
893 // contains computed properties with an uninitialized value. 923 // contains computed properties with an uninitialized value.
894 if (key->value()->IsInternalizedString()) { 924 if (key->value()->IsInternalizedString()) {
895 if (property->emit_store()) { 925 if (property->emit_store()) {
896 VisitForValue(property->value()); 926 VisitForValue(property->value());
897 Node* value = environment()->Pop(); 927 Node* value = environment()->Pop();
898 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName()); 928 PrintableUnique<Name> name = MakeUnique(key->AsPropertyName());
899 NewNode(javascript()->StoreNamed(name), literal, value); 929 Node* store =
930 NewNode(javascript()->StoreNamed(name), literal, value);
931 BuildLazyBailout(store, key->id());
900 } else { 932 } else {
901 VisitForEffect(property->value()); 933 VisitForEffect(property->value());
902 } 934 }
903 break; 935 break;
904 } 936 }
905 environment()->Push(literal); // Duplicate receiver. 937 environment()->Push(literal); // Duplicate receiver.
906 VisitForValue(property->key()); 938 VisitForValue(property->key());
907 VisitForValue(property->value()); 939 VisitForValue(property->value());
908 Node* value = environment()->Pop(); 940 Node* value = environment()->Pop();
909 Node* key = environment()->Pop(); 941 Node* key = environment()->Pop();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 1012
981 // Create nodes to evaluate all the non-constant subexpressions and to store 1013 // Create nodes to evaluate all the non-constant subexpressions and to store
982 // them into the newly cloned array. 1014 // them into the newly cloned array.
983 for (int i = 0; i < expr->values()->length(); i++) { 1015 for (int i = 0; i < expr->values()->length(); i++) {
984 Expression* subexpr = expr->values()->at(i); 1016 Expression* subexpr = expr->values()->at(i);
985 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1017 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
986 1018
987 VisitForValue(subexpr); 1019 VisitForValue(subexpr);
988 Node* value = environment()->Pop(); 1020 Node* value = environment()->Pop();
989 Node* index = jsgraph()->Constant(i); 1021 Node* index = jsgraph()->Constant(i);
990 NewNode(javascript()->StoreProperty(), literal, index, value); 1022 Node* store = NewNode(javascript()->StoreProperty(), literal, index, value);
1023 BuildLazyBailout(store, expr->GetIdForElement(i));
991 } 1024 }
992 1025
993 environment()->Pop(); // Array literal index. 1026 environment()->Pop(); // Array literal index.
994 ast_context()->ProduceValue(environment()->Pop()); 1027 ast_context()->ProduceValue(environment()->Pop());
995 } 1028 }
996 1029
997 1030
998 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) { 1031 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
999 DCHECK(expr->IsValidReferenceExpression()); 1032 DCHECK(expr->IsValidReferenceExpression());
1000 1033
1001 // Left-hand side can only be a property, a global or a variable slot. 1034 // Left-hand side can only be a property, a global or a variable slot.
1002 Property* property = expr->AsProperty(); 1035 Property* property = expr->AsProperty();
1003 LhsKind assign_type = DetermineLhsKind(expr); 1036 LhsKind assign_type = DetermineLhsKind(expr);
1004 1037
1005 // Evaluate LHS expression and store the value. 1038 // Evaluate LHS expression and store the value.
1006 switch (assign_type) { 1039 switch (assign_type) {
1007 case VARIABLE: { 1040 case VARIABLE: {
1008 Variable* var = expr->AsVariableProxy()->var(); 1041 Variable* var = expr->AsVariableProxy()->var();
1009 BuildVariableAssignment(var, value, Token::ASSIGN); 1042 // TODO(jarin) Fill in the correct bailout id.
1043 BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None());
1010 break; 1044 break;
1011 } 1045 }
1012 case NAMED_PROPERTY: { 1046 case NAMED_PROPERTY: {
1013 environment()->Push(value); 1047 environment()->Push(value);
1014 VisitForValue(property->obj()); 1048 VisitForValue(property->obj());
1015 Node* object = environment()->Pop(); 1049 Node* object = environment()->Pop();
1016 value = environment()->Pop(); 1050 value = environment()->Pop();
1017 PrintableUnique<Name> name = 1051 PrintableUnique<Name> name =
1018 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1052 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1019 NewNode(javascript()->StoreNamed(name), object, value); 1053 Node* store = NewNode(javascript()->StoreNamed(name), object, value);
1054 // TODO(jarin) Fill in the correct bailout id.
1055 BuildLazyBailout(store, BailoutId::None());
1020 break; 1056 break;
1021 } 1057 }
1022 case KEYED_PROPERTY: { 1058 case KEYED_PROPERTY: {
1023 environment()->Push(value); 1059 environment()->Push(value);
1024 VisitForValue(property->obj()); 1060 VisitForValue(property->obj());
1025 VisitForValue(property->key()); 1061 VisitForValue(property->key());
1026 Node* key = environment()->Pop(); 1062 Node* key = environment()->Pop();
1027 Node* object = environment()->Pop(); 1063 Node* object = environment()->Pop();
1028 value = environment()->Pop(); 1064 value = environment()->Pop();
1029 NewNode(javascript()->StoreProperty(), object, key, value); 1065 Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
1066 // TODO(jarin) Fill in the correct bailout id.
1067 BuildLazyBailout(store, BailoutId::None());
1030 break; 1068 break;
1031 } 1069 }
1032 } 1070 }
1033 } 1071 }
1034 1072
1035 1073
1036 void AstGraphBuilder::VisitAssignment(Assignment* expr) { 1074 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
1037 DCHECK(expr->target()->IsValidReferenceExpression()); 1075 DCHECK(expr->target()->IsValidReferenceExpression());
1038 1076
1039 // Left-hand side can only be a property, a global or a variable slot. 1077 // Left-hand side can only be a property, a global or a variable slot.
(...skipping 15 matching lines...) Expand all
1055 } 1093 }
1056 } 1094 }
1057 1095
1058 // Evaluate the value and potentially handle compound assignments by loading 1096 // Evaluate the value and potentially handle compound assignments by loading
1059 // the left-hand side value and performing a binary operation. 1097 // the left-hand side value and performing a binary operation.
1060 if (expr->is_compound()) { 1098 if (expr->is_compound()) {
1061 Node* old_value = NULL; 1099 Node* old_value = NULL;
1062 switch (assign_type) { 1100 switch (assign_type) {
1063 case VARIABLE: { 1101 case VARIABLE: {
1064 Variable* variable = expr->target()->AsVariableProxy()->var(); 1102 Variable* variable = expr->target()->AsVariableProxy()->var();
1065 old_value = BuildVariableLoad(variable); 1103 old_value = BuildVariableLoad(variable, expr->target()->id());
1066 break; 1104 break;
1067 } 1105 }
1068 case NAMED_PROPERTY: { 1106 case NAMED_PROPERTY: {
1069 Node* object = environment()->Top(); 1107 Node* object = environment()->Top();
1070 PrintableUnique<Name> name = 1108 PrintableUnique<Name> name =
1071 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1109 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1072 old_value = NewNode(javascript()->LoadNamed(name), object); 1110 old_value = NewNode(javascript()->LoadNamed(name), object);
1111 BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
1073 break; 1112 break;
1074 } 1113 }
1075 case KEYED_PROPERTY: { 1114 case KEYED_PROPERTY: {
1076 Node* key = environment()->Top(); 1115 Node* key = environment()->Top();
1077 Node* object = environment()->Peek(1); 1116 Node* object = environment()->Peek(1);
1078 old_value = NewNode(javascript()->LoadProperty(), object, key); 1117 old_value = NewNode(javascript()->LoadProperty(), object, key);
1118 BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
1079 break; 1119 break;
1080 } 1120 }
1081 } 1121 }
1082 environment()->Push(old_value); 1122 environment()->Push(old_value);
1083 VisitForValue(expr->value()); 1123 VisitForValue(expr->value());
1084 Node* right = environment()->Pop(); 1124 Node* right = environment()->Pop();
1085 Node* left = environment()->Pop(); 1125 Node* left = environment()->Pop();
1086 Node* value = BuildBinaryOp(left, right, expr->binary_op()); 1126 Node* value = BuildBinaryOp(left, right, expr->binary_op());
1087 environment()->Push(value); 1127 environment()->Push(value);
1128 BuildLazyBailout(value, expr->binary_operation()->id());
1088 } else { 1129 } else {
1089 VisitForValue(expr->value()); 1130 VisitForValue(expr->value());
1090 } 1131 }
1091 1132
1092 // Store the value. 1133 // Store the value.
1093 Node* value = environment()->Pop(); 1134 Node* value = environment()->Pop();
1094 switch (assign_type) { 1135 switch (assign_type) {
1095 case VARIABLE: { 1136 case VARIABLE: {
1096 Variable* variable = expr->target()->AsVariableProxy()->var(); 1137 Variable* variable = expr->target()->AsVariableProxy()->var();
1097 BuildVariableAssignment(variable, value, expr->op()); 1138 BuildVariableAssignment(variable, value, expr->op(),
1139 expr->AssignmentId());
1098 break; 1140 break;
1099 } 1141 }
1100 case NAMED_PROPERTY: { 1142 case NAMED_PROPERTY: {
1101 Node* object = environment()->Pop(); 1143 Node* object = environment()->Pop();
1102 PrintableUnique<Name> name = 1144 PrintableUnique<Name> name =
1103 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1145 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1104 NewNode(javascript()->StoreNamed(name), object, value); 1146 Node* store = NewNode(javascript()->StoreNamed(name), object, value);
1147 BuildLazyBailout(store, expr->AssignmentId());
1105 break; 1148 break;
1106 } 1149 }
1107 case KEYED_PROPERTY: { 1150 case KEYED_PROPERTY: {
1108 Node* key = environment()->Pop(); 1151 Node* key = environment()->Pop();
1109 Node* object = environment()->Pop(); 1152 Node* object = environment()->Pop();
1110 NewNode(javascript()->StoreProperty(), object, key, value); 1153 Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
1154 BuildLazyBailout(store, expr->AssignmentId());
1111 break; 1155 break;
1112 } 1156 }
1113 } 1157 }
1114 1158
1115 ast_context()->ProduceValue(value); 1159 ast_context()->ProduceValue(value);
1116 } 1160 }
1117 1161
1118 1162
1119 void AstGraphBuilder::VisitYield(Yield* expr) { 1163 void AstGraphBuilder::VisitYield(Yield* expr) {
1120 VisitForValue(expr->generator_object()); 1164 VisitForValue(expr->generator_object());
(...skipping 22 matching lines...) Expand all
1143 PrintableUnique<Name> name = 1187 PrintableUnique<Name> name =
1144 MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); 1188 MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
1145 value = NewNode(javascript()->LoadNamed(name), object); 1189 value = NewNode(javascript()->LoadNamed(name), object);
1146 } else { 1190 } else {
1147 VisitForValue(expr->obj()); 1191 VisitForValue(expr->obj());
1148 VisitForValue(expr->key()); 1192 VisitForValue(expr->key());
1149 Node* key = environment()->Pop(); 1193 Node* key = environment()->Pop();
1150 Node* object = environment()->Pop(); 1194 Node* object = environment()->Pop();
1151 value = NewNode(javascript()->LoadProperty(), object, key); 1195 value = NewNode(javascript()->LoadProperty(), object, key);
1152 } 1196 }
1153 ast_context()->ProduceValue(value); 1197 ast_context()->ProduceValueWithLazyBailout(value);
1154 } 1198 }
1155 1199
1156 1200
1157 void AstGraphBuilder::VisitCall(Call* expr) { 1201 void AstGraphBuilder::VisitCall(Call* expr) {
1158 Expression* callee = expr->expression(); 1202 Expression* callee = expr->expression();
1159 Call::CallType call_type = expr->GetCallType(isolate()); 1203 Call::CallType call_type = expr->GetCallType(isolate());
1160 1204
1161 // Prepare the callee and the receiver to the function call. This depends on 1205 // Prepare the callee and the receiver to the function call. This depends on
1162 // the semantics of the underlying call type. 1206 // the semantics of the underlying call type.
1163 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; 1207 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1164 Node* receiver_value = NULL; 1208 Node* receiver_value = NULL;
1165 Node* callee_value = NULL; 1209 Node* callee_value = NULL;
1166 bool possibly_eval = false; 1210 bool possibly_eval = false;
1167 switch (call_type) { 1211 switch (call_type) {
1168 case Call::GLOBAL_CALL: { 1212 case Call::GLOBAL_CALL: {
1169 Variable* variable = callee->AsVariableProxy()->var(); 1213 Variable* variable = callee->AsVariableProxy()->var();
1170 callee_value = BuildVariableLoad(variable); 1214 callee_value = BuildVariableLoad(variable, expr->expression()->id());
1171 receiver_value = jsgraph()->UndefinedConstant(); 1215 receiver_value = jsgraph()->UndefinedConstant();
1172 break; 1216 break;
1173 } 1217 }
1174 case Call::LOOKUP_SLOT_CALL: { 1218 case Call::LOOKUP_SLOT_CALL: {
1175 Variable* variable = callee->AsVariableProxy()->var(); 1219 Variable* variable = callee->AsVariableProxy()->var();
1176 DCHECK(variable->location() == Variable::LOOKUP); 1220 DCHECK(variable->location() == Variable::LOOKUP);
1177 Node* name = jsgraph()->Constant(variable->name()); 1221 Node* name = jsgraph()->Constant(variable->name());
1178 Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); 1222 Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
1179 Node* pair = NewNode(op, current_context(), name); 1223 Node* pair = NewNode(op, current_context(), name);
1180 callee_value = NewNode(common()->Projection(0), pair); 1224 callee_value = NewNode(common()->Projection(0), pair);
1181 receiver_value = NewNode(common()->Projection(1), pair); 1225 receiver_value = NewNode(common()->Projection(1), pair);
1182 break; 1226 break;
1183 } 1227 }
1184 case Call::PROPERTY_CALL: { 1228 case Call::PROPERTY_CALL: {
1185 Property* property = callee->AsProperty(); 1229 Property* property = callee->AsProperty();
1186 VisitForValue(property->obj()); 1230 VisitForValue(property->obj());
1187 Node* object = environment()->Top(); 1231 Node* object = environment()->Top();
1188 if (property->key()->IsPropertyName()) { 1232 if (property->key()->IsPropertyName()) {
1189 PrintableUnique<Name> name = 1233 PrintableUnique<Name> name =
1190 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1234 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1191 callee_value = NewNode(javascript()->LoadNamed(name), object); 1235 callee_value = NewNode(javascript()->LoadNamed(name), object);
1192 } else { 1236 } else {
1193 VisitForValue(property->key()); 1237 VisitForValue(property->key());
1194 Node* key = environment()->Pop(); 1238 Node* key = environment()->Pop();
1195 callee_value = NewNode(javascript()->LoadProperty(), object, key); 1239 callee_value = NewNode(javascript()->LoadProperty(), object, key);
1196 } 1240 }
1241 BuildLazyBailoutWithPushedNode(callee_value, property->LoadId());
1197 receiver_value = environment()->Pop(); 1242 receiver_value = environment()->Pop();
1198 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an 1243 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
1199 // object for sloppy callees. This could also be modeled explicitly here, 1244 // object for sloppy callees. This could also be modeled explicitly here,
1200 // thereby obsoleting the need for a flag to the call operator. 1245 // thereby obsoleting the need for a flag to the call operator.
1201 flags = CALL_AS_METHOD; 1246 flags = CALL_AS_METHOD;
1202 break; 1247 break;
1203 } 1248 }
1204 case Call::POSSIBLY_EVAL_CALL: 1249 case Call::POSSIBLY_EVAL_CALL:
1205 possibly_eval = true; 1250 possibly_eval = true;
1206 // Fall through. 1251 // Fall through.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 Node* new_receiver = NewNode(common()->Projection(1), pair); 1286 Node* new_receiver = NewNode(common()->Projection(1), pair);
1242 1287
1243 // Patch callee and receiver on the environment. 1288 // Patch callee and receiver on the environment.
1244 environment()->Poke(arg_count + 1, new_callee); 1289 environment()->Poke(arg_count + 1, new_callee);
1245 environment()->Poke(arg_count + 0, new_receiver); 1290 environment()->Poke(arg_count + 0, new_receiver);
1246 } 1291 }
1247 1292
1248 // Create node to perform the function call. 1293 // Create node to perform the function call.
1249 Operator* call = javascript()->Call(args->length() + 2, flags); 1294 Operator* call = javascript()->Call(args->length() + 2, flags);
1250 Node* value = ProcessArguments(call, args->length() + 2); 1295 Node* value = ProcessArguments(call, args->length() + 2);
1251 ast_context()->ProduceValue(value); 1296 ast_context()->ProduceValueWithLazyBailout(value);
1252 } 1297 }
1253 1298
1254 1299
1255 void AstGraphBuilder::VisitCallNew(CallNew* expr) { 1300 void AstGraphBuilder::VisitCallNew(CallNew* expr) {
1256 VisitForValue(expr->expression()); 1301 VisitForValue(expr->expression());
1257 1302
1258 // Evaluate all arguments to the construct call. 1303 // Evaluate all arguments to the construct call.
1259 ZoneList<Expression*>* args = expr->arguments(); 1304 ZoneList<Expression*>* args = expr->arguments();
1260 VisitForValues(args); 1305 VisitForValues(args);
1261 1306
1262 // Create node to perform the construct call. 1307 // Create node to perform the construct call.
1263 Operator* call = javascript()->CallNew(args->length() + 1); 1308 Operator* call = javascript()->CallNew(args->length() + 1);
1264 Node* value = ProcessArguments(call, args->length() + 1); 1309 Node* value = ProcessArguments(call, args->length() + 1);
1265 ast_context()->ProduceValue(value); 1310 ast_context()->ProduceValueWithLazyBailout(value);
1266 } 1311 }
1267 1312
1268 1313
1269 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) { 1314 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
1270 Handle<String> name = expr->name(); 1315 Handle<String> name = expr->name();
1271 1316
1272 // The callee and the receiver both have to be pushed onto the operand stack 1317 // The callee and the receiver both have to be pushed onto the operand stack
1273 // before arguments are being evaluated. 1318 // before arguments are being evaluated.
1274 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; 1319 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1275 Node* receiver_value = BuildLoadBuiltinsObject(); 1320 Node* receiver_value = BuildLoadBuiltinsObject();
1276 PrintableUnique<String> unique = MakeUnique(name); 1321 PrintableUnique<String> unique = MakeUnique(name);
1277 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); 1322 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
1278 environment()->Push(callee_value); 1323 environment()->Push(callee_value);
1324 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
1325 // refuses to optimize functions with jsruntime calls).
1326 BuildLazyBailout(callee_value, BailoutId::None());
1279 environment()->Push(receiver_value); 1327 environment()->Push(receiver_value);
1280 1328
1281 // Evaluate all arguments to the JS runtime call. 1329 // Evaluate all arguments to the JS runtime call.
1282 ZoneList<Expression*>* args = expr->arguments(); 1330 ZoneList<Expression*>* args = expr->arguments();
1283 VisitForValues(args); 1331 VisitForValues(args);
1284 1332
1285 // Create node to perform the JS runtime call. 1333 // Create node to perform the JS runtime call.
1286 Operator* call = javascript()->Call(args->length() + 2, flags); 1334 Operator* call = javascript()->Call(args->length() + 2, flags);
1287 Node* value = ProcessArguments(call, args->length() + 2); 1335 Node* value = ProcessArguments(call, args->length() + 2);
1288 ast_context()->ProduceValue(value); 1336 ast_context()->ProduceValueWithLazyBailout(value);
1289 } 1337 }
1290 1338
1291 1339
1292 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 1340 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
1293 const Runtime::Function* function = expr->function(); 1341 const Runtime::Function* function = expr->function();
1294 1342
1295 // Handle calls to runtime functions implemented in JavaScript separately as 1343 // Handle calls to runtime functions implemented in JavaScript separately as
1296 // the call follows JavaScript ABI and the callee is statically unknown. 1344 // the call follows JavaScript ABI and the callee is statically unknown.
1297 if (expr->is_jsruntime()) { 1345 if (expr->is_jsruntime()) {
1298 DCHECK(function == NULL && expr->name()->length() > 0); 1346 DCHECK(function == NULL && expr->name()->length() > 0);
1299 return VisitCallJSRuntime(expr); 1347 return VisitCallJSRuntime(expr);
1300 } 1348 }
1301 1349
1302 // Evaluate all arguments to the runtime call. 1350 // Evaluate all arguments to the runtime call.
1303 ZoneList<Expression*>* args = expr->arguments(); 1351 ZoneList<Expression*>* args = expr->arguments();
1304 VisitForValues(args); 1352 VisitForValues(args);
1305 1353
1306 // Create node to perform the runtime call. 1354 // Create node to perform the runtime call.
1307 Runtime::FunctionId functionId = function->function_id; 1355 Runtime::FunctionId functionId = function->function_id;
1308 Operator* call = javascript()->Runtime(functionId, args->length()); 1356 Operator* call = javascript()->Runtime(functionId, args->length());
1309 Node* value = ProcessArguments(call, args->length()); 1357 Node* value = ProcessArguments(call, args->length());
1310 ast_context()->ProduceValue(value); 1358 ast_context()->ProduceValueWithLazyBailout(value);
1311
1312 BuildLazyBailout(value, expr->id());
1313 } 1359 }
1314 1360
1315 1361
1316 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 1362 void AstGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
1317 switch (expr->op()) { 1363 switch (expr->op()) {
1318 case Token::DELETE: 1364 case Token::DELETE:
1319 return VisitDelete(expr); 1365 return VisitDelete(expr);
1320 case Token::VOID: 1366 case Token::VOID:
1321 return VisitVoid(expr); 1367 return VisitVoid(expr);
1322 case Token::TYPEOF: 1368 case Token::TYPEOF:
(...skipping 16 matching lines...) Expand all
1339 // Reserve space for result of postfix operation. 1385 // Reserve space for result of postfix operation.
1340 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect(); 1386 bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
1341 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant()); 1387 if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant());
1342 1388
1343 // Evaluate LHS expression and get old value. 1389 // Evaluate LHS expression and get old value.
1344 Node* old_value = NULL; 1390 Node* old_value = NULL;
1345 int stack_depth = -1; 1391 int stack_depth = -1;
1346 switch (assign_type) { 1392 switch (assign_type) {
1347 case VARIABLE: { 1393 case VARIABLE: {
1348 Variable* variable = expr->expression()->AsVariableProxy()->var(); 1394 Variable* variable = expr->expression()->AsVariableProxy()->var();
1349 old_value = BuildVariableLoad(variable); 1395 old_value = BuildVariableLoad(variable, expr->expression()->id());
1350 stack_depth = 0; 1396 stack_depth = 0;
1351 break; 1397 break;
1352 } 1398 }
1353 case NAMED_PROPERTY: { 1399 case NAMED_PROPERTY: {
1354 VisitForValue(property->obj()); 1400 VisitForValue(property->obj());
1355 Node* object = environment()->Top(); 1401 Node* object = environment()->Top();
1356 PrintableUnique<Name> name = 1402 PrintableUnique<Name> name =
1357 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1403 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1358 old_value = NewNode(javascript()->LoadNamed(name), object); 1404 old_value = NewNode(javascript()->LoadNamed(name), object);
1405 BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
1359 stack_depth = 1; 1406 stack_depth = 1;
1360 break; 1407 break;
1361 } 1408 }
1362 case KEYED_PROPERTY: { 1409 case KEYED_PROPERTY: {
1363 VisitForValue(property->obj()); 1410 VisitForValue(property->obj());
1364 VisitForValue(property->key()); 1411 VisitForValue(property->key());
1365 Node* key = environment()->Top(); 1412 Node* key = environment()->Top();
1366 Node* object = environment()->Peek(1); 1413 Node* object = environment()->Peek(1);
1367 old_value = NewNode(javascript()->LoadProperty(), object, key); 1414 old_value = NewNode(javascript()->LoadProperty(), object, key);
1415 BuildLazyBailoutWithPushedNode(old_value, property->LoadId());
1368 stack_depth = 2; 1416 stack_depth = 2;
1369 break; 1417 break;
1370 } 1418 }
1371 } 1419 }
1372 1420
1373 // Convert old value into a number. 1421 // Convert old value into a number.
1374 old_value = NewNode(javascript()->ToNumber(), old_value); 1422 old_value = NewNode(javascript()->ToNumber(), old_value);
1375 1423
1376 // Save result for postfix expressions at correct stack depth. 1424 // Save result for postfix expressions at correct stack depth.
1377 if (is_postfix) environment()->Poke(stack_depth, old_value); 1425 if (is_postfix) environment()->Poke(stack_depth, old_value);
1378 1426
1379 // Create node to perform +1/-1 operation. 1427 // Create node to perform +1/-1 operation.
1380 Node* value = 1428 Node* value =
1381 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); 1429 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
1430 // TODO(jarin) Insert proper bailout id here (will need to change
1431 // full code generator).
1432 BuildLazyBailout(value, BailoutId::None());
1382 1433
1383 // Store the value. 1434 // Store the value.
1384 switch (assign_type) { 1435 switch (assign_type) {
1385 case VARIABLE: { 1436 case VARIABLE: {
1386 Variable* variable = expr->expression()->AsVariableProxy()->var(); 1437 Variable* variable = expr->expression()->AsVariableProxy()->var();
1387 BuildVariableAssignment(variable, value, expr->op()); 1438 BuildVariableAssignment(variable, value, expr->op(),
1439 expr->AssignmentId());
1388 break; 1440 break;
1389 } 1441 }
1390 case NAMED_PROPERTY: { 1442 case NAMED_PROPERTY: {
1391 Node* object = environment()->Pop(); 1443 Node* object = environment()->Pop();
1392 PrintableUnique<Name> name = 1444 PrintableUnique<Name> name =
1393 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1445 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1394 NewNode(javascript()->StoreNamed(name), object, value); 1446 Node* store = NewNode(javascript()->StoreNamed(name), object, value);
1447 BuildLazyBailout(store, expr->AssignmentId());
1395 break; 1448 break;
1396 } 1449 }
1397 case KEYED_PROPERTY: { 1450 case KEYED_PROPERTY: {
1398 Node* key = environment()->Pop(); 1451 Node* key = environment()->Pop();
1399 Node* object = environment()->Pop(); 1452 Node* object = environment()->Pop();
1400 NewNode(javascript()->StoreProperty(), object, key, value); 1453 Node* store = NewNode(javascript()->StoreProperty(), object, key, value);
1454 BuildLazyBailout(store, expr->AssignmentId());
1401 break; 1455 break;
1402 } 1456 }
1403 } 1457 }
1404 1458
1405 // Restore old value for postfix expressions. 1459 // Restore old value for postfix expressions.
1406 if (is_postfix) value = environment()->Pop(); 1460 if (is_postfix) value = environment()->Pop();
1407 1461
1408 ast_context()->ProduceValue(value); 1462 ast_context()->ProduceValue(value);
1409 } 1463 }
1410 1464
1411 1465
1412 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 1466 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
1413 switch (expr->op()) { 1467 switch (expr->op()) {
1414 case Token::COMMA: 1468 case Token::COMMA:
1415 return VisitComma(expr); 1469 return VisitComma(expr);
1416 case Token::OR: 1470 case Token::OR:
1417 case Token::AND: 1471 case Token::AND:
1418 return VisitLogicalExpression(expr); 1472 return VisitLogicalExpression(expr);
1419 default: { 1473 default: {
1420 VisitForValue(expr->left()); 1474 VisitForValue(expr->left());
1421 VisitForValue(expr->right()); 1475 VisitForValue(expr->right());
1422 Node* right = environment()->Pop(); 1476 Node* right = environment()->Pop();
1423 Node* left = environment()->Pop(); 1477 Node* left = environment()->Pop();
1424 Node* value = BuildBinaryOp(left, right, expr->op()); 1478 Node* value = BuildBinaryOp(left, right, expr->op());
1425 ast_context()->ProduceValue(value); 1479 ast_context()->ProduceValueWithLazyBailout(value);
1426 } 1480 }
1427 } 1481 }
1428 } 1482 }
1429 1483
1430 1484
1431 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 1485 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1432 Operator* op; 1486 Operator* op;
1433 switch (expr->op()) { 1487 switch (expr->op()) {
1434 case Token::EQ: 1488 case Token::EQ:
1435 op = javascript()->Equal(); 1489 op = javascript()->Equal();
(...skipping 28 matching lines...) Expand all
1464 default: 1518 default:
1465 op = NULL; 1519 op = NULL;
1466 UNREACHABLE(); 1520 UNREACHABLE();
1467 } 1521 }
1468 VisitForValue(expr->left()); 1522 VisitForValue(expr->left());
1469 VisitForValue(expr->right()); 1523 VisitForValue(expr->right());
1470 Node* right = environment()->Pop(); 1524 Node* right = environment()->Pop();
1471 Node* left = environment()->Pop(); 1525 Node* left = environment()->Pop();
1472 Node* value = NewNode(op, left, right); 1526 Node* value = NewNode(op, left, right);
1473 ast_context()->ProduceValue(value); 1527 ast_context()->ProduceValue(value);
1528
1529 BuildLazyBailout(value, expr->id());
1474 } 1530 }
1475 1531
1476 1532
1477 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) { 1533 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
1478 Node* value = GetFunctionClosure(); 1534 Node* value = GetFunctionClosure();
1479 ast_context()->ProduceValue(value); 1535 ast_context()->ProduceValue(value);
1480 } 1536 }
1481 1537
1482 1538
1483 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); } 1539 void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 ast_context()->ProduceValue(value); 1599 ast_context()->ProduceValue(value);
1544 } 1600 }
1545 1601
1546 1602
1547 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) { 1603 void AstGraphBuilder::VisitTypeof(UnaryOperation* expr) {
1548 Node* operand; 1604 Node* operand;
1549 if (expr->expression()->IsVariableProxy()) { 1605 if (expr->expression()->IsVariableProxy()) {
1550 // Typeof does not throw a reference error on global variables, hence we 1606 // Typeof does not throw a reference error on global variables, hence we
1551 // perform a non-contextual load in case the operand is a variable proxy. 1607 // perform a non-contextual load in case the operand is a variable proxy.
1552 Variable* variable = expr->expression()->AsVariableProxy()->var(); 1608 Variable* variable = expr->expression()->AsVariableProxy()->var();
1553 operand = BuildVariableLoad(variable, NOT_CONTEXTUAL); 1609 operand =
1610 BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL);
1554 } else { 1611 } else {
1555 VisitForValue(expr->expression()); 1612 VisitForValue(expr->expression());
1556 operand = environment()->Pop(); 1613 operand = environment()->Pop();
1557 } 1614 }
1558 Node* value = NewNode(javascript()->TypeOf(), operand); 1615 Node* value = NewNode(javascript()->TypeOf(), operand);
1559 ast_context()->ProduceValue(value); 1616 ast_context()->ProduceValue(value);
1560 } 1617 }
1561 1618
1562 1619
1563 void AstGraphBuilder::VisitNot(UnaryOperation* expr) { 1620 void AstGraphBuilder::VisitNot(UnaryOperation* expr) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) { 1700 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
1644 if (arguments == NULL) return NULL; 1701 if (arguments == NULL) return NULL;
1645 1702
1646 // Allocate and initialize a new arguments object. 1703 // Allocate and initialize a new arguments object.
1647 Node* callee = GetFunctionClosure(); 1704 Node* callee = GetFunctionClosure();
1648 Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1); 1705 Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
1649 Node* object = NewNode(op, callee); 1706 Node* object = NewNode(op, callee);
1650 1707
1651 // Assign the object to the arguments variable. 1708 // Assign the object to the arguments variable.
1652 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); 1709 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
1653 BuildVariableAssignment(arguments, object, Token::ASSIGN); 1710 // This should never lazy deopt, so it is fine to send invalid bailout id.
1711 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
1654 1712
1655 return object; 1713 return object;
1656 } 1714 }
1657 1715
1658 1716
1659 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, 1717 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
1660 Node* not_hole) { 1718 Node* not_hole) {
1661 IfBuilder hole_check(this); 1719 IfBuilder hole_check(this);
1662 Node* the_hole = jsgraph()->TheHoleConstant(); 1720 Node* the_hole = jsgraph()->TheHoleConstant();
1663 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); 1721 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
(...skipping 16 matching lines...) Expand all
1680 hole_check.Then(); 1738 hole_check.Then();
1681 environment()->Push(BuildThrowReferenceError(variable)); 1739 environment()->Push(BuildThrowReferenceError(variable));
1682 hole_check.Else(); 1740 hole_check.Else();
1683 environment()->Push(not_hole); 1741 environment()->Push(not_hole);
1684 hole_check.End(); 1742 hole_check.End();
1685 return environment()->Pop(); 1743 return environment()->Pop();
1686 } 1744 }
1687 1745
1688 1746
1689 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, 1747 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
1748 BailoutId bailout_id,
1690 ContextualMode contextual_mode) { 1749 ContextualMode contextual_mode) {
1691 Node* the_hole = jsgraph()->TheHoleConstant(); 1750 Node* the_hole = jsgraph()->TheHoleConstant();
1692 VariableMode mode = variable->mode(); 1751 VariableMode mode = variable->mode();
1693 switch (variable->location()) { 1752 switch (variable->location()) {
1694 case Variable::UNALLOCATED: { 1753 case Variable::UNALLOCATED: {
1695 // Global var, const, or let variable. 1754 // Global var, const, or let variable.
1696 Node* global = BuildLoadGlobalObject(); 1755 Node* global = BuildLoadGlobalObject();
1697 PrintableUnique<Name> name = MakeUnique(variable->name()); 1756 PrintableUnique<Name> name = MakeUnique(variable->name());
1698 Operator* op = javascript()->LoadNamed(name, contextual_mode); 1757 Operator* op = javascript()->LoadNamed(name, contextual_mode);
1699 return NewNode(op, global); 1758 Node* node = NewNode(op, global);
1759 BuildLazyBailoutWithPushedNode(node, bailout_id);
1760 return node;
1700 } 1761 }
1701 case Variable::PARAMETER: 1762 case Variable::PARAMETER:
1702 case Variable::LOCAL: { 1763 case Variable::LOCAL: {
1703 // Local var, const, or let variable. 1764 // Local var, const, or let variable.
1704 Node* value = environment()->Lookup(variable); 1765 Node* value = environment()->Lookup(variable);
1705 if (mode == CONST_LEGACY) { 1766 if (mode == CONST_LEGACY) {
1706 // Perform check for uninitialized legacy const variables. 1767 // Perform check for uninitialized legacy const variables.
1707 if (value->op() == the_hole->op()) { 1768 if (value->op() == the_hole->op()) {
1708 value = jsgraph()->UndefinedConstant(); 1769 value = jsgraph()->UndefinedConstant();
1709 } else if (value->opcode() == IrOpcode::kPhi) { 1770 } else if (value->opcode() == IrOpcode::kPhi) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); 1839 Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
1779 return NewNode(op, current_context(), name); 1840 return NewNode(op, current_context(), name);
1780 } 1841 }
1781 } 1842 }
1782 UNREACHABLE(); 1843 UNREACHABLE();
1783 return NULL; 1844 return NULL;
1784 } 1845 }
1785 1846
1786 1847
1787 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, 1848 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
1788 Token::Value op) { 1849 Token::Value op,
1850 BailoutId bailout_id) {
1789 Node* the_hole = jsgraph()->TheHoleConstant(); 1851 Node* the_hole = jsgraph()->TheHoleConstant();
1790 VariableMode mode = variable->mode(); 1852 VariableMode mode = variable->mode();
1791 switch (variable->location()) { 1853 switch (variable->location()) {
1792 case Variable::UNALLOCATED: { 1854 case Variable::UNALLOCATED: {
1793 // Global var, const, or let variable. 1855 // Global var, const, or let variable.
1794 Node* global = BuildLoadGlobalObject(); 1856 Node* global = BuildLoadGlobalObject();
1795 PrintableUnique<Name> name = MakeUnique(variable->name()); 1857 PrintableUnique<Name> name = MakeUnique(variable->name());
1796 Operator* op = javascript()->StoreNamed(name); 1858 Operator* op = javascript()->StoreNamed(name);
1797 return NewNode(op, global, value); 1859 Node* store = NewNode(op, global, value);
1860 BuildLazyBailout(store, bailout_id);
1861 return store;
1798 } 1862 }
1799 case Variable::PARAMETER: 1863 case Variable::PARAMETER:
1800 case Variable::LOCAL: 1864 case Variable::LOCAL:
1801 // Local var, const, or let variable. 1865 // Local var, const, or let variable.
1802 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 1866 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1803 // Perform an initialization check for legacy const variables. 1867 // Perform an initialization check for legacy const variables.
1804 Node* current = environment()->Lookup(variable); 1868 Node* current = environment()->Lookup(variable);
1805 if (current->op() != the_hole->op()) { 1869 if (current->op() != the_hole->op()) {
1806 value = BuildHoleCheckSilent(current, value, current); 1870 value = BuildHoleCheckSilent(current, value, current);
1807 } 1871 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1951 DCHECK(environment()->GetControlDependency() == node); 2015 DCHECK(environment()->GetControlDependency() == node);
1952 2016
1953 StructuredGraphBuilder::Environment* continuation_env = environment(); 2017 StructuredGraphBuilder::Environment* continuation_env = environment();
1954 // Create environment for the deoptimization block, and build the block. 2018 // Create environment for the deoptimization block, and build the block.
1955 StructuredGraphBuilder::Environment* deopt_env = 2019 StructuredGraphBuilder::Environment* deopt_env =
1956 CopyEnvironment(continuation_env); 2020 CopyEnvironment(continuation_env);
1957 set_environment(deopt_env); 2021 set_environment(deopt_env);
1958 2022
1959 NewNode(common()->LazyDeoptimization()); 2023 NewNode(common()->LazyDeoptimization());
1960 2024
2025 // TODO(jarin) If ast_id.IsNone(), perhaps we should generate an empty
2026 // deopt block and make sure there is no patch entry for this (so
2027 // that the deoptimizer dies when trying to deoptimize here).
2028
1961 Node* state_node = environment()->Checkpoint(ast_id); 2029 Node* state_node = environment()->Checkpoint(ast_id);
1962 2030
1963 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node); 2031 Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node);
1964 2032
1965 UpdateControlDependencyToLeaveFunction(deoptimize_node); 2033 UpdateControlDependencyToLeaveFunction(deoptimize_node);
1966 2034
1967 // Continue with the original environment. 2035 // Continue with the original environment.
1968 set_environment(continuation_env); 2036 set_environment(continuation_env);
1969 2037
1970 NewNode(common()->Continuation()); 2038 NewNode(common()->Continuation());
1971 } 2039 }
1972 } 2040 }
2041
2042
2043 void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node,
2044 BailoutId ast_id) {
2045 environment()->Push(node);
2046 BuildLazyBailout(node, ast_id);
2047 environment()->Pop();
2048 }
1973 } 2049 }
1974 } 2050 }
1975 } // namespace v8::internal::compiler 2051 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/code-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698