| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 HeapStringAllocator allocator; | 1524 HeapStringAllocator allocator; |
| 1525 StringStream accumulator(&allocator); | 1525 StringStream accumulator(&allocator); |
| 1526 Cell::cast(this)->value()->ShortPrint(&accumulator); | 1526 Cell::cast(this)->value()->ShortPrint(&accumulator); |
| 1527 os << accumulator.ToCString().get(); | 1527 os << accumulator.ToCString().get(); |
| 1528 break; | 1528 break; |
| 1529 } | 1529 } |
| 1530 case PROPERTY_CELL_TYPE: { | 1530 case PROPERTY_CELL_TYPE: { |
| 1531 os << "PropertyCell for "; | 1531 os << "PropertyCell for "; |
| 1532 HeapStringAllocator allocator; | 1532 HeapStringAllocator allocator; |
| 1533 StringStream accumulator(&allocator); | 1533 StringStream accumulator(&allocator); |
| 1534 PropertyCell::cast(this)->value()->ShortPrint(&accumulator); | 1534 PropertyCell* cell = PropertyCell::cast(this); |
| 1535 os << accumulator.ToCString().get(); | 1535 cell->value()->ShortPrint(&accumulator); |
| 1536 os << accumulator.ToCString().get() << " " << cell->property_details(); |
| 1536 break; | 1537 break; |
| 1537 } | 1538 } |
| 1538 case WEAK_CELL_TYPE: { | 1539 case WEAK_CELL_TYPE: { |
| 1539 os << "WeakCell for "; | 1540 os << "WeakCell for "; |
| 1540 HeapStringAllocator allocator; | 1541 HeapStringAllocator allocator; |
| 1541 StringStream accumulator(&allocator); | 1542 StringStream accumulator(&allocator); |
| 1542 WeakCell::cast(this)->value()->ShortPrint(&accumulator); | 1543 WeakCell::cast(this)->value()->ShortPrint(&accumulator); |
| 1543 os << accumulator.ToCString().get(); | 1544 os << accumulator.ToCString().get(); |
| 1544 break; | 1545 break; |
| 1545 } | 1546 } |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 PropertyAttributes attributes) { | 1810 PropertyAttributes attributes) { |
| 1810 DCHECK(!object->HasFastProperties()); | 1811 DCHECK(!object->HasFastProperties()); |
| 1811 Isolate* isolate = object->GetIsolate(); | 1812 Isolate* isolate = object->GetIsolate(); |
| 1812 if (object->IsGlobalObject()) { | 1813 if (object->IsGlobalObject()) { |
| 1813 Handle<GlobalDictionary> dict(object->global_dictionary()); | 1814 Handle<GlobalDictionary> dict(object->global_dictionary()); |
| 1814 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); | 1815 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
| 1815 int entry = dict->FindEntry(name); | 1816 int entry = dict->FindEntry(name); |
| 1816 // If there's a cell there, just invalidate and set the property. | 1817 // If there's a cell there, just invalidate and set the property. |
| 1817 if (entry != GlobalDictionary::kNotFound) { | 1818 if (entry != GlobalDictionary::kNotFound) { |
| 1818 PropertyCell::UpdateCell(dict, entry, value, details); | 1819 PropertyCell::UpdateCell(dict, entry, value, details); |
| 1819 // TODO(dcarney): move this to UpdateCell. | 1820 // TODO(ishell): move this to UpdateCell. |
| 1820 // Need to adjust the details. | 1821 // Need to adjust the details. |
| 1821 int index = dict->NextEnumerationIndex(); | 1822 int index = dict->NextEnumerationIndex(); |
| 1822 dict->SetNextEnumerationIndex(index + 1); | 1823 dict->SetNextEnumerationIndex(index + 1); |
| 1823 details = dict->DetailsAt(entry).set_index(index); | 1824 PropertyCell* cell = PropertyCell::cast(dict->ValueAt(entry)); |
| 1824 dict->DetailsAtPut(entry, details); | 1825 details = cell->property_details().set_index(index); |
| 1826 cell->set_property_details(details); |
| 1825 | 1827 |
| 1826 } else { | 1828 } else { |
| 1827 auto cell = isolate->factory()->NewPropertyCell(); | 1829 auto cell = isolate->factory()->NewPropertyCell(); |
| 1828 cell->set_value(*value); | 1830 cell->set_value(*value); |
| 1829 auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined | 1831 auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined |
| 1830 : PropertyCellType::kConstant; | 1832 : PropertyCellType::kConstant; |
| 1831 details = details.set_cell_type(cell_type); | 1833 details = details.set_cell_type(cell_type); |
| 1832 value = cell; | 1834 value = cell; |
| 1833 | 1835 |
| 1834 Handle<GlobalDictionary> result = | 1836 Handle<GlobalDictionary> result = |
| (...skipping 3580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5415 Isolate* isolate = object->GetIsolate(); | 5417 Isolate* isolate = object->GetIsolate(); |
| 5416 | 5418 |
| 5417 if (object->IsGlobalObject()) { | 5419 if (object->IsGlobalObject()) { |
| 5418 // If we have a global object, invalidate the cell and swap in a new one. | 5420 // If we have a global object, invalidate the cell and swap in a new one. |
| 5419 Handle<GlobalDictionary> dictionary(object->global_dictionary()); | 5421 Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
| 5420 int entry = dictionary->FindEntry(name); | 5422 int entry = dictionary->FindEntry(name); |
| 5421 DCHECK_NE(GlobalDictionary::kNotFound, entry); | 5423 DCHECK_NE(GlobalDictionary::kNotFound, entry); |
| 5422 | 5424 |
| 5423 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); | 5425 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); |
| 5424 cell->set_value(isolate->heap()->the_hole_value()); | 5426 cell->set_value(isolate->heap()->the_hole_value()); |
| 5425 // TODO(dcarney): InvalidateForDelete | 5427 // TODO(ishell): InvalidateForDelete |
| 5426 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( | 5428 cell->set_property_details( |
| 5427 PropertyCellType::kInvalidated)); | 5429 cell->property_details().set_cell_type(PropertyCellType::kInvalidated)); |
| 5428 } else { | 5430 } else { |
| 5429 Handle<NameDictionary> dictionary(object->property_dictionary()); | 5431 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 5430 int entry = dictionary->FindEntry(name); | 5432 int entry = dictionary->FindEntry(name); |
| 5431 DCHECK_NE(NameDictionary::kNotFound, entry); | 5433 DCHECK_NE(NameDictionary::kNotFound, entry); |
| 5432 | 5434 |
| 5433 NameDictionary::DeleteProperty(dictionary, entry); | 5435 NameDictionary::DeleteProperty(dictionary, entry); |
| 5434 Handle<NameDictionary> new_properties = | 5436 Handle<NameDictionary> new_properties = |
| 5435 NameDictionary::Shrink(dictionary, name); | 5437 NameDictionary::Shrink(dictionary, name); |
| 5436 object->set_properties(*new_properties); | 5438 object->set_properties(*new_properties); |
| 5437 } | 5439 } |
| (...skipping 10174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15612 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, | 15614 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, |
| 15613 Handle<Name> name) { | 15615 Handle<Name> name) { |
| 15614 DCHECK(!global->HasFastProperties()); | 15616 DCHECK(!global->HasFastProperties()); |
| 15615 auto dictionary = handle(global->global_dictionary()); | 15617 auto dictionary = handle(global->global_dictionary()); |
| 15616 int entry = dictionary->FindEntry(name); | 15618 int entry = dictionary->FindEntry(name); |
| 15617 if (entry == GlobalDictionary::kNotFound) return; | 15619 if (entry == GlobalDictionary::kNotFound) return; |
| 15618 PropertyCell::InvalidateEntry(dictionary, entry); | 15620 PropertyCell::InvalidateEntry(dictionary, entry); |
| 15619 } | 15621 } |
| 15620 | 15622 |
| 15621 | 15623 |
| 15622 // TODO(dcarney): rename to EnsureEmptyPropertyCell or something. | 15624 // TODO(ishell): rename to EnsureEmptyPropertyCell or something. |
| 15623 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( | 15625 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
| 15624 Handle<GlobalObject> global, Handle<Name> name) { | 15626 Handle<GlobalObject> global, Handle<Name> name) { |
| 15625 DCHECK(!global->HasFastProperties()); | 15627 DCHECK(!global->HasFastProperties()); |
| 15626 auto dictionary = handle(global->global_dictionary()); | 15628 auto dictionary = handle(global->global_dictionary()); |
| 15627 int entry = dictionary->FindEntry(name); | 15629 int entry = dictionary->FindEntry(name); |
| 15628 Handle<PropertyCell> cell; | 15630 Handle<PropertyCell> cell; |
| 15629 if (entry != GlobalDictionary::kNotFound) { | 15631 if (entry != GlobalDictionary::kNotFound) { |
| 15630 // This call should be idempotent. | 15632 // This call should be idempotent. |
| 15631 DCHECK(dictionary->DetailsAt(entry).cell_type() == | |
| 15632 PropertyCellType::kUninitialized || | |
| 15633 dictionary->DetailsAt(entry).cell_type() == | |
| 15634 PropertyCellType::kInvalidated); | |
| 15635 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 15633 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
| 15636 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); | 15634 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 15635 DCHECK(cell->property_details().cell_type() == |
| 15636 PropertyCellType::kUninitialized || |
| 15637 cell->property_details().cell_type() == |
| 15638 PropertyCellType::kInvalidated); |
| 15637 DCHECK(cell->value()->IsTheHole()); | 15639 DCHECK(cell->value()->IsTheHole()); |
| 15638 return cell; | 15640 return cell; |
| 15639 } | 15641 } |
| 15640 Isolate* isolate = global->GetIsolate(); | 15642 Isolate* isolate = global->GetIsolate(); |
| 15641 cell = isolate->factory()->NewPropertyCell(); | 15643 cell = isolate->factory()->NewPropertyCell(); |
| 15642 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); | 15644 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); |
| 15643 dictionary = GlobalDictionary::Add(dictionary, name, cell, details); | 15645 dictionary = GlobalDictionary::Add(dictionary, name, cell, details); |
| 15644 global->set_properties(*dictionary); | 15646 global->set_properties(*dictionary); |
| 15645 return cell; | 15647 return cell; |
| 15646 } | 15648 } |
| (...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17298 Handle<GlobalDictionary> dictionary, int entry) { | 17300 Handle<GlobalDictionary> dictionary, int entry) { |
| 17299 Isolate* isolate = dictionary->GetIsolate(); | 17301 Isolate* isolate = dictionary->GetIsolate(); |
| 17300 // Swap with a copy. | 17302 // Swap with a copy. |
| 17301 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 17303 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
| 17302 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 17304 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 17303 auto new_cell = isolate->factory()->NewPropertyCell(); | 17305 auto new_cell = isolate->factory()->NewPropertyCell(); |
| 17304 new_cell->set_value(cell->value()); | 17306 new_cell->set_value(cell->value()); |
| 17305 dictionary->ValueAtPut(entry, *new_cell); | 17307 dictionary->ValueAtPut(entry, *new_cell); |
| 17306 bool is_the_hole = cell->value()->IsTheHole(); | 17308 bool is_the_hole = cell->value()->IsTheHole(); |
| 17307 // Cell is officially mutable henceforth. | 17309 // Cell is officially mutable henceforth. |
| 17308 auto details = dictionary->DetailsAt(entry); | 17310 PropertyDetails details = cell->property_details(); |
| 17309 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated | 17311 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated |
| 17310 : PropertyCellType::kMutable); | 17312 : PropertyCellType::kMutable); |
| 17311 dictionary->DetailsAtPut(entry, details); | 17313 new_cell->set_property_details(details); |
| 17312 // Old cell is ready for invalidation. | 17314 // Old cell is ready for invalidation. |
| 17313 if (is_the_hole) { | 17315 if (is_the_hole) { |
| 17314 cell->set_value(isolate->heap()->undefined_value()); | 17316 cell->set_value(isolate->heap()->undefined_value()); |
| 17315 } else { | 17317 } else { |
| 17316 cell->set_value(isolate->heap()->the_hole_value()); | 17318 cell->set_value(isolate->heap()->the_hole_value()); |
| 17317 } | 17319 } |
| 17318 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17320 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17319 isolate, DependentCode::kPropertyCellChangedGroup); | 17321 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17320 return new_cell; | 17322 return new_cell; |
| 17321 } | 17323 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17376 UNREACHABLE(); | 17378 UNREACHABLE(); |
| 17377 return PropertyCellType::kMutable; | 17379 return PropertyCellType::kMutable; |
| 17378 } | 17380 } |
| 17379 | 17381 |
| 17380 | 17382 |
| 17381 void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, | 17383 void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, |
| 17382 Handle<Object> value, PropertyDetails details) { | 17384 Handle<Object> value, PropertyDetails details) { |
| 17383 DCHECK(!value->IsTheHole()); | 17385 DCHECK(!value->IsTheHole()); |
| 17384 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 17386 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
| 17385 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 17387 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 17386 const PropertyDetails original_details = dictionary->DetailsAt(entry); | 17388 const PropertyDetails original_details = cell->property_details(); |
| 17387 // Data accesses could be cached in ics or optimized code. | 17389 // Data accesses could be cached in ics or optimized code. |
| 17388 bool invalidate = | 17390 bool invalidate = |
| 17389 original_details.kind() == kData && details.kind() == kAccessor; | 17391 original_details.kind() == kData && details.kind() == kAccessor; |
| 17390 int index = original_details.dictionary_index(); | 17392 int index = original_details.dictionary_index(); |
| 17391 auto old_type = original_details.cell_type(); | 17393 PropertyCellType old_type = original_details.cell_type(); |
| 17392 // Preserve the enumeration index unless the property was deleted or never | 17394 // Preserve the enumeration index unless the property was deleted or never |
| 17393 // initialized. | 17395 // initialized. |
| 17394 if (cell->value()->IsTheHole()) { | 17396 if (cell->value()->IsTheHole()) { |
| 17395 index = dictionary->NextEnumerationIndex(); | 17397 index = dictionary->NextEnumerationIndex(); |
| 17396 dictionary->SetNextEnumerationIndex(index + 1); | 17398 dictionary->SetNextEnumerationIndex(index + 1); |
| 17397 // Negative lookup cells must be invalidated. | 17399 // Negative lookup cells must be invalidated. |
| 17398 invalidate = true; | 17400 invalidate = true; |
| 17399 } | 17401 } |
| 17400 DCHECK(index > 0); | 17402 DCHECK(index > 0); |
| 17401 details = details.set_index(index); | 17403 details = details.set_index(index); |
| 17402 | 17404 |
| 17403 auto new_type = UpdatedType(cell, value, original_details); | 17405 PropertyCellType new_type = UpdatedType(cell, value, original_details); |
| 17404 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); | 17406 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); |
| 17405 | 17407 |
| 17406 // Install new property details and cell value. | 17408 // Install new property details and cell value. |
| 17407 details = details.set_cell_type(new_type); | 17409 details = details.set_cell_type(new_type); |
| 17408 dictionary->DetailsAtPut(entry, details); | 17410 cell->set_property_details(details); |
| 17409 cell->set_value(*value); | 17411 cell->set_value(*value); |
| 17410 | 17412 |
| 17411 // Deopt when transitioning from a constant type. | 17413 // Deopt when transitioning from a constant type. |
| 17412 if (!invalidate && (old_type != new_type)) { | 17414 if (!invalidate && (old_type != new_type)) { |
| 17413 auto isolate = dictionary->GetIsolate(); | 17415 auto isolate = dictionary->GetIsolate(); |
| 17414 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17416 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17415 isolate, DependentCode::kPropertyCellChangedGroup); | 17417 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17416 } | 17418 } |
| 17417 } | 17419 } |
| 17418 | 17420 |
| 17419 | 17421 |
| 17420 // static | 17422 // static |
| 17421 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17423 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17422 Handle<Object> new_value) { | 17424 Handle<Object> new_value) { |
| 17423 if (cell->value() != *new_value) { | 17425 if (cell->value() != *new_value) { |
| 17424 cell->set_value(*new_value); | 17426 cell->set_value(*new_value); |
| 17425 Isolate* isolate = cell->GetIsolate(); | 17427 Isolate* isolate = cell->GetIsolate(); |
| 17426 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17428 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17427 isolate, DependentCode::kPropertyCellChangedGroup); | 17429 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17428 } | 17430 } |
| 17429 } | 17431 } |
| 17430 } } // namespace v8::internal | 17432 } } // namespace v8::internal |
| OLD | NEW |