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 10129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15567 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, | 15569 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, |
15568 Handle<Name> name) { | 15570 Handle<Name> name) { |
15569 DCHECK(!global->HasFastProperties()); | 15571 DCHECK(!global->HasFastProperties()); |
15570 auto dictionary = handle(global->global_dictionary()); | 15572 auto dictionary = handle(global->global_dictionary()); |
15571 int entry = dictionary->FindEntry(name); | 15573 int entry = dictionary->FindEntry(name); |
15572 if (entry == GlobalDictionary::kNotFound) return; | 15574 if (entry == GlobalDictionary::kNotFound) return; |
15573 PropertyCell::InvalidateEntry(dictionary, entry); | 15575 PropertyCell::InvalidateEntry(dictionary, entry); |
15574 } | 15576 } |
15575 | 15577 |
15576 | 15578 |
15577 // TODO(dcarney): rename to EnsureEmptyPropertyCell or something. | 15579 // TODO(ishell): rename to EnsureEmptyPropertyCell or something. |
15578 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( | 15580 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
15579 Handle<GlobalObject> global, Handle<Name> name) { | 15581 Handle<GlobalObject> global, Handle<Name> name) { |
15580 DCHECK(!global->HasFastProperties()); | 15582 DCHECK(!global->HasFastProperties()); |
15581 auto dictionary = handle(global->global_dictionary()); | 15583 auto dictionary = handle(global->global_dictionary()); |
15582 int entry = dictionary->FindEntry(name); | 15584 int entry = dictionary->FindEntry(name); |
15583 Handle<PropertyCell> cell; | 15585 Handle<PropertyCell> cell; |
15584 if (entry != GlobalDictionary::kNotFound) { | 15586 if (entry != GlobalDictionary::kNotFound) { |
15585 // This call should be idempotent. | 15587 // This call should be idempotent. |
15586 DCHECK(dictionary->DetailsAt(entry).cell_type() == | |
15587 PropertyCellType::kUninitialized || | |
15588 dictionary->DetailsAt(entry).cell_type() == | |
15589 PropertyCellType::kInvalidated); | |
15590 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 15588 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
15591 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); | 15589 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 15590 DCHECK(cell->property_details().cell_type() == |
| 15591 PropertyCellType::kUninitialized || |
| 15592 cell->property_details().cell_type() == |
| 15593 PropertyCellType::kInvalidated); |
15592 DCHECK(cell->value()->IsTheHole()); | 15594 DCHECK(cell->value()->IsTheHole()); |
15593 return cell; | 15595 return cell; |
15594 } | 15596 } |
15595 Isolate* isolate = global->GetIsolate(); | 15597 Isolate* isolate = global->GetIsolate(); |
15596 cell = isolate->factory()->NewPropertyCell(); | 15598 cell = isolate->factory()->NewPropertyCell(); |
15597 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); | 15599 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); |
15598 dictionary = GlobalDictionary::Add(dictionary, name, cell, details); | 15600 dictionary = GlobalDictionary::Add(dictionary, name, cell, details); |
15599 global->set_properties(*dictionary); | 15601 global->set_properties(*dictionary); |
15600 return cell; | 15602 return cell; |
15601 } | 15603 } |
(...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17253 Handle<GlobalDictionary> dictionary, int entry) { | 17255 Handle<GlobalDictionary> dictionary, int entry) { |
17254 Isolate* isolate = dictionary->GetIsolate(); | 17256 Isolate* isolate = dictionary->GetIsolate(); |
17255 // Swap with a copy. | 17257 // Swap with a copy. |
17256 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 17258 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
17257 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 17259 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
17258 auto new_cell = isolate->factory()->NewPropertyCell(); | 17260 auto new_cell = isolate->factory()->NewPropertyCell(); |
17259 new_cell->set_value(cell->value()); | 17261 new_cell->set_value(cell->value()); |
17260 dictionary->ValueAtPut(entry, *new_cell); | 17262 dictionary->ValueAtPut(entry, *new_cell); |
17261 bool is_the_hole = cell->value()->IsTheHole(); | 17263 bool is_the_hole = cell->value()->IsTheHole(); |
17262 // Cell is officially mutable henceforth. | 17264 // Cell is officially mutable henceforth. |
17263 auto details = dictionary->DetailsAt(entry); | 17265 PropertyDetails details = cell->property_details(); |
17264 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated | 17266 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated |
17265 : PropertyCellType::kMutable); | 17267 : PropertyCellType::kMutable); |
17266 dictionary->DetailsAtPut(entry, details); | 17268 new_cell->set_property_details(details); |
17267 // Old cell is ready for invalidation. | 17269 // Old cell is ready for invalidation. |
17268 if (is_the_hole) { | 17270 if (is_the_hole) { |
17269 cell->set_value(isolate->heap()->undefined_value()); | 17271 cell->set_value(isolate->heap()->undefined_value()); |
17270 } else { | 17272 } else { |
17271 cell->set_value(isolate->heap()->the_hole_value()); | 17273 cell->set_value(isolate->heap()->the_hole_value()); |
17272 } | 17274 } |
17273 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17275 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17274 isolate, DependentCode::kPropertyCellChangedGroup); | 17276 isolate, DependentCode::kPropertyCellChangedGroup); |
17275 return new_cell; | 17277 return new_cell; |
17276 } | 17278 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17331 UNREACHABLE(); | 17333 UNREACHABLE(); |
17332 return PropertyCellType::kMutable; | 17334 return PropertyCellType::kMutable; |
17333 } | 17335 } |
17334 | 17336 |
17335 | 17337 |
17336 void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, | 17338 void PropertyCell::UpdateCell(Handle<GlobalDictionary> dictionary, int entry, |
17337 Handle<Object> value, PropertyDetails details) { | 17339 Handle<Object> value, PropertyDetails details) { |
17338 DCHECK(!value->IsTheHole()); | 17340 DCHECK(!value->IsTheHole()); |
17339 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); | 17341 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); |
17340 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 17342 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
17341 const PropertyDetails original_details = dictionary->DetailsAt(entry); | 17343 const PropertyDetails original_details = cell->property_details(); |
17342 // Data accesses could be cached in ics or optimized code. | 17344 // Data accesses could be cached in ics or optimized code. |
17343 bool invalidate = | 17345 bool invalidate = |
17344 original_details.kind() == kData && details.kind() == kAccessor; | 17346 original_details.kind() == kData && details.kind() == kAccessor; |
17345 int index = original_details.dictionary_index(); | 17347 int index = original_details.dictionary_index(); |
17346 auto old_type = original_details.cell_type(); | 17348 PropertyCellType old_type = original_details.cell_type(); |
17347 // Preserve the enumeration index unless the property was deleted or never | 17349 // Preserve the enumeration index unless the property was deleted or never |
17348 // initialized. | 17350 // initialized. |
17349 if (cell->value()->IsTheHole()) { | 17351 if (cell->value()->IsTheHole()) { |
17350 index = dictionary->NextEnumerationIndex(); | 17352 index = dictionary->NextEnumerationIndex(); |
17351 dictionary->SetNextEnumerationIndex(index + 1); | 17353 dictionary->SetNextEnumerationIndex(index + 1); |
17352 // Negative lookup cells must be invalidated. | 17354 // Negative lookup cells must be invalidated. |
17353 invalidate = true; | 17355 invalidate = true; |
17354 } | 17356 } |
17355 DCHECK(index > 0); | 17357 DCHECK(index > 0); |
17356 details = details.set_index(index); | 17358 details = details.set_index(index); |
17357 | 17359 |
17358 auto new_type = UpdatedType(cell, value, original_details); | 17360 PropertyCellType new_type = UpdatedType(cell, value, original_details); |
17359 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); | 17361 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); |
17360 | 17362 |
17361 // Install new property details and cell value. | 17363 // Install new property details and cell value. |
17362 details = details.set_cell_type(new_type); | 17364 details = details.set_cell_type(new_type); |
17363 dictionary->DetailsAtPut(entry, details); | 17365 cell->set_property_details(details); |
17364 cell->set_value(*value); | 17366 cell->set_value(*value); |
17365 | 17367 |
17366 // Deopt when transitioning from a constant type. | 17368 // Deopt when transitioning from a constant type. |
17367 if (!invalidate && (old_type != new_type)) { | 17369 if (!invalidate && (old_type != new_type)) { |
17368 auto isolate = dictionary->GetIsolate(); | 17370 auto isolate = dictionary->GetIsolate(); |
17369 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17371 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17370 isolate, DependentCode::kPropertyCellChangedGroup); | 17372 isolate, DependentCode::kPropertyCellChangedGroup); |
17371 } | 17373 } |
17372 } | 17374 } |
17373 | 17375 |
17374 | 17376 |
17375 // static | 17377 // static |
17376 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17378 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
17377 Handle<Object> new_value) { | 17379 Handle<Object> new_value) { |
17378 if (cell->value() != *new_value) { | 17380 if (cell->value() != *new_value) { |
17379 cell->set_value(*new_value); | 17381 cell->set_value(*new_value); |
17380 Isolate* isolate = cell->GetIsolate(); | 17382 Isolate* isolate = cell->GetIsolate(); |
17381 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17383 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17382 isolate, DependentCode::kPropertyCellChangedGroup); | 17384 isolate, DependentCode::kPropertyCellChangedGroup); |
17383 } | 17385 } |
17384 } | 17386 } |
17385 } } // namespace v8::internal | 17387 } } // namespace v8::internal |
OLD | NEW |