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

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

Issue 925363003: Cleanup AstGraphBuilder::AddHomeObjectIfNeeded a bit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_trycatch-3
Patch Set: Created 5 years, 10 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
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | 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/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
(...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 ObjectLiteral::Property* property = expr->properties()->at(i); 1338 ObjectLiteral::Property* property = expr->properties()->at(i);
1339 environment()->Push(property->is_static() ? literal : proto); 1339 environment()->Push(property->is_static() ? literal : proto);
1340 1340
1341 VisitForValue(property->key()); 1341 VisitForValue(property->key());
1342 environment()->Push( 1342 environment()->Push(
1343 BuildToName(environment()->Pop(), expr->GetIdForProperty(i))); 1343 BuildToName(environment()->Pop(), expr->GetIdForProperty(i)));
1344 VisitForValue(property->value()); 1344 VisitForValue(property->value());
1345 Node* value = environment()->Pop(); 1345 Node* value = environment()->Pop();
1346 Node* key = environment()->Pop(); 1346 Node* key = environment()->Pop();
1347 Node* receiver = environment()->Pop(); 1347 Node* receiver = environment()->Pop();
1348 BuildSetHomeObject(value, receiver, property->value());
1349
1348 switch (property->kind()) { 1350 switch (property->kind()) {
1349 case ObjectLiteral::Property::CONSTANT: 1351 case ObjectLiteral::Property::CONSTANT:
1350 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1352 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1351 case ObjectLiteral::Property::PROTOTYPE: 1353 case ObjectLiteral::Property::PROTOTYPE:
1352 UNREACHABLE(); 1354 UNREACHABLE();
1353 case ObjectLiteral::Property::COMPUTED: { 1355 case ObjectLiteral::Property::COMPUTED: {
1354 const Operator* op = 1356 const Operator* op =
1355 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3); 1357 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
1356 NewNode(op, receiver, key, value); 1358 NewNode(op, receiver, key, value);
1357 break; 1359 break;
1358 } 1360 }
1359 case ObjectLiteral::Property::GETTER: { 1361 case ObjectLiteral::Property::GETTER: {
1360 Node* attr = jsgraph()->Constant(DONT_ENUM); 1362 Node* attr = jsgraph()->Constant(DONT_ENUM);
1361 const Operator* op = javascript()->CallRuntime( 1363 const Operator* op = javascript()->CallRuntime(
1362 Runtime::kDefineGetterPropertyUnchecked, 4); 1364 Runtime::kDefineGetterPropertyUnchecked, 4);
1363 NewNode(op, receiver, key, value, attr); 1365 NewNode(op, receiver, key, value, attr);
1364 break; 1366 break;
1365 } 1367 }
1366 case ObjectLiteral::Property::SETTER: { 1368 case ObjectLiteral::Property::SETTER: {
1367 Node* attr = jsgraph()->Constant(DONT_ENUM); 1369 Node* attr = jsgraph()->Constant(DONT_ENUM);
1368 const Operator* op = javascript()->CallRuntime( 1370 const Operator* op = javascript()->CallRuntime(
1369 Runtime::kDefineSetterPropertyUnchecked, 4); 1371 Runtime::kDefineSetterPropertyUnchecked, 4);
1370 NewNode(op, receiver, key, value, attr); 1372 NewNode(op, receiver, key, value, attr);
1371 break; 1373 break;
1372 } 1374 }
1373 } 1375 }
1374
1375 AddHomeObjectIfNeeded(property->value(), value, receiver);
1376 } 1376 }
1377 1377
1378 // Transform both the class literal and the prototype to fast properties. 1378 // Transform both the class literal and the prototype to fast properties.
1379 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); 1379 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1);
1380 NewNode(op, environment()->Pop()); // prototype 1380 NewNode(op, environment()->Pop()); // prototype
1381 NewNode(op, environment()->Pop()); // literal 1381 NewNode(op, environment()->Pop()); // literal
1382 1382
1383 // Assign to class variable. 1383 // Assign to class variable.
1384 if (expr->scope() != NULL) { 1384 if (expr->scope() != NULL) {
1385 DCHECK_NOT_NULL(expr->class_variable_proxy()); 1385 DCHECK_NOT_NULL(expr->class_variable_proxy());
1386 Variable* var = expr->class_variable_proxy()->var(); 1386 Variable* var = expr->class_variable_proxy()->var();
1387 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None()); 1387 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
1388 } 1388 }
1389 1389
1390 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); 1390 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
1391 ast_context()->ProduceValue(literal); 1391 ast_context()->ProduceValue(literal);
1392 } 1392 }
1393 1393
1394 1394
1395 void AstGraphBuilder::AddHomeObjectIfNeeded(Expression* expr, Node* function,
1396 Node* home_object) {
1397 if (FunctionLiteral::NeedsHomeObject(expr)) {
1398 Unique<Name> name = MakeUnique(isolate()->factory()->home_object_symbol());
1399 Node* store = NewNode(javascript()->StoreNamed(language_mode(), name),
1400 function, home_object);
1401 PrepareFrameState(store, BailoutId::None());
1402 }
1403 }
1404
1405
1406 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 1395 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
1407 UNREACHABLE(); 1396 UNREACHABLE();
1408 } 1397 }
1409 1398
1410 1399
1411 void AstGraphBuilder::VisitConditional(Conditional* expr) { 1400 void AstGraphBuilder::VisitConditional(Conditional* expr) {
1412 IfBuilder compare_if(this); 1401 IfBuilder compare_if(this);
1413 VisitForTest(expr->condition()); 1402 VisitForTest(expr->condition());
1414 Node* condition = environment()->Pop(); 1403 Node* condition = environment()->Pop();
1415 compare_if.If(condition); 1404 compare_if.If(condition);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 // contains computed properties with an uninitialized value. 1486 // contains computed properties with an uninitialized value.
1498 if (key->value()->IsInternalizedString()) { 1487 if (key->value()->IsInternalizedString()) {
1499 if (property->emit_store()) { 1488 if (property->emit_store()) {
1500 VisitForValue(property->value()); 1489 VisitForValue(property->value());
1501 Node* value = environment()->Pop(); 1490 Node* value = environment()->Pop();
1502 Unique<Name> name = MakeUnique(key->AsPropertyName()); 1491 Unique<Name> name = MakeUnique(key->AsPropertyName());
1503 Node* store = 1492 Node* store =
1504 NewNode(javascript()->StoreNamed(language_mode(), name), 1493 NewNode(javascript()->StoreNamed(language_mode(), name),
1505 literal, value); 1494 literal, value);
1506 PrepareFrameState(store, key->id()); 1495 PrepareFrameState(store, key->id());
1507 1496 BuildSetHomeObject(value, literal, property->value());
1508 AddHomeObjectIfNeeded(property->value(), value, literal);
1509 } else { 1497 } else {
1510 VisitForEffect(property->value()); 1498 VisitForEffect(property->value());
1511 } 1499 }
1512 break; 1500 break;
1513 } 1501 }
1514 environment()->Push(literal); // Duplicate receiver. 1502 environment()->Push(literal); // Duplicate receiver.
1515 VisitForValue(property->key()); 1503 VisitForValue(property->key());
1516 VisitForValue(property->value()); 1504 VisitForValue(property->value());
1517 Node* value = environment()->Pop(); 1505 Node* value = environment()->Pop();
1518 Node* key = environment()->Pop(); 1506 Node* key = environment()->Pop();
1519 Node* receiver = environment()->Pop(); 1507 Node* receiver = environment()->Pop();
1520 if (property->emit_store()) { 1508 if (property->emit_store()) {
1521 Node* language = jsgraph()->Constant(SLOPPY); 1509 Node* language = jsgraph()->Constant(SLOPPY);
1522 const Operator* op = 1510 const Operator* op =
1523 javascript()->CallRuntime(Runtime::kSetProperty, 4); 1511 javascript()->CallRuntime(Runtime::kSetProperty, 4);
1524 NewNode(op, receiver, key, value, language); 1512 NewNode(op, receiver, key, value, language);
1525 1513 BuildSetHomeObject(value, receiver, property->value());
1526 AddHomeObjectIfNeeded(property->value(), value, receiver);
1527 } 1514 }
1528 break; 1515 break;
1529 } 1516 }
1530 case ObjectLiteral::Property::PROTOTYPE: { 1517 case ObjectLiteral::Property::PROTOTYPE: {
1531 environment()->Push(literal); // Duplicate receiver. 1518 environment()->Push(literal); // Duplicate receiver.
1532 VisitForValue(property->value()); 1519 VisitForValue(property->value());
1533 Node* value = environment()->Pop(); 1520 Node* value = environment()->Pop();
1534 Node* receiver = environment()->Pop(); 1521 Node* receiver = environment()->Pop();
1535 DCHECK(property->emit_store()); 1522 DCHECK(property->emit_store());
1536 const Operator* op = 1523 const Operator* op =
(...skipping 15 matching lines...) Expand all
1552 break; 1539 break;
1553 } 1540 }
1554 } 1541 }
1555 1542
1556 // Create nodes to define accessors, using only a single call to the runtime 1543 // Create nodes to define accessors, using only a single call to the runtime
1557 // for each pair of corresponding getters and setters. 1544 // for each pair of corresponding getters and setters.
1558 for (AccessorTable::Iterator it = accessor_table.begin(); 1545 for (AccessorTable::Iterator it = accessor_table.begin();
1559 it != accessor_table.end(); ++it) { 1546 it != accessor_table.end(); ++it) {
1560 VisitForValue(it->first); 1547 VisitForValue(it->first);
1561 VisitForValueOrNull(it->second->getter); 1548 VisitForValueOrNull(it->second->getter);
1549 BuildSetHomeObject(environment()->Top(), literal, it->second->getter);
1562 VisitForValueOrNull(it->second->setter); 1550 VisitForValueOrNull(it->second->setter);
1551 BuildSetHomeObject(environment()->Top(), literal, it->second->setter);
1563 Node* setter = environment()->Pop(); 1552 Node* setter = environment()->Pop();
1564 Node* getter = environment()->Pop(); 1553 Node* getter = environment()->Pop();
1565 Node* name = environment()->Pop(); 1554 Node* name = environment()->Pop();
1566 AddHomeObjectIfNeeded(it->second->getter, getter, literal);
1567 AddHomeObjectIfNeeded(it->second->setter, setter, literal);
1568 Node* attr = jsgraph()->Constant(NONE); 1555 Node* attr = jsgraph()->Constant(NONE);
1569 const Operator* op = 1556 const Operator* op =
1570 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1557 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1571 Node* call = NewNode(op, literal, name, getter, setter, attr); 1558 Node* call = NewNode(op, literal, name, getter, setter, attr);
1572 // This should not lazy deopt on a new literal. 1559 // This should not lazy deopt on a new literal.
1573 PrepareFrameState(call, BailoutId::None()); 1560 PrepareFrameState(call, BailoutId::None());
1574 } 1561 }
1575 1562
1576 // Object literals have two parts. The "static" part on the left contains no 1563 // Object literals have two parts. The "static" part on the left contains no
1577 // computed property names, and so we can compute its map ahead of time; see 1564 // computed property names, and so we can compute its map ahead of time; see
(...skipping 11 matching lines...) Expand all
1589 VisitForValue(property->key()); 1576 VisitForValue(property->key());
1590 environment()->Push(BuildToName(environment()->Pop(), 1577 environment()->Push(BuildToName(environment()->Pop(),
1591 expr->GetIdForProperty(property_index))); 1578 expr->GetIdForProperty(property_index)));
1592 // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should 1579 // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should
1593 // not be on the operand stack while the value is being evaluated. Come up 1580 // not be on the operand stack while the value is being evaluated. Come up
1594 // with a repro for this and fix it. Also find a nice way to do so. :) 1581 // with a repro for this and fix it. Also find a nice way to do so. :)
1595 VisitForValue(property->value()); 1582 VisitForValue(property->value());
1596 Node* value = environment()->Pop(); 1583 Node* value = environment()->Pop();
1597 Node* key = environment()->Pop(); 1584 Node* key = environment()->Pop();
1598 Node* receiver = environment()->Pop(); 1585 Node* receiver = environment()->Pop();
1599 1586 BuildSetHomeObject(value, receiver, property->value());
1600 AddHomeObjectIfNeeded(property->value(), value, receiver);
1601 1587
1602 switch (property->kind()) { 1588 switch (property->kind()) {
1603 case ObjectLiteral::Property::CONSTANT: 1589 case ObjectLiteral::Property::CONSTANT:
1604 case ObjectLiteral::Property::COMPUTED: 1590 case ObjectLiteral::Property::COMPUTED:
1605 case ObjectLiteral::Property::MATERIALIZED_LITERAL: { 1591 case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
1606 Node* attr = jsgraph()->Constant(NONE); 1592 Node* attr = jsgraph()->Constant(NONE);
1607 const Operator* op = 1593 const Operator* op =
1608 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1594 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1609 Node* call = NewNode(op, receiver, key, value, attr); 1595 Node* call = NewNode(op, receiver, key, value, attr);
1610 PrepareFrameState(call, BailoutId::None()); 1596 PrepareFrameState(call, BailoutId::None());
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { 2793 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
2808 // TODO(turbofan): Possible optimization is to NOP on name constants. But the 2794 // TODO(turbofan): Possible optimization is to NOP on name constants. But the
2809 // same caveat as with BuildToBoolean applies, and it should be factored out 2795 // same caveat as with BuildToBoolean applies, and it should be factored out
2810 // into a JSOperatorReducer. 2796 // into a JSOperatorReducer.
2811 Node* name = NewNode(javascript()->ToName(), input); 2797 Node* name = NewNode(javascript()->ToName(), input);
2812 PrepareFrameState(name, bailout_id); 2798 PrepareFrameState(name, bailout_id);
2813 return name; 2799 return name;
2814 } 2800 }
2815 2801
2816 2802
2803 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
2804 Expression* expr) {
2805 if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
2806 Unique<Name> name = MakeUnique(isolate()->factory()->home_object_symbol());
2807 const Operator* op = javascript()->StoreNamed(language_mode(), name);
2808 Node* store = NewNode(op, value, home_object);
2809 PrepareFrameState(store, BailoutId::None());
2810 return store;
arv (Not doing code reviews) 2015/02/16 20:09:56 What is the return value used for here?
Michael Starzinger 2015/02/16 20:30:35 It's not used, but for symmetry all builder method
2811 }
2812
2813
2817 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable, 2814 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
2818 BailoutId bailout_id) { 2815 BailoutId bailout_id) {
2819 // TODO(mstarzinger): Should be unified with the VisitThrow implementation. 2816 // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
2820 Node* variable_name = jsgraph()->Constant(variable->name()); 2817 Node* variable_name = jsgraph()->Constant(variable->name());
2821 const Operator* op = 2818 const Operator* op =
2822 javascript()->CallRuntime(Runtime::kThrowReferenceError, 1); 2819 javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
2823 Node* call = NewNode(op, variable_name); 2820 Node* call = NewNode(op, variable_name);
2824 PrepareFrameState(call, bailout_id); 2821 PrepareFrameState(call, bailout_id);
2825 return call; 2822 return call;
2826 } 2823 }
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 Node* dead_node = graph()->NewNode(common()->Dead()); 3186 Node* dead_node = graph()->NewNode(common()->Dead());
3190 dead_control_.set(dead_node); 3187 dead_control_.set(dead_node);
3191 return dead_node; 3188 return dead_node;
3192 } 3189 }
3193 return dead_control_.get(); 3190 return dead_control_.get();
3194 } 3191 }
3195 3192
3196 } // namespace compiler 3193 } // namespace compiler
3197 } // namespace internal 3194 } // namespace internal
3198 } // namespace v8 3195 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698