| 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 716 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 BuildLazyBailout(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 BuildLazyBailout(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 BuildLazyBailout(value, expr->binary_operation()->id()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 BuildLazyBailout(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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 BuildLazyBailout(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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 BuildLazyBailout(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 BuildLazyBailout(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); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 BuildLazyBailout(value, expr->id(), StateCombineFromAstContext()); |
| 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 259 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 BuildLazyBailout(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 232 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::BuildLazyBailout(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 | 2035 |
| 2047 void AstGraphBuilder::BuildLazyBailoutWithPushedNode(Node* node, | 2036 AstGraphBuilder::OutputFrameStateCombine |
| 2048 BailoutId ast_id) { | 2037 AstGraphBuilder::StateCombineFromAstContext() { |
| 2049 environment()->Push(node); | 2038 return ast_context()->IsEffect() ? IGNORE_OUTPUT : PUSH_OUTPUT; |
| 2050 BuildLazyBailout(node, ast_id); | |
| 2051 environment()->Pop(); | |
| 2052 } | 2039 } |
| 2053 } | 2040 } |
| 2054 } | 2041 } |
| 2055 } // namespace v8::internal::compiler | 2042 } // namespace v8::internal::compiler |
| OLD | NEW |