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

Side by Side Diff: src/full-codegen/x87/full-codegen-x87.cc

Issue 1341223002: X87: Vector ICs: The Oracle needs to report feedback for the object literals and the count operatio… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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 | « no previous file | 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 __ CallStub(&stub); 1166 __ CallStub(&stub);
1167 } else { 1167 } else {
1168 __ push(Immediate(info)); 1168 __ push(Immediate(info));
1169 __ CallRuntime( 1169 __ CallRuntime(
1170 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); 1170 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1);
1171 } 1171 }
1172 context()->Plug(eax); 1172 context()->Plug(eax);
1173 } 1173 }
1174 1174
1175 1175
1176 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, 1176 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1177 int offset, 1177 FeedbackVectorICSlot slot) {
1178 FeedbackVectorICSlot slot) { 1178 DCHECK(NeedsHomeObject(initializer));
1179 if (NeedsHomeObject(initializer)) { 1179 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1180 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1180 __ mov(StoreDescriptor::NameRegister(),
1181 __ mov(StoreDescriptor::NameRegister(), 1181 Immediate(isolate()->factory()->home_object_symbol()));
1182 Immediate(isolate()->factory()->home_object_symbol())); 1182 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1183 __ mov(StoreDescriptor::ValueRegister(), 1183 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1184 Operand(esp, offset * kPointerSize)); 1184 CallStoreIC();
1185 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1186 CallStoreIC();
1187 }
1188 } 1185 }
1189 1186
1190 1187
1188 void FullCodeGenerator::EmitSetHomeObjectAccumulator(
1189 Expression* initializer, int offset, FeedbackVectorICSlot slot) {
1190 DCHECK(NeedsHomeObject(initializer));
1191 __ mov(StoreDescriptor::ReceiverRegister(), eax);
1192 __ mov(StoreDescriptor::NameRegister(),
1193 Immediate(isolate()->factory()->home_object_symbol()));
1194 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
1195 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1196 CallStoreIC();
1197 }
1198
1199
1191 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1200 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1192 TypeofMode typeof_mode, 1201 TypeofMode typeof_mode,
1193 Label* slow) { 1202 Label* slow) {
1194 Register context = esi; 1203 Register context = esi;
1195 Register temp = edx; 1204 Register temp = edx;
1196 1205
1197 Scope* s = scope(); 1206 Scope* s = scope();
1198 while (s != NULL) { 1207 while (s != NULL) {
1199 if (s->num_heap_slots() > 0) { 1208 if (s->num_heap_slots() > 0) {
1200 if (s->calls_sloppy_eval()) { 1209 if (s->calls_sloppy_eval()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 context()->Plug(eax); 1357 context()->Plug(eax);
1349 break; 1358 break;
1350 } 1359 }
1351 1360
1352 case VariableLocation::PARAMETER: 1361 case VariableLocation::PARAMETER:
1353 case VariableLocation::LOCAL: 1362 case VariableLocation::LOCAL:
1354 case VariableLocation::CONTEXT: { 1363 case VariableLocation::CONTEXT: {
1355 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1364 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1356 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1365 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1357 : "[ Stack variable"); 1366 : "[ Stack variable");
1367
1358 if (NeedsHoleCheckForLoad(proxy)) { 1368 if (NeedsHoleCheckForLoad(proxy)) {
1359 // Let and const need a read barrier. 1369 // Let and const need a read barrier.
1360 Label done; 1370 Label done;
1361 GetVar(eax, var); 1371 GetVar(eax, var);
1362 __ cmp(eax, isolate()->factory()->the_hole_value()); 1372 __ cmp(eax, isolate()->factory()->the_hole_value());
1363 __ j(not_equal, &done, Label::kNear); 1373 __ j(not_equal, &done, Label::kNear);
1364 if (var->mode() == LET || var->mode() == CONST) { 1374 if (var->mode() == LET || var->mode() == CONST) {
1365 // Throw a reference error when using an uninitialized let/const 1375 // Throw a reference error when using an uninitialized let/const
1366 // binding in harmony mode. 1376 // binding in harmony mode.
1367 __ push(Immediate(var->name())); 1377 __ push(Immediate(var->name()));
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 __ mov(FieldOperand(eax, i + kPointerSize), ecx); 1458 __ mov(FieldOperand(eax, i + kPointerSize), ecx);
1449 } 1459 }
1450 if ((size % (2 * kPointerSize)) != 0) { 1460 if ((size % (2 * kPointerSize)) != 0) {
1451 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); 1461 __ mov(edx, FieldOperand(ebx, size - kPointerSize));
1452 __ mov(FieldOperand(eax, size - kPointerSize), edx); 1462 __ mov(FieldOperand(eax, size - kPointerSize), edx);
1453 } 1463 }
1454 context()->Plug(eax); 1464 context()->Plug(eax);
1455 } 1465 }
1456 1466
1457 1467
1458 void FullCodeGenerator::EmitAccessor(Expression* expression) { 1468 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1469 Expression* expression = (property == NULL) ? NULL : property->value();
1459 if (expression == NULL) { 1470 if (expression == NULL) {
1460 __ push(Immediate(isolate()->factory()->null_value())); 1471 __ push(Immediate(isolate()->factory()->null_value()));
1461 } else { 1472 } else {
1462 VisitForStackValue(expression); 1473 VisitForStackValue(expression);
1474 if (NeedsHomeObject(expression)) {
1475 DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1476 property->kind() == ObjectLiteral::Property::SETTER);
1477 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1478 EmitSetHomeObject(expression, offset, property->GetSlot());
1479 }
1463 } 1480 }
1464 } 1481 }
1465 1482
1466 1483
1467 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1484 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1468 Comment cmnt(masm_, "[ ObjectLiteral"); 1485 Comment cmnt(masm_, "[ ObjectLiteral");
1469 1486
1470 Handle<FixedArray> constant_properties = expr->constant_properties(); 1487 Handle<FixedArray> constant_properties = expr->constant_properties();
1471 int flags = expr->ComputeFlags(); 1488 int flags = expr->ComputeFlags();
1472 // If any of the keys would store to the elements array, then we shouldn't 1489 // If any of the keys would store to the elements array, then we shouldn't
(...skipping 15 matching lines...) Expand all
1488 __ CallStub(&stub); 1505 __ CallStub(&stub);
1489 } 1506 }
1490 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1507 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1491 1508
1492 // If result_saved is true the result is on top of the stack. If 1509 // If result_saved is true the result is on top of the stack. If
1493 // result_saved is false the result is in eax. 1510 // result_saved is false the result is in eax.
1494 bool result_saved = false; 1511 bool result_saved = false;
1495 1512
1496 AccessorTable accessor_table(zone()); 1513 AccessorTable accessor_table(zone());
1497 int property_index = 0; 1514 int property_index = 0;
1498 // store_slot_index points to the vector IC slot for the next store IC used.
1499 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
1500 // and must be updated if the number of store ICs emitted here changes.
1501 int store_slot_index = 0;
1502 for (; property_index < expr->properties()->length(); property_index++) { 1515 for (; property_index < expr->properties()->length(); property_index++) {
1503 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1516 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1504 if (property->is_computed_name()) break; 1517 if (property->is_computed_name()) break;
1505 if (property->IsCompileTimeValue()) continue; 1518 if (property->IsCompileTimeValue()) continue;
1506 1519
1507 Literal* key = property->key()->AsLiteral(); 1520 Literal* key = property->key()->AsLiteral();
1508 Expression* value = property->value(); 1521 Expression* value = property->value();
1509 if (!result_saved) { 1522 if (!result_saved) {
1510 __ push(eax); // Save result on the stack 1523 __ push(eax); // Save result on the stack
1511 result_saved = true; 1524 result_saved = true;
1512 } 1525 }
1513 switch (property->kind()) { 1526 switch (property->kind()) {
1514 case ObjectLiteral::Property::CONSTANT: 1527 case ObjectLiteral::Property::CONSTANT:
1515 UNREACHABLE(); 1528 UNREACHABLE();
1516 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1529 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1517 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1530 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1518 // Fall through. 1531 // Fall through.
1519 case ObjectLiteral::Property::COMPUTED: 1532 case ObjectLiteral::Property::COMPUTED:
1520 // It is safe to use [[Put]] here because the boilerplate already 1533 // It is safe to use [[Put]] here because the boilerplate already
1521 // contains computed properties with an uninitialized value. 1534 // contains computed properties with an uninitialized value.
1522 if (key->value()->IsInternalizedString()) { 1535 if (key->value()->IsInternalizedString()) {
1523 if (property->emit_store()) { 1536 if (property->emit_store()) {
1524 VisitForAccumulatorValue(value); 1537 VisitForAccumulatorValue(value);
1525 DCHECK(StoreDescriptor::ValueRegister().is(eax)); 1538 DCHECK(StoreDescriptor::ValueRegister().is(eax));
1526 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 1539 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
1527 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1540 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
1528 if (FLAG_vector_stores) { 1541 if (FLAG_vector_stores) {
1529 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); 1542 EmitLoadStoreICSlot(property->GetSlot(0));
1530 CallStoreIC(); 1543 CallStoreIC();
1531 } else { 1544 } else {
1532 CallStoreIC(key->LiteralFeedbackId()); 1545 CallStoreIC(key->LiteralFeedbackId());
1533 } 1546 }
1534 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1547 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1535
1536 if (NeedsHomeObject(value)) { 1548 if (NeedsHomeObject(value)) {
1537 __ mov(StoreDescriptor::ReceiverRegister(), eax); 1549 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1538 __ mov(StoreDescriptor::NameRegister(),
1539 Immediate(isolate()->factory()->home_object_symbol()));
1540 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0));
1541 if (FLAG_vector_stores) {
1542 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
1543 }
1544 CallStoreIC();
1545 } 1550 }
1546 } else { 1551 } else {
1547 VisitForEffect(value); 1552 VisitForEffect(value);
1548 } 1553 }
1549 break; 1554 break;
1550 } 1555 }
1551 __ push(Operand(esp, 0)); // Duplicate receiver. 1556 __ push(Operand(esp, 0)); // Duplicate receiver.
1552 VisitForStackValue(key); 1557 VisitForStackValue(key);
1553 VisitForStackValue(value); 1558 VisitForStackValue(value);
1554 if (property->emit_store()) { 1559 if (property->emit_store()) {
1555 EmitSetHomeObjectIfNeeded( 1560 if (NeedsHomeObject(value)) {
1556 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); 1561 EmitSetHomeObject(value, 2, property->GetSlot());
1562 }
1557 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode 1563 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode
1558 __ CallRuntime(Runtime::kSetProperty, 4); 1564 __ CallRuntime(Runtime::kSetProperty, 4);
1559 } else { 1565 } else {
1560 __ Drop(3); 1566 __ Drop(3);
1561 } 1567 }
1562 break; 1568 break;
1563 case ObjectLiteral::Property::PROTOTYPE: 1569 case ObjectLiteral::Property::PROTOTYPE:
1564 __ push(Operand(esp, 0)); // Duplicate receiver. 1570 __ push(Operand(esp, 0)); // Duplicate receiver.
1565 VisitForStackValue(value); 1571 VisitForStackValue(value);
1566 DCHECK(property->emit_store()); 1572 DCHECK(property->emit_store());
1567 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1573 __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1568 break; 1574 break;
1569 case ObjectLiteral::Property::GETTER: 1575 case ObjectLiteral::Property::GETTER:
1570 if (property->emit_store()) { 1576 if (property->emit_store()) {
1571 accessor_table.lookup(key)->second->getter = value; 1577 accessor_table.lookup(key)->second->getter = property;
1572 } 1578 }
1573 break; 1579 break;
1574 case ObjectLiteral::Property::SETTER: 1580 case ObjectLiteral::Property::SETTER:
1575 if (property->emit_store()) { 1581 if (property->emit_store()) {
1576 accessor_table.lookup(key)->second->setter = value; 1582 accessor_table.lookup(key)->second->setter = property;
1577 } 1583 }
1578 break; 1584 break;
1579 } 1585 }
1580 } 1586 }
1581 1587
1582 // Emit code to define accessors, using only a single call to the runtime for 1588 // Emit code to define accessors, using only a single call to the runtime for
1583 // each pair of corresponding getters and setters. 1589 // each pair of corresponding getters and setters.
1584 for (AccessorTable::Iterator it = accessor_table.begin(); 1590 for (AccessorTable::Iterator it = accessor_table.begin();
1585 it != accessor_table.end(); 1591 it != accessor_table.end();
1586 ++it) { 1592 ++it) {
1587 __ push(Operand(esp, 0)); // Duplicate receiver. 1593 __ push(Operand(esp, 0)); // Duplicate receiver.
1588 VisitForStackValue(it->first); 1594 VisitForStackValue(it->first);
1595
1589 EmitAccessor(it->second->getter); 1596 EmitAccessor(it->second->getter);
1590 EmitSetHomeObjectIfNeeded(
1591 it->second->getter, 2,
1592 expr->SlotForHomeObject(it->second->getter, &store_slot_index));
1593
1594 EmitAccessor(it->second->setter); 1597 EmitAccessor(it->second->setter);
1595 EmitSetHomeObjectIfNeeded(
1596 it->second->setter, 3,
1597 expr->SlotForHomeObject(it->second->setter, &store_slot_index));
1598 1598
1599 __ push(Immediate(Smi::FromInt(NONE))); 1599 __ push(Immediate(Smi::FromInt(NONE)));
1600 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1600 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1601 } 1601 }
1602 1602
1603 // Object literals have two parts. The "static" part on the left contains no 1603 // Object literals have two parts. The "static" part on the left contains no
1604 // computed property names, and so we can compute its map ahead of time; see 1604 // computed property names, and so we can compute its map ahead of time; see
1605 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1605 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1606 // starts with the first computed property name, and continues with all 1606 // starts with the first computed property name, and continues with all
1607 // properties to its right. All the code from above initializes the static 1607 // properties to its right. All the code from above initializes the static
(...skipping 13 matching lines...) Expand all
1621 __ push(Operand(esp, 0)); // Duplicate receiver. 1621 __ push(Operand(esp, 0)); // Duplicate receiver.
1622 1622
1623 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1623 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1624 DCHECK(!property->is_computed_name()); 1624 DCHECK(!property->is_computed_name());
1625 VisitForStackValue(value); 1625 VisitForStackValue(value);
1626 DCHECK(property->emit_store()); 1626 DCHECK(property->emit_store());
1627 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1627 __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1628 } else { 1628 } else {
1629 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1629 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1630 VisitForStackValue(value); 1630 VisitForStackValue(value);
1631 EmitSetHomeObjectIfNeeded( 1631 if (NeedsHomeObject(value)) {
1632 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); 1632 EmitSetHomeObject(value, 2, property->GetSlot());
1633 }
1633 1634
1634 switch (property->kind()) { 1635 switch (property->kind()) {
1635 case ObjectLiteral::Property::CONSTANT: 1636 case ObjectLiteral::Property::CONSTANT:
1636 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1637 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1637 case ObjectLiteral::Property::COMPUTED: 1638 case ObjectLiteral::Property::COMPUTED:
1638 if (property->emit_store()) { 1639 if (property->emit_store()) {
1639 __ push(Immediate(Smi::FromInt(NONE))); 1640 __ push(Immediate(Smi::FromInt(NONE)));
1640 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1641 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1641 } else { 1642 } else {
1642 __ Drop(3); 1643 __ Drop(3);
(...skipping 21 matching lines...) Expand all
1664 DCHECK(result_saved); 1665 DCHECK(result_saved);
1665 __ push(Operand(esp, 0)); 1666 __ push(Operand(esp, 0));
1666 __ CallRuntime(Runtime::kToFastProperties, 1); 1667 __ CallRuntime(Runtime::kToFastProperties, 1);
1667 } 1668 }
1668 1669
1669 if (result_saved) { 1670 if (result_saved) {
1670 context()->PlugTOS(); 1671 context()->PlugTOS();
1671 } else { 1672 } else {
1672 context()->Plug(eax); 1673 context()->Plug(eax);
1673 } 1674 }
1674
1675 // Verify that compilation exactly consumed the number of store ic slots that
1676 // the ObjectLiteral node had to offer.
1677 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
1678 } 1675 }
1679 1676
1680 1677
1681 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1678 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
1682 Comment cmnt(masm_, "[ ArrayLiteral"); 1679 Comment cmnt(masm_, "[ ArrayLiteral");
1683 1680
1684 expr->BuildConstantElements(isolate()); 1681 expr->BuildConstantElements(isolate());
1685 Handle<FixedArray> constant_elements = expr->constant_elements(); 1682 Handle<FixedArray> constant_elements = expr->constant_elements();
1686 bool has_constant_fast_elements = 1683 bool has_constant_fast_elements =
1687 IsFastObjectElementsKind(expr->constant_elements_kind()); 1684 IsFastObjectElementsKind(expr->constant_elements_kind());
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after
2336 break; 2333 break;
2337 default: 2334 default:
2338 UNREACHABLE(); 2335 UNREACHABLE();
2339 } 2336 }
2340 2337
2341 __ bind(&done); 2338 __ bind(&done);
2342 context()->Plug(eax); 2339 context()->Plug(eax);
2343 } 2340 }
2344 2341
2345 2342
2346 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, 2343 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2347 int* used_store_slots) {
2348 // Constructor is in eax. 2344 // Constructor is in eax.
2349 DCHECK(lit != NULL); 2345 DCHECK(lit != NULL);
2350 __ push(eax); 2346 __ push(eax);
2351 2347
2352 // No access check is needed here since the constructor is created by the 2348 // No access check is needed here since the constructor is created by the
2353 // class literal. 2349 // class literal.
2354 Register scratch = ebx; 2350 Register scratch = ebx;
2355 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); 2351 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
2356 __ Push(scratch); 2352 __ Push(scratch);
2357 2353
(...skipping 11 matching lines...) Expand all
2369 // The static prototype property is read only. We handle the non computed 2365 // The static prototype property is read only. We handle the non computed
2370 // property name case in the parser. Since this is the only case where we 2366 // property name case in the parser. Since this is the only case where we
2371 // need to check for an own read only property we special case this so we do 2367 // need to check for an own read only property we special case this so we do
2372 // not need to do this for every property. 2368 // not need to do this for every property.
2373 if (property->is_static() && property->is_computed_name()) { 2369 if (property->is_static() && property->is_computed_name()) {
2374 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); 2370 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1);
2375 __ push(eax); 2371 __ push(eax);
2376 } 2372 }
2377 2373
2378 VisitForStackValue(value); 2374 VisitForStackValue(value);
2379 EmitSetHomeObjectIfNeeded(value, 2, 2375 if (NeedsHomeObject(value)) {
2380 lit->SlotForHomeObject(value, used_store_slots)); 2376 EmitSetHomeObject(value, 2, property->GetSlot());
2377 }
2381 2378
2382 switch (property->kind()) { 2379 switch (property->kind()) {
2383 case ObjectLiteral::Property::CONSTANT: 2380 case ObjectLiteral::Property::CONSTANT:
2384 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2381 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2385 case ObjectLiteral::Property::PROTOTYPE: 2382 case ObjectLiteral::Property::PROTOTYPE:
2386 UNREACHABLE(); 2383 UNREACHABLE();
2387 case ObjectLiteral::Property::COMPUTED: 2384 case ObjectLiteral::Property::COMPUTED:
2388 __ CallRuntime(Runtime::kDefineClassMethod, 3); 2385 __ CallRuntime(Runtime::kDefineClassMethod, 3);
2389 break; 2386 break;
2390 2387
(...skipping 2749 matching lines...) Expand 10 before | Expand all | Expand 10 after
5140 Assembler::target_address_at(call_target_address, 5137 Assembler::target_address_at(call_target_address,
5141 unoptimized_code)); 5138 unoptimized_code));
5142 return OSR_AFTER_STACK_CHECK; 5139 return OSR_AFTER_STACK_CHECK;
5143 } 5140 }
5144 5141
5145 5142
5146 } // namespace internal 5143 } // namespace internal
5147 } // namespace v8 5144 } // namespace v8
5148 5145
5149 #endif // V8_TARGET_ARCH_X87 5146 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698