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

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

Issue 595863002: Adding more missing deoptimization points in Turbofan. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 2 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/machine-operator.h" 9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 854
855 // Create node to materialize a regular expression literal. 855 // Create node to materialize a regular expression literal.
856 Node* literals_array = 856 Node* literals_array =
857 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset); 857 BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
858 Node* literal_index = jsgraph()->Constant(expr->literal_index()); 858 Node* literal_index = jsgraph()->Constant(expr->literal_index());
859 Node* pattern = jsgraph()->Constant(expr->pattern()); 859 Node* pattern = jsgraph()->Constant(expr->pattern());
860 Node* flags = jsgraph()->Constant(expr->flags()); 860 Node* flags = jsgraph()->Constant(expr->flags());
861 const Operator* op = 861 const Operator* op =
862 javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4); 862 javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
863 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags); 863 Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
864 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
864 ast_context()->ProduceValue(literal); 865 ast_context()->ProduceValue(literal);
865 } 866 }
866 867
867 868
868 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 869 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
869 Node* closure = GetFunctionClosure(); 870 Node* closure = GetFunctionClosure();
870 871
871 // Create node to deep-copy the literal boilerplate. 872 // Create node to deep-copy the literal boilerplate.
872 expr->BuildConstantProperties(isolate()); 873 expr->BuildConstantProperties(isolate());
873 Node* literals_array = 874 Node* literals_array =
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 case VARIABLE: { 1089 case VARIABLE: {
1089 Variable* variable = expr->target()->AsVariableProxy()->var(); 1090 Variable* variable = expr->target()->AsVariableProxy()->var();
1090 old_value = BuildVariableLoad(variable, expr->target()->id()); 1091 old_value = BuildVariableLoad(variable, expr->target()->id());
1091 break; 1092 break;
1092 } 1093 }
1093 case NAMED_PROPERTY: { 1094 case NAMED_PROPERTY: {
1094 Node* object = environment()->Top(); 1095 Node* object = environment()->Top();
1095 Unique<Name> name = 1096 Unique<Name> name =
1096 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1097 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1097 old_value = NewNode(javascript()->LoadNamed(name), object); 1098 old_value = NewNode(javascript()->LoadNamed(name), object);
1098 PrepareFrameState(old_value, property->LoadId(), kPushOutput); 1099 PrepareFrameState(old_value, property->LoadId(),
1100 OutputFrameStateCombine::Push());
1099 break; 1101 break;
1100 } 1102 }
1101 case KEYED_PROPERTY: { 1103 case KEYED_PROPERTY: {
1102 Node* key = environment()->Top(); 1104 Node* key = environment()->Top();
1103 Node* object = environment()->Peek(1); 1105 Node* object = environment()->Peek(1);
1104 old_value = NewNode(javascript()->LoadProperty(), object, key); 1106 old_value = NewNode(javascript()->LoadProperty(), object, key);
1105 PrepareFrameState(old_value, property->LoadId(), kPushOutput); 1107 PrepareFrameState(old_value, property->LoadId(),
1108 OutputFrameStateCombine::Push());
1106 break; 1109 break;
1107 } 1110 }
1108 } 1111 }
1109 environment()->Push(old_value); 1112 environment()->Push(old_value);
1110 VisitForValue(expr->value()); 1113 VisitForValue(expr->value());
1111 Node* right = environment()->Pop(); 1114 Node* right = environment()->Pop();
1112 Node* left = environment()->Pop(); 1115 Node* left = environment()->Pop();
1113 Node* value = BuildBinaryOp(left, right, expr->binary_op()); 1116 Node* value = BuildBinaryOp(left, right, expr->binary_op());
1114 PrepareFrameState(value, expr->binary_operation()->id(), kPushOutput); 1117 PrepareFrameState(value, expr->binary_operation()->id(),
1118 OutputFrameStateCombine::Push());
1115 environment()->Push(value); 1119 environment()->Push(value);
1116 } else { 1120 } else {
1117 VisitForValue(expr->value()); 1121 VisitForValue(expr->value());
1118 } 1122 }
1119 1123
1120 // Store the value. 1124 // Store the value.
1121 Node* value = environment()->Pop(); 1125 Node* value = environment()->Pop();
1122 switch (assign_type) { 1126 switch (assign_type) {
1123 case VARIABLE: { 1127 case VARIABLE: {
1124 Variable* variable = expr->target()->AsVariableProxy()->var(); 1128 Variable* variable = expr->target()->AsVariableProxy()->var();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 // TODO(turbofan): VisitYield 1161 // TODO(turbofan): VisitYield
1158 ast_context()->ProduceValue(jsgraph()->UndefinedConstant()); 1162 ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
1159 } 1163 }
1160 1164
1161 1165
1162 void AstGraphBuilder::VisitThrow(Throw* expr) { 1166 void AstGraphBuilder::VisitThrow(Throw* expr) {
1163 VisitForValue(expr->exception()); 1167 VisitForValue(expr->exception());
1164 Node* exception = environment()->Pop(); 1168 Node* exception = environment()->Pop();
1165 const Operator* op = javascript()->Runtime(Runtime::kThrow, 1); 1169 const Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
1166 Node* value = NewNode(op, exception); 1170 Node* value = NewNode(op, exception);
1171 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1167 ast_context()->ProduceValue(value); 1172 ast_context()->ProduceValue(value);
1168 } 1173 }
1169 1174
1170 1175
1171 void AstGraphBuilder::VisitProperty(Property* expr) { 1176 void AstGraphBuilder::VisitProperty(Property* expr) {
1172 Node* value; 1177 Node* value;
1173 if (expr->key()->IsPropertyName()) { 1178 if (expr->key()->IsPropertyName()) {
1174 VisitForValue(expr->obj()); 1179 VisitForValue(expr->obj());
1175 Node* object = environment()->Pop(); 1180 Node* object = environment()->Pop();
1176 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName()); 1181 Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
(...skipping 28 matching lines...) Expand all
1205 break; 1210 break;
1206 } 1211 }
1207 case Call::LOOKUP_SLOT_CALL: { 1212 case Call::LOOKUP_SLOT_CALL: {
1208 Variable* variable = callee->AsVariableProxy()->var(); 1213 Variable* variable = callee->AsVariableProxy()->var();
1209 DCHECK(variable->location() == Variable::LOOKUP); 1214 DCHECK(variable->location() == Variable::LOOKUP);
1210 Node* name = jsgraph()->Constant(variable->name()); 1215 Node* name = jsgraph()->Constant(variable->name());
1211 const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2); 1216 const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
1212 Node* pair = NewNode(op, current_context(), name); 1217 Node* pair = NewNode(op, current_context(), name);
1213 callee_value = NewNode(common()->Projection(0), pair); 1218 callee_value = NewNode(common()->Projection(0), pair);
1214 receiver_value = NewNode(common()->Projection(1), pair); 1219 receiver_value = NewNode(common()->Projection(1), pair);
1220
1221 PrepareFrameState(pair, expr->EvalOrLookupId(),
1222 OutputFrameStateCombine::Push());
1215 break; 1223 break;
1216 } 1224 }
1217 case Call::PROPERTY_CALL: { 1225 case Call::PROPERTY_CALL: {
1218 Property* property = callee->AsProperty(); 1226 Property* property = callee->AsProperty();
1219 VisitForValue(property->obj()); 1227 VisitForValue(property->obj());
1220 Node* object = environment()->Top(); 1228 Node* object = environment()->Top();
1221 if (property->key()->IsPropertyName()) { 1229 if (property->key()->IsPropertyName()) {
1222 Unique<Name> name = 1230 Unique<Name> name =
1223 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1231 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1224 callee_value = NewNode(javascript()->LoadNamed(name), object); 1232 callee_value = NewNode(javascript()->LoadNamed(name), object);
1225 } else { 1233 } else {
1226 VisitForValue(property->key()); 1234 VisitForValue(property->key());
1227 Node* key = environment()->Pop(); 1235 Node* key = environment()->Pop();
1228 callee_value = NewNode(javascript()->LoadProperty(), object, key); 1236 callee_value = NewNode(javascript()->LoadProperty(), object, key);
1229 } 1237 }
1230 PrepareFrameState(callee_value, property->LoadId(), kPushOutput); 1238 PrepareFrameState(callee_value, property->LoadId(),
1239 OutputFrameStateCombine::Push());
1231 receiver_value = environment()->Pop(); 1240 receiver_value = environment()->Pop();
1232 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an 1241 // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
1233 // object for sloppy callees. This could also be modeled explicitly here, 1242 // object for sloppy callees. This could also be modeled explicitly here,
1234 // thereby obsoleting the need for a flag to the call operator. 1243 // thereby obsoleting the need for a flag to the call operator.
1235 flags = CALL_AS_METHOD; 1244 flags = CALL_AS_METHOD;
1236 break; 1245 break;
1237 } 1246 }
1238 case Call::POSSIBLY_EVAL_CALL: 1247 case Call::POSSIBLY_EVAL_CALL:
1239 possibly_eval = true; 1248 possibly_eval = true;
1240 // Fall through. 1249 // Fall through.
(...skipping 23 matching lines...) Expand all
1264 Node* source = environment()->Peek(arg_count - 1); 1273 Node* source = environment()->Peek(arg_count - 1);
1265 1274
1266 // Create node to ask for help resolving potential eval call. This will 1275 // Create node to ask for help resolving potential eval call. This will
1267 // provide a fully resolved callee and the corresponding receiver. 1276 // provide a fully resolved callee and the corresponding receiver.
1268 Node* receiver = environment()->Lookup(info()->scope()->receiver()); 1277 Node* receiver = environment()->Lookup(info()->scope()->receiver());
1269 Node* strict = jsgraph()->Constant(strict_mode()); 1278 Node* strict = jsgraph()->Constant(strict_mode());
1270 Node* position = jsgraph()->Constant(info()->scope()->start_position()); 1279 Node* position = jsgraph()->Constant(info()->scope()->start_position());
1271 const Operator* op = 1280 const Operator* op =
1272 javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5); 1281 javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 5);
1273 Node* pair = NewNode(op, callee, source, receiver, strict, position); 1282 Node* pair = NewNode(op, callee, source, receiver, strict, position);
1283 PrepareFrameState(pair, expr->EvalOrLookupId(),
1284 OutputFrameStateCombine::PokeAt(arg_count + 1));
1274 Node* new_callee = NewNode(common()->Projection(0), pair); 1285 Node* new_callee = NewNode(common()->Projection(0), pair);
1275 Node* new_receiver = NewNode(common()->Projection(1), pair); 1286 Node* new_receiver = NewNode(common()->Projection(1), pair);
1276 1287
1277 // Patch callee and receiver on the environment. 1288 // Patch callee and receiver on the environment.
1278 environment()->Poke(arg_count + 1, new_callee); 1289 environment()->Poke(arg_count + 1, new_callee);
1279 environment()->Poke(arg_count + 0, new_receiver); 1290 environment()->Poke(arg_count + 0, new_receiver);
1280 } 1291 }
1281 1292
1282 // Create node to perform the function call. 1293 // Create node to perform the function call.
1283 const Operator* call = javascript()->Call(args->length() + 2, flags); 1294 const Operator* call = javascript()->Call(args->length() + 2, flags);
(...skipping 22 matching lines...) Expand all
1306 Handle<String> name = expr->name(); 1317 Handle<String> name = expr->name();
1307 1318
1308 // The callee and the receiver both have to be pushed onto the operand stack 1319 // The callee and the receiver both have to be pushed onto the operand stack
1309 // before arguments are being evaluated. 1320 // before arguments are being evaluated.
1310 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS; 1321 CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
1311 Node* receiver_value = BuildLoadBuiltinsObject(); 1322 Node* receiver_value = BuildLoadBuiltinsObject();
1312 Unique<String> unique = MakeUnique(name); 1323 Unique<String> unique = MakeUnique(name);
1313 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value); 1324 Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
1314 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft 1325 // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
1315 // refuses to optimize functions with jsruntime calls). 1326 // refuses to optimize functions with jsruntime calls).
1316 PrepareFrameState(callee_value, BailoutId::None(), kPushOutput); 1327 PrepareFrameState(callee_value, BailoutId::None(),
1328 OutputFrameStateCombine::Push());
1317 environment()->Push(callee_value); 1329 environment()->Push(callee_value);
1318 environment()->Push(receiver_value); 1330 environment()->Push(receiver_value);
1319 1331
1320 // Evaluate all arguments to the JS runtime call. 1332 // Evaluate all arguments to the JS runtime call.
1321 ZoneList<Expression*>* args = expr->arguments(); 1333 ZoneList<Expression*>* args = expr->arguments();
1322 VisitForValues(args); 1334 VisitForValues(args);
1323 1335
1324 // Create node to perform the JS runtime call. 1336 // Create node to perform the JS runtime call.
1325 const Operator* call = javascript()->Call(args->length() + 2, flags); 1337 const Operator* call = javascript()->Call(args->length() + 2, flags);
1326 Node* value = ProcessArguments(call, args->length() + 2); 1338 Node* value = ProcessArguments(call, args->length() + 2);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 old_value = BuildVariableLoad(variable, expr->expression()->id()); 1400 old_value = BuildVariableLoad(variable, expr->expression()->id());
1389 stack_depth = 0; 1401 stack_depth = 0;
1390 break; 1402 break;
1391 } 1403 }
1392 case NAMED_PROPERTY: { 1404 case NAMED_PROPERTY: {
1393 VisitForValue(property->obj()); 1405 VisitForValue(property->obj());
1394 Node* object = environment()->Top(); 1406 Node* object = environment()->Top();
1395 Unique<Name> name = 1407 Unique<Name> name =
1396 MakeUnique(property->key()->AsLiteral()->AsPropertyName()); 1408 MakeUnique(property->key()->AsLiteral()->AsPropertyName());
1397 old_value = NewNode(javascript()->LoadNamed(name), object); 1409 old_value = NewNode(javascript()->LoadNamed(name), object);
1398 PrepareFrameState(old_value, property->LoadId(), kPushOutput); 1410 PrepareFrameState(old_value, property->LoadId(),
1411 OutputFrameStateCombine::Push());
1399 stack_depth = 1; 1412 stack_depth = 1;
1400 break; 1413 break;
1401 } 1414 }
1402 case KEYED_PROPERTY: { 1415 case KEYED_PROPERTY: {
1403 VisitForValue(property->obj()); 1416 VisitForValue(property->obj());
1404 VisitForValue(property->key()); 1417 VisitForValue(property->key());
1405 Node* key = environment()->Top(); 1418 Node* key = environment()->Top();
1406 Node* object = environment()->Peek(1); 1419 Node* object = environment()->Peek(1);
1407 old_value = NewNode(javascript()->LoadProperty(), object, key); 1420 old_value = NewNode(javascript()->LoadProperty(), object, key);
1408 PrepareFrameState(old_value, property->LoadId(), kPushOutput); 1421 PrepareFrameState(old_value, property->LoadId(),
1422 OutputFrameStateCombine::Push());
1409 stack_depth = 2; 1423 stack_depth = 2;
1410 break; 1424 break;
1411 } 1425 }
1412 } 1426 }
1413 1427
1414 // Convert old value into a number. 1428 // Convert old value into a number.
1415 old_value = NewNode(javascript()->ToNumber(), old_value); 1429 old_value = NewNode(javascript()->ToNumber(), old_value);
1416 1430
1417 // Save result for postfix expressions at correct stack depth. 1431 // Save result for postfix expressions at correct stack depth.
1418 if (is_postfix) environment()->Poke(stack_depth, old_value); 1432 if (is_postfix) environment()->Poke(stack_depth, old_value);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 } 1590 }
1577 1591
1578 1592
1579 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { 1593 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) {
1580 Node* value; 1594 Node* value;
1581 if (expr->expression()->IsVariableProxy()) { 1595 if (expr->expression()->IsVariableProxy()) {
1582 // Delete of an unqualified identifier is only allowed in classic mode but 1596 // Delete of an unqualified identifier is only allowed in classic mode but
1583 // deleting "this" is allowed in all language modes. 1597 // deleting "this" is allowed in all language modes.
1584 Variable* variable = expr->expression()->AsVariableProxy()->var(); 1598 Variable* variable = expr->expression()->AsVariableProxy()->var();
1585 DCHECK(strict_mode() == SLOPPY || variable->is_this()); 1599 DCHECK(strict_mode() == SLOPPY || variable->is_this());
1586 value = BuildVariableDelete(variable); 1600 value = BuildVariableDelete(variable, expr->id(),
1601 ast_context()->GetStateCombine());
1587 } else if (expr->expression()->IsProperty()) { 1602 } else if (expr->expression()->IsProperty()) {
1588 Property* property = expr->expression()->AsProperty(); 1603 Property* property = expr->expression()->AsProperty();
1589 VisitForValue(property->obj()); 1604 VisitForValue(property->obj());
1590 VisitForValue(property->key()); 1605 VisitForValue(property->key());
1591 Node* key = environment()->Pop(); 1606 Node* key = environment()->Pop();
1592 Node* object = environment()->Pop(); 1607 Node* object = environment()->Pop();
1593 value = NewNode(javascript()->DeleteProperty(strict_mode()), object, key); 1608 value = NewNode(javascript()->DeleteProperty(strict_mode()), object, key);
1609 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
1594 } else { 1610 } else {
1595 VisitForEffect(expr->expression()); 1611 VisitForEffect(expr->expression());
1596 value = jsgraph()->TrueConstant(); 1612 value = jsgraph()->TrueConstant();
1597 } 1613 }
1598 ast_context()->ProduceValue(value); 1614 ast_context()->ProduceValue(value);
1599 } 1615 }
1600 1616
1601 1617
1602 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) { 1618 void AstGraphBuilder::VisitVoid(UnaryOperation* expr) {
1603 VisitForEffect(expr->expression()); 1619 VisitForEffect(expr->expression());
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 hole_check.Then(); 1745 hole_check.Then();
1730 environment()->Push(for_hole); 1746 environment()->Push(for_hole);
1731 hole_check.Else(); 1747 hole_check.Else();
1732 environment()->Push(not_hole); 1748 environment()->Push(not_hole);
1733 hole_check.End(); 1749 hole_check.End();
1734 return environment()->Pop(); 1750 return environment()->Pop();
1735 } 1751 }
1736 1752
1737 1753
1738 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, 1754 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
1739 Node* not_hole) { 1755 Node* not_hole,
1756 BailoutId bailout_id) {
1740 IfBuilder hole_check(this); 1757 IfBuilder hole_check(this);
1741 Node* the_hole = jsgraph()->TheHoleConstant(); 1758 Node* the_hole = jsgraph()->TheHoleConstant();
1742 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); 1759 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
1743 hole_check.If(check); 1760 hole_check.If(check);
1744 hole_check.Then(); 1761 hole_check.Then();
1745 environment()->Push(BuildThrowReferenceError(variable)); 1762 environment()->Push(BuildThrowReferenceError(variable, bailout_id));
1746 hole_check.Else(); 1763 hole_check.Else();
1747 environment()->Push(not_hole); 1764 environment()->Push(not_hole);
1748 hole_check.End(); 1765 hole_check.End();
1749 return environment()->Pop(); 1766 return environment()->Pop();
1750 } 1767 }
1751 1768
1752 1769
1753 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable, 1770 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
1754 BailoutId bailout_id, 1771 BailoutId bailout_id,
1755 ContextualMode contextual_mode) { 1772 ContextualMode contextual_mode) {
1756 Node* the_hole = jsgraph()->TheHoleConstant(); 1773 Node* the_hole = jsgraph()->TheHoleConstant();
1757 VariableMode mode = variable->mode(); 1774 VariableMode mode = variable->mode();
1758 switch (variable->location()) { 1775 switch (variable->location()) {
1759 case Variable::UNALLOCATED: { 1776 case Variable::UNALLOCATED: {
1760 // Global var, const, or let variable. 1777 // Global var, const, or let variable.
1761 Node* global = BuildLoadGlobalObject(); 1778 Node* global = BuildLoadGlobalObject();
1762 Unique<Name> name = MakeUnique(variable->name()); 1779 Unique<Name> name = MakeUnique(variable->name());
1763 const Operator* op = javascript()->LoadNamed(name, contextual_mode); 1780 const Operator* op = javascript()->LoadNamed(name, contextual_mode);
1764 Node* node = NewNode(op, global); 1781 Node* node = NewNode(op, global);
1765 PrepareFrameState(node, bailout_id, kPushOutput); 1782 PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
1766 return node; 1783 return node;
1767 } 1784 }
1768 case Variable::PARAMETER: 1785 case Variable::PARAMETER:
1769 case Variable::LOCAL: { 1786 case Variable::LOCAL: {
1770 // Local var, const, or let variable. 1787 // Local var, const, or let variable.
1771 Node* value = environment()->Lookup(variable); 1788 Node* value = environment()->Lookup(variable);
1772 if (mode == CONST_LEGACY) { 1789 if (mode == CONST_LEGACY) {
1773 // Perform check for uninitialized legacy const variables. 1790 // Perform check for uninitialized legacy const variables.
1774 if (value->op() == the_hole->op()) { 1791 if (value->op() == the_hole->op()) {
1775 value = jsgraph()->UndefinedConstant(); 1792 value = jsgraph()->UndefinedConstant();
1776 } else if (value->opcode() == IrOpcode::kPhi) { 1793 } else if (value->opcode() == IrOpcode::kPhi) {
1777 Node* undefined = jsgraph()->UndefinedConstant(); 1794 Node* undefined = jsgraph()->UndefinedConstant();
1778 value = BuildHoleCheckSilent(value, undefined, value); 1795 value = BuildHoleCheckSilent(value, undefined, value);
1779 } 1796 }
1780 } else if (mode == LET || mode == CONST) { 1797 } else if (mode == LET || mode == CONST) {
1781 // Perform check for uninitialized let/const variables. 1798 // Perform check for uninitialized let/const variables.
1782 if (value->op() == the_hole->op()) { 1799 if (value->op() == the_hole->op()) {
1783 value = BuildThrowReferenceError(variable); 1800 value = BuildThrowReferenceError(variable, bailout_id);
1784 } else if (value->opcode() == IrOpcode::kPhi) { 1801 } else if (value->opcode() == IrOpcode::kPhi) {
1785 value = BuildHoleCheckThrow(value, variable, value); 1802 value = BuildHoleCheckThrow(value, variable, value, bailout_id);
1786 } 1803 }
1787 } 1804 }
1788 return value; 1805 return value;
1789 } 1806 }
1790 case Variable::CONTEXT: { 1807 case Variable::CONTEXT: {
1791 // Context variable (potentially up the context chain). 1808 // Context variable (potentially up the context chain).
1792 int depth = current_scope()->ContextChainLength(variable->scope()); 1809 int depth = current_scope()->ContextChainLength(variable->scope());
1793 bool immutable = variable->maybe_assigned() == kNotAssigned; 1810 bool immutable = variable->maybe_assigned() == kNotAssigned;
1794 const Operator* op = 1811 const Operator* op =
1795 javascript()->LoadContext(depth, variable->index(), immutable); 1812 javascript()->LoadContext(depth, variable->index(), immutable);
1796 Node* value = NewNode(op, current_context()); 1813 Node* value = NewNode(op, current_context());
1797 // TODO(titzer): initialization checks are redundant for already 1814 // TODO(titzer): initialization checks are redundant for already
1798 // initialized immutable context loads, but only specialization knows. 1815 // initialized immutable context loads, but only specialization knows.
1799 // Maybe specializer should be a parameter to the graph builder? 1816 // Maybe specializer should be a parameter to the graph builder?
1800 if (mode == CONST_LEGACY) { 1817 if (mode == CONST_LEGACY) {
1801 // Perform check for uninitialized legacy const variables. 1818 // Perform check for uninitialized legacy const variables.
1802 Node* undefined = jsgraph()->UndefinedConstant(); 1819 Node* undefined = jsgraph()->UndefinedConstant();
1803 value = BuildHoleCheckSilent(value, undefined, value); 1820 value = BuildHoleCheckSilent(value, undefined, value);
1804 } else if (mode == LET || mode == CONST) { 1821 } else if (mode == LET || mode == CONST) {
1805 // Perform check for uninitialized let/const variables. 1822 // Perform check for uninitialized let/const variables.
1806 value = BuildHoleCheckThrow(value, variable, value); 1823 value = BuildHoleCheckThrow(value, variable, value, bailout_id);
1807 } 1824 }
1808 return value; 1825 return value;
1809 } 1826 }
1810 case Variable::LOOKUP: { 1827 case Variable::LOOKUP: {
1811 // Dynamic lookup of context variable (anywhere in the chain). 1828 // Dynamic lookup of context variable (anywhere in the chain).
1812 Node* name = jsgraph()->Constant(variable->name()); 1829 Node* name = jsgraph()->Constant(variable->name());
1813 Runtime::FunctionId function_id = 1830 Runtime::FunctionId function_id =
1814 (contextual_mode == CONTEXTUAL) 1831 (contextual_mode == CONTEXTUAL)
1815 ? Runtime::kLoadLookupSlot 1832 ? Runtime::kLoadLookupSlot
1816 : Runtime::kLoadLookupSlotNoReferenceError; 1833 : Runtime::kLoadLookupSlotNoReferenceError;
1817 const Operator* op = javascript()->Runtime(function_id, 2); 1834 const Operator* op = javascript()->Runtime(function_id, 2);
1818 Node* pair = NewNode(op, current_context(), name); 1835 Node* pair = NewNode(op, current_context(), name);
1836 PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1));
1819 return NewNode(common()->Projection(0), pair); 1837 return NewNode(common()->Projection(0), pair);
1820 } 1838 }
1821 } 1839 }
1822 UNREACHABLE(); 1840 UNREACHABLE();
1823 return NULL; 1841 return NULL;
1824 } 1842 }
1825 1843
1826 1844
1827 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) { 1845 Node* AstGraphBuilder::BuildVariableDelete(
1846 Variable* variable, BailoutId bailout_id,
1847 OutputFrameStateCombine state_combine) {
1828 switch (variable->location()) { 1848 switch (variable->location()) {
1829 case Variable::UNALLOCATED: { 1849 case Variable::UNALLOCATED: {
1830 // Global var, const, or let variable. 1850 // Global var, const, or let variable.
1831 Node* global = BuildLoadGlobalObject(); 1851 Node* global = BuildLoadGlobalObject();
1832 Node* name = jsgraph()->Constant(variable->name()); 1852 Node* name = jsgraph()->Constant(variable->name());
1833 const Operator* op = javascript()->DeleteProperty(strict_mode()); 1853 const Operator* op = javascript()->DeleteProperty(strict_mode());
1834 return NewNode(op, global, name); 1854 Node* result = NewNode(op, global, name);
1855 PrepareFrameState(result, bailout_id, state_combine);
1856 return result;
1835 } 1857 }
1836 case Variable::PARAMETER: 1858 case Variable::PARAMETER:
1837 case Variable::LOCAL: 1859 case Variable::LOCAL:
1838 case Variable::CONTEXT: 1860 case Variable::CONTEXT:
1839 // Local var, const, or let variable or context variable. 1861 // Local var, const, or let variable or context variable.
1840 return variable->is_this() ? jsgraph()->TrueConstant() 1862 return variable->is_this() ? jsgraph()->TrueConstant()
1841 : jsgraph()->FalseConstant(); 1863 : jsgraph()->FalseConstant();
1842 case Variable::LOOKUP: { 1864 case Variable::LOOKUP: {
1843 // Dynamic lookup of context variable (anywhere in the chain). 1865 // Dynamic lookup of context variable (anywhere in the chain).
1844 Node* name = jsgraph()->Constant(variable->name()); 1866 Node* name = jsgraph()->Constant(variable->name());
1845 const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2); 1867 const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
1846 return NewNode(op, current_context(), name); 1868 Node* result = NewNode(op, current_context(), name);
1869 PrepareFrameState(result, bailout_id, state_combine);
1870 return result;
1847 } 1871 }
1848 } 1872 }
1849 UNREACHABLE(); 1873 UNREACHABLE();
1850 return NULL; 1874 return NULL;
1851 } 1875 }
1852 1876
1853 1877
1854 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value, 1878 Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
1855 Token::Value op, 1879 Token::Value op,
1856 BailoutId bailout_id) { 1880 BailoutId bailout_id) {
(...skipping 21 matching lines...) Expand all
1878 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { 1902 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
1879 // Non-initializing assignments to legacy const is ignored. 1903 // Non-initializing assignments to legacy const is ignored.
1880 return value; 1904 return value;
1881 } else if (mode == LET && op != Token::INIT_LET) { 1905 } else if (mode == LET && op != Token::INIT_LET) {
1882 // Perform an initialization check for let declared variables. 1906 // Perform an initialization check for let declared variables.
1883 // Also note that the dynamic hole-check is only done to ensure that 1907 // Also note that the dynamic hole-check is only done to ensure that
1884 // this does not break in the presence of do-expressions within the 1908 // this does not break in the presence of do-expressions within the
1885 // temporal dead zone of a let declared variable. 1909 // temporal dead zone of a let declared variable.
1886 Node* current = environment()->Lookup(variable); 1910 Node* current = environment()->Lookup(variable);
1887 if (current->op() == the_hole->op()) { 1911 if (current->op() == the_hole->op()) {
1888 value = BuildThrowReferenceError(variable); 1912 value = BuildThrowReferenceError(variable, bailout_id);
1889 } else if (value->opcode() == IrOpcode::kPhi) { 1913 } else if (value->opcode() == IrOpcode::kPhi) {
1890 value = BuildHoleCheckThrow(current, variable, value); 1914 value = BuildHoleCheckThrow(current, variable, value, bailout_id);
1891 } 1915 }
1892 } else if (mode == CONST && op != Token::INIT_CONST) { 1916 } else if (mode == CONST && op != Token::INIT_CONST) {
1893 // All assignments to const variables are early errors. 1917 // All assignments to const variables are early errors.
1894 UNREACHABLE(); 1918 UNREACHABLE();
1895 } 1919 }
1896 environment()->Bind(variable, value); 1920 environment()->Bind(variable, value);
1897 return value; 1921 return value;
1898 case Variable::CONTEXT: { 1922 case Variable::CONTEXT: {
1899 // Context variable (potentially up the context chain). 1923 // Context variable (potentially up the context chain).
1900 int depth = current_scope()->ContextChainLength(variable->scope()); 1924 int depth = current_scope()->ContextChainLength(variable->scope());
1901 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { 1925 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
1902 // Perform an initialization check for legacy const variables. 1926 // Perform an initialization check for legacy const variables.
1903 const Operator* op = 1927 const Operator* op =
1904 javascript()->LoadContext(depth, variable->index(), false); 1928 javascript()->LoadContext(depth, variable->index(), false);
1905 Node* current = NewNode(op, current_context()); 1929 Node* current = NewNode(op, current_context());
1906 value = BuildHoleCheckSilent(current, value, current); 1930 value = BuildHoleCheckSilent(current, value, current);
1907 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { 1931 } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
1908 // Non-initializing assignments to legacy const is ignored. 1932 // Non-initializing assignments to legacy const is ignored.
1909 return value; 1933 return value;
1910 } else if (mode == LET && op != Token::INIT_LET) { 1934 } else if (mode == LET && op != Token::INIT_LET) {
1911 // Perform an initialization check for let declared variables. 1935 // Perform an initialization check for let declared variables.
1912 const Operator* op = 1936 const Operator* op =
1913 javascript()->LoadContext(depth, variable->index(), false); 1937 javascript()->LoadContext(depth, variable->index(), false);
1914 Node* current = NewNode(op, current_context()); 1938 Node* current = NewNode(op, current_context());
1915 value = BuildHoleCheckThrow(current, variable, value); 1939 value = BuildHoleCheckThrow(current, variable, value, bailout_id);
1916 } else if (mode == CONST && op != Token::INIT_CONST) { 1940 } else if (mode == CONST && op != Token::INIT_CONST) {
1917 // All assignments to const variables are early errors. 1941 // All assignments to const variables are early errors.
1918 UNREACHABLE(); 1942 UNREACHABLE();
1919 } 1943 }
1920 const Operator* op = javascript()->StoreContext(depth, variable->index()); 1944 const Operator* op = javascript()->StoreContext(depth, variable->index());
1921 return NewNode(op, current_context(), value); 1945 return NewNode(op, current_context(), value);
1922 } 1946 }
1923 case Variable::LOOKUP: { 1947 case Variable::LOOKUP: {
1924 // Dynamic lookup of context variable (anywhere in the chain). 1948 // Dynamic lookup of context variable (anywhere in the chain).
1925 Node* name = jsgraph()->Constant(variable->name()); 1949 Node* name = jsgraph()->Constant(variable->name());
1926 Node* strict = jsgraph()->Constant(strict_mode()); 1950 Node* strict = jsgraph()->Constant(strict_mode());
1927 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for 1951 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
1928 // initializations of const declarations. 1952 // initializations of const declarations.
1929 const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4); 1953 const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
1930 return NewNode(op, value, current_context(), name, strict); 1954 Node* store = NewNode(op, value, current_context(), name, strict);
1955 PrepareFrameState(store, bailout_id);
1956 return store;
1931 } 1957 }
1932 } 1958 }
1933 UNREACHABLE(); 1959 UNREACHABLE();
1934 return NULL; 1960 return NULL;
1935 } 1961 }
1936 1962
1937 1963
1938 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) { 1964 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
1939 // TODO(sigurds) Use simplified load here once it is ready. 1965 // TODO(sigurds) Use simplified load here once it is ready.
1940 Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, 1966 Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
(...skipping 17 matching lines...) Expand all
1958 return NewNode(load_op, context); 1984 return NewNode(load_op, context);
1959 } 1985 }
1960 1986
1961 1987
1962 Node* AstGraphBuilder::BuildToBoolean(Node* value) { 1988 Node* AstGraphBuilder::BuildToBoolean(Node* value) {
1963 // TODO(mstarzinger): Possible optimization is to NOP for boolean values. 1989 // TODO(mstarzinger): Possible optimization is to NOP for boolean values.
1964 return NewNode(javascript()->ToBoolean(), value); 1990 return NewNode(javascript()->ToBoolean(), value);
1965 } 1991 }
1966 1992
1967 1993
1968 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) { 1994 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
1995 BailoutId bailout_id) {
1969 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. 1996 // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
1970 Node* variable_name = jsgraph()->Constant(variable->name()); 1997 Node* variable_name = jsgraph()->Constant(variable->name());
1971 const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1); 1998 const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
1972 return NewNode(op, variable_name); 1999 Node* call = NewNode(op, variable_name);
2000 PrepareFrameState(call, bailout_id);
2001 return call;
1973 } 2002 }
1974 2003
1975 2004
1976 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { 2005 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
1977 const Operator* js_op; 2006 const Operator* js_op;
1978 switch (op) { 2007 switch (op) {
1979 case Token::BIT_OR: 2008 case Token::BIT_OR:
1980 js_op = javascript()->BitwiseOr(); 2009 js_op = javascript()->BitwiseOr();
1981 break; 2010 break;
1982 case Token::BIT_AND: 2011 case Token::BIT_AND:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() == 2052 DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
2024 IrOpcode::kDead); 2053 IrOpcode::kDead);
2025 NodeProperties::ReplaceFrameStateInput( 2054 NodeProperties::ReplaceFrameStateInput(
2026 node, environment()->Checkpoint(ast_id, combine)); 2055 node, environment()->Checkpoint(ast_id, combine));
2027 } 2056 }
2028 } 2057 }
2029 2058
2030 } 2059 }
2031 } 2060 }
2032 } // namespace v8::internal::compiler 2061 } // 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