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

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

Issue 926013002: TF: Add support for [[HomeObject]] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
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
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 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 } 1350 }
1351 case ObjectLiteral::Property::SETTER: { 1351 case ObjectLiteral::Property::SETTER: {
1352 Node* attr = jsgraph()->Constant(DONT_ENUM); 1352 Node* attr = jsgraph()->Constant(DONT_ENUM);
1353 const Operator* op = javascript()->CallRuntime( 1353 const Operator* op = javascript()->CallRuntime(
1354 Runtime::kDefineSetterPropertyUnchecked, 4); 1354 Runtime::kDefineSetterPropertyUnchecked, 4);
1355 NewNode(op, receiver, key, value, attr); 1355 NewNode(op, receiver, key, value, attr);
1356 break; 1356 break;
1357 } 1357 }
1358 } 1358 }
1359 1359
1360 // TODO(mstarzinger): This is temporary to make "super" work and replicates 1360 AddHomeObjectIfNeeded(property->value(), value, receiver);
1361 // the existing FullCodeGenerator::NeedsHomeObject predicate.
1362 if (FunctionLiteral::NeedsHomeObject(property->value())) {
1363 Unique<Name> name =
1364 MakeUnique(isolate()->factory()->home_object_symbol());
1365 Node* store = NewNode(javascript()->StoreNamed(language_mode(), name),
1366 value, receiver);
1367 PrepareFrameState(store, BailoutId::None());
1368 }
1369 } 1361 }
1370 1362
1371 // Transform both the class literal and the prototype to fast properties. 1363 // Transform both the class literal and the prototype to fast properties.
1372 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); 1364 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1);
1373 NewNode(op, environment()->Pop()); // prototype 1365 NewNode(op, environment()->Pop()); // prototype
1374 NewNode(op, environment()->Pop()); // literal 1366 NewNode(op, environment()->Pop()); // literal
1375 1367
1376 // Assign to class variable. 1368 // Assign to class variable.
1377 if (expr->scope() != NULL) { 1369 if (expr->scope() != NULL) {
1378 DCHECK_NOT_NULL(expr->class_variable_proxy()); 1370 DCHECK_NOT_NULL(expr->class_variable_proxy());
1379 Variable* var = expr->class_variable_proxy()->var(); 1371 Variable* var = expr->class_variable_proxy()->var();
1380 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None()); 1372 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None());
1381 } 1373 }
1382 1374
1383 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine()); 1375 PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
1384 ast_context()->ProduceValue(literal); 1376 ast_context()->ProduceValue(literal);
1385 } 1377 }
1386 1378
1387 1379
1380 void AstGraphBuilder::AddHomeObjectIfNeeded(Expression* expr, Node* function,
1381 Node* home_object) {
1382 if (FunctionLiteral::NeedsHomeObject(expr)) {
1383 Unique<Name> name = MakeUnique(isolate()->factory()->home_object_symbol());
1384 Node* store = NewNode(javascript()->StoreNamed(language_mode(), name),
1385 function, home_object);
1386 PrepareFrameState(store, BailoutId::None());
1387 }
1388 }
1389
1390
1388 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 1391 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
1389 UNREACHABLE(); 1392 UNREACHABLE();
1390 } 1393 }
1391 1394
1392 1395
1393 void AstGraphBuilder::VisitConditional(Conditional* expr) { 1396 void AstGraphBuilder::VisitConditional(Conditional* expr) {
1394 IfBuilder compare_if(this); 1397 IfBuilder compare_if(this);
1395 VisitForTest(expr->condition()); 1398 VisitForTest(expr->condition());
1396 Node* condition = environment()->Pop(); 1399 Node* condition = environment()->Pop();
1397 compare_if.If(condition); 1400 compare_if.If(condition);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 // contains computed properties with an uninitialized value. 1482 // contains computed properties with an uninitialized value.
1480 if (key->value()->IsInternalizedString()) { 1483 if (key->value()->IsInternalizedString()) {
1481 if (property->emit_store()) { 1484 if (property->emit_store()) {
1482 VisitForValue(property->value()); 1485 VisitForValue(property->value());
1483 Node* value = environment()->Pop(); 1486 Node* value = environment()->Pop();
1484 Unique<Name> name = MakeUnique(key->AsPropertyName()); 1487 Unique<Name> name = MakeUnique(key->AsPropertyName());
1485 Node* store = 1488 Node* store =
1486 NewNode(javascript()->StoreNamed(language_mode(), name), 1489 NewNode(javascript()->StoreNamed(language_mode(), name),
1487 literal, value); 1490 literal, value);
1488 PrepareFrameState(store, key->id()); 1491 PrepareFrameState(store, key->id());
1492
1493 AddHomeObjectIfNeeded(property->value(), value, literal);
1489 } else { 1494 } else {
1490 VisitForEffect(property->value()); 1495 VisitForEffect(property->value());
1491 } 1496 }
1492 break; 1497 break;
1493 } 1498 }
1494 environment()->Push(literal); // Duplicate receiver. 1499 environment()->Push(literal); // Duplicate receiver.
1495 VisitForValue(property->key()); 1500 VisitForValue(property->key());
1496 VisitForValue(property->value()); 1501 VisitForValue(property->value());
1497 Node* value = environment()->Pop(); 1502 Node* value = environment()->Pop();
1498 Node* key = environment()->Pop(); 1503 Node* key = environment()->Pop();
1499 Node* receiver = environment()->Pop(); 1504 Node* receiver = environment()->Pop();
1500 if (property->emit_store()) { 1505 if (property->emit_store()) {
1501 Node* language = jsgraph()->Constant(SLOPPY); 1506 Node* language = jsgraph()->Constant(SLOPPY);
1502 const Operator* op = 1507 const Operator* op =
1503 javascript()->CallRuntime(Runtime::kSetProperty, 4); 1508 javascript()->CallRuntime(Runtime::kSetProperty, 4);
1504 NewNode(op, receiver, key, value, language); 1509 NewNode(op, receiver, key, value, language);
1510
1511 AddHomeObjectIfNeeded(property->value(), value, receiver);
1505 } 1512 }
1506 break; 1513 break;
1507 } 1514 }
1508 case ObjectLiteral::Property::PROTOTYPE: { 1515 case ObjectLiteral::Property::PROTOTYPE: {
1509 environment()->Push(literal); // Duplicate receiver. 1516 environment()->Push(literal); // Duplicate receiver.
1510 VisitForValue(property->value()); 1517 VisitForValue(property->value());
1511 Node* value = environment()->Pop(); 1518 Node* value = environment()->Pop();
1512 Node* receiver = environment()->Pop(); 1519 Node* receiver = environment()->Pop();
1513 DCHECK(property->emit_store()); 1520 DCHECK(property->emit_store());
1514 const Operator* op = 1521 const Operator* op =
(...skipping 15 matching lines...) Expand all
1530 break; 1537 break;
1531 } 1538 }
1532 } 1539 }
1533 1540
1534 // Create nodes to define accessors, using only a single call to the runtime 1541 // Create nodes to define accessors, using only a single call to the runtime
1535 // for each pair of corresponding getters and setters. 1542 // for each pair of corresponding getters and setters.
1536 for (AccessorTable::Iterator it = accessor_table.begin(); 1543 for (AccessorTable::Iterator it = accessor_table.begin();
1537 it != accessor_table.end(); ++it) { 1544 it != accessor_table.end(); ++it) {
1538 VisitForValue(it->first); 1545 VisitForValue(it->first);
1539 VisitForValueOrNull(it->second->getter); 1546 VisitForValueOrNull(it->second->getter);
1540 VisitForValueOrNull(it->second->setter); 1547 VisitForValueOrNull(it->second->setter);
Michael Starzinger 2015/02/16 18:36:01 If we ever deoptimize while evaluating the setter
1541 Node* setter = environment()->Pop(); 1548 Node* setter = environment()->Pop();
1542 Node* getter = environment()->Pop(); 1549 Node* getter = environment()->Pop();
1543 Node* name = environment()->Pop(); 1550 Node* name = environment()->Pop();
1551 AddHomeObjectIfNeeded(it->second->getter, getter, literal);
1552 AddHomeObjectIfNeeded(it->second->setter, setter, literal);
1544 Node* attr = jsgraph()->Constant(NONE); 1553 Node* attr = jsgraph()->Constant(NONE);
1545 const Operator* op = 1554 const Operator* op =
1546 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1555 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1547 Node* call = NewNode(op, literal, name, getter, setter, attr); 1556 Node* call = NewNode(op, literal, name, getter, setter, attr);
1548 // This should not lazy deopt on a new literal. 1557 // This should not lazy deopt on a new literal.
1549 PrepareFrameState(call, BailoutId::None()); 1558 PrepareFrameState(call, BailoutId::None());
1550 } 1559 }
1551 1560
1552 // Object literals have two parts. The "static" part on the left contains no 1561 // Object literals have two parts. The "static" part on the left contains no
1553 // computed property names, and so we can compute its map ahead of time; see 1562 // computed property names, and so we can compute its map ahead of time; see
(...skipping 12 matching lines...) Expand all
1566 environment()->Push(BuildToName(environment()->Pop(), 1575 environment()->Push(BuildToName(environment()->Pop(),
1567 expr->GetIdForProperty(property_index))); 1576 expr->GetIdForProperty(property_index)));
1568 // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should 1577 // TODO(mstarzinger): For ObjectLiteral::Property::PROTOTYPE the key should
1569 // not be on the operand stack while the value is being evaluated. Come up 1578 // not be on the operand stack while the value is being evaluated. Come up
1570 // with a repro for this and fix it. Also find a nice way to do so. :) 1579 // with a repro for this and fix it. Also find a nice way to do so. :)
1571 VisitForValue(property->value()); 1580 VisitForValue(property->value());
1572 Node* value = environment()->Pop(); 1581 Node* value = environment()->Pop();
1573 Node* key = environment()->Pop(); 1582 Node* key = environment()->Pop();
1574 Node* receiver = environment()->Pop(); 1583 Node* receiver = environment()->Pop();
1575 1584
1585 AddHomeObjectIfNeeded(property->value(), value, receiver);
1586
1576 switch (property->kind()) { 1587 switch (property->kind()) {
1577 case ObjectLiteral::Property::CONSTANT: 1588 case ObjectLiteral::Property::CONSTANT:
1578 case ObjectLiteral::Property::COMPUTED: 1589 case ObjectLiteral::Property::COMPUTED:
1579 case ObjectLiteral::Property::MATERIALIZED_LITERAL: { 1590 case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
1580 Node* attr = jsgraph()->Constant(NONE); 1591 Node* attr = jsgraph()->Constant(NONE);
1581 const Operator* op = 1592 const Operator* op =
1582 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1593 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1583 Node* call = NewNode(op, receiver, key, value, attr); 1594 Node* call = NewNode(op, receiver, key, value, attr);
1584 PrepareFrameState(call, BailoutId::None()); 1595 PrepareFrameState(call, BailoutId::None());
1585 break; 1596 break;
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3131 Node* dead_node = graph()->NewNode(common()->Dead()); 3142 Node* dead_node = graph()->NewNode(common()->Dead());
3132 dead_control_.set(dead_node); 3143 dead_control_.set(dead_node);
3133 return dead_node; 3144 return dead_node;
3134 } 3145 }
3135 return dead_control_.get(); 3146 return dead_control_.get();
3136 } 3147 }
3137 3148
3138 } // namespace compiler 3149 } // namespace compiler
3139 } // namespace internal 3150 } // namespace internal
3140 } // namespace v8 3151 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698