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

Side by Side Diff: src/objects.cc

Issue 996133002: correctly invalidate global cells (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: weak cell check Created 5 years, 9 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 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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 DCHECK(!object->HasFastProperties()); 535 DCHECK(!object->HasFastProperties());
536 Handle<NameDictionary> property_dictionary(object->property_dictionary()); 536 Handle<NameDictionary> property_dictionary(object->property_dictionary());
537 537
538 if (!name->IsUniqueName()) { 538 if (!name->IsUniqueName()) {
539 name = object->GetIsolate()->factory()->InternalizeString( 539 name = object->GetIsolate()->factory()->InternalizeString(
540 Handle<String>::cast(name)); 540 Handle<String>::cast(name));
541 } 541 }
542 542
543 int entry = property_dictionary->FindEntry(name); 543 int entry = property_dictionary->FindEntry(name);
544 if (entry == NameDictionary::kNotFound) { 544 if (entry == NameDictionary::kNotFound) {
545 Handle<Object> store_value = value;
546 if (object->IsGlobalObject()) { 545 if (object->IsGlobalObject()) {
547 store_value = object->GetIsolate()->factory()->NewPropertyCell(value); 546 auto cell = object->GetIsolate()->factory()->NewPropertyCell();
547 cell->set_value(*value);
548 auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined
549 : PropertyCellType::kConstant;
550 details = details.set_cell_type(cell_type);
551 value = cell;
548 } 552 }
553 property_dictionary =
554 NameDictionary::Add(property_dictionary, name, value, details);
555 object->set_properties(*property_dictionary);
556 return;
557 }
549 558
550 property_dictionary = NameDictionary::Add( 559 if (object->IsGlobalObject()) {
551 property_dictionary, name, store_value, details); 560 PropertyCell::UpdateCell(property_dictionary, entry, value, details);
552 object->set_properties(*property_dictionary);
553 return; 561 return;
554 } 562 }
555 563
556 PropertyDetails original_details = property_dictionary->DetailsAt(entry); 564 PropertyDetails original_details = property_dictionary->DetailsAt(entry);
557 int enumeration_index = original_details.dictionary_index(); 565 int enumeration_index = original_details.dictionary_index();
558
559 if (!object->IsGlobalObject()) {
560 DCHECK(enumeration_index > 0);
561 details = PropertyDetails(details.attributes(), details.type(),
562 enumeration_index);
563 property_dictionary->SetEntry(entry, name, value, details);
564 return;
565 }
566
567 Handle<PropertyCell> cell(
568 PropertyCell::cast(property_dictionary->ValueAt(entry)));
569 // Preserve the enumeration index unless the property was deleted.
570 if (cell->value()->IsTheHole()) {
571 enumeration_index = property_dictionary->NextEnumerationIndex();
572 property_dictionary->SetNextEnumerationIndex(enumeration_index + 1);
573 }
574 DCHECK(enumeration_index > 0); 566 DCHECK(enumeration_index > 0);
575 details = PropertyDetails( 567 details = details.set_index(enumeration_index);
576 details.attributes(), details.type(), enumeration_index); 568 property_dictionary->SetEntry(entry, name, value, details);
577 PropertyCell::SetValueInferType(cell, value);
578 // Please note we have to update the property details.
579 property_dictionary->DetailsAtPut(entry, details);
580 } 569 }
581 570
582 571
583 static MaybeHandle<JSObject> FindIndexedAllCanReadHolder( 572 static MaybeHandle<JSObject> FindIndexedAllCanReadHolder(
584 Isolate* isolate, Handle<JSObject> js_object, 573 Isolate* isolate, Handle<JSObject> js_object,
585 PrototypeIterator::WhereToStart where_to_start) { 574 PrototypeIterator::WhereToStart where_to_start) {
586 for (PrototypeIterator iter(isolate, js_object, where_to_start); 575 for (PrototypeIterator iter(isolate, js_object, where_to_start);
587 !iter.IsAtEnd(); iter.Advance()) { 576 !iter.IsAtEnd(); iter.Advance()) {
588 auto curr = PrototypeIterator::GetCurrent(iter); 577 auto curr = PrototypeIterator::GetCurrent(iter);
589 if (!curr->IsJSObject()) break; 578 if (!curr->IsJSObject()) break;
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 } 1760 }
1772 1761
1773 1762
1774 void JSObject::AddSlowProperty(Handle<JSObject> object, 1763 void JSObject::AddSlowProperty(Handle<JSObject> object,
1775 Handle<Name> name, 1764 Handle<Name> name,
1776 Handle<Object> value, 1765 Handle<Object> value,
1777 PropertyAttributes attributes) { 1766 PropertyAttributes attributes) {
1778 DCHECK(!object->HasFastProperties()); 1767 DCHECK(!object->HasFastProperties());
1779 Isolate* isolate = object->GetIsolate(); 1768 Isolate* isolate = object->GetIsolate();
1780 Handle<NameDictionary> dict(object->property_dictionary()); 1769 Handle<NameDictionary> dict(object->property_dictionary());
1770 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid);
1781 if (object->IsGlobalObject()) { 1771 if (object->IsGlobalObject()) {
1782 // In case name is an orphaned property reuse the cell.
1783 int entry = dict->FindEntry(name); 1772 int entry = dict->FindEntry(name);
1773 // If there's a cell there, just invalidate and set the property.
1784 if (entry != NameDictionary::kNotFound) { 1774 if (entry != NameDictionary::kNotFound) {
1785 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); 1775 PropertyCell::UpdateCell(dict, entry, value, details);
1786 PropertyCell::SetValueInferType(cell, value); 1776 // TODO(dcarney): move this to UpdateCell.
1787 // Assign an enumeration index to the property and update 1777 // Need to adjust the details.
1788 // SetNextEnumerationIndex.
1789 int index = dict->NextEnumerationIndex(); 1778 int index = dict->NextEnumerationIndex();
1790 PropertyDetails details(attributes, DATA, index);
1791 dict->SetNextEnumerationIndex(index + 1); 1779 dict->SetNextEnumerationIndex(index + 1);
1792 dict->SetEntry(entry, name, cell, details); 1780 details = dict->DetailsAt(entry).set_index(index);
1781 dict->DetailsAtPut(entry, details);
1793 return; 1782 return;
1794 } 1783 }
1795 value = isolate->factory()->NewPropertyCell(value); 1784 auto cell = isolate->factory()->NewPropertyCell();
1785 cell->set_value(*value);
1786 auto cell_type = value->IsUndefined() ? PropertyCellType::kUndefined
1787 : PropertyCellType::kConstant;
1788 details = details.set_cell_type(cell_type);
1789 value = cell;
1796 } 1790 }
1797 PropertyDetails details(attributes, DATA, 0);
1798 Handle<NameDictionary> result = 1791 Handle<NameDictionary> result =
1799 NameDictionary::Add(dict, name, value, details); 1792 NameDictionary::Add(dict, name, value, details);
1800 if (*dict != *result) object->set_properties(*result); 1793 if (*dict != *result) object->set_properties(*result);
1801 } 1794 }
1802 1795
1803 1796
1804 Context* JSObject::GetCreationContext() { 1797 Context* JSObject::GetCreationContext() {
1805 Object* constructor = this->map()->GetConstructor(); 1798 Object* constructor = this->map()->GetConstructor();
1806 JSFunction* function; 1799 JSFunction* function;
1807 if (!constructor->IsJSFunction()) { 1800 if (!constructor->IsJSFunction()) {
(...skipping 2799 matching lines...) Expand 10 before | Expand all | Expand 10 after
4607 Handle<NameDictionary> dictionary = 4600 Handle<NameDictionary> dictionary =
4608 NameDictionary::New(isolate, property_count); 4601 NameDictionary::New(isolate, property_count);
4609 4602
4610 Handle<DescriptorArray> descs(map->instance_descriptors()); 4603 Handle<DescriptorArray> descs(map->instance_descriptors());
4611 for (int i = 0; i < real_size; i++) { 4604 for (int i = 0; i < real_size; i++) {
4612 PropertyDetails details = descs->GetDetails(i); 4605 PropertyDetails details = descs->GetDetails(i);
4613 Handle<Name> key(descs->GetKey(i)); 4606 Handle<Name> key(descs->GetKey(i));
4614 switch (details.type()) { 4607 switch (details.type()) {
4615 case DATA_CONSTANT: { 4608 case DATA_CONSTANT: {
4616 Handle<Object> value(descs->GetConstant(i), isolate); 4609 Handle<Object> value(descs->GetConstant(i), isolate);
4617 PropertyDetails d(details.attributes(), DATA, i + 1); 4610 PropertyDetails d(details.attributes(), DATA, i + 1,
4611 PropertyCellType::kInvalid);
4618 dictionary = NameDictionary::Add(dictionary, key, value, d); 4612 dictionary = NameDictionary::Add(dictionary, key, value, d);
4619 break; 4613 break;
4620 } 4614 }
4621 case DATA: { 4615 case DATA: {
4622 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4616 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4623 Handle<Object> value; 4617 Handle<Object> value;
4624 if (object->IsUnboxedDoubleField(index)) { 4618 if (object->IsUnboxedDoubleField(index)) {
4625 double old_value = object->RawFastDoublePropertyAt(index); 4619 double old_value = object->RawFastDoublePropertyAt(index);
4626 value = isolate->factory()->NewHeapNumber(old_value); 4620 value = isolate->factory()->NewHeapNumber(old_value);
4627 } else { 4621 } else {
4628 value = handle(object->RawFastPropertyAt(index), isolate); 4622 value = handle(object->RawFastPropertyAt(index), isolate);
4629 if (details.representation().IsDouble()) { 4623 if (details.representation().IsDouble()) {
4630 DCHECK(value->IsMutableHeapNumber()); 4624 DCHECK(value->IsMutableHeapNumber());
4631 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); 4625 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
4632 value = isolate->factory()->NewHeapNumber(old->value()); 4626 value = isolate->factory()->NewHeapNumber(old->value());
4633 } 4627 }
4634 } 4628 }
4635 PropertyDetails d(details.attributes(), DATA, i + 1); 4629 PropertyDetails d(details.attributes(), DATA, i + 1,
4630 PropertyCellType::kInvalid);
4636 dictionary = NameDictionary::Add(dictionary, key, value, d); 4631 dictionary = NameDictionary::Add(dictionary, key, value, d);
4637 break; 4632 break;
4638 } 4633 }
4639 case ACCESSOR: { 4634 case ACCESSOR: {
4640 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4635 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4641 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 4636 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
4642 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); 4637 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4638 PropertyCellType::kInvalid);
4643 dictionary = NameDictionary::Add(dictionary, key, value, d); 4639 dictionary = NameDictionary::Add(dictionary, key, value, d);
4644 break; 4640 break;
4645 } 4641 }
4646 case ACCESSOR_CONSTANT: { 4642 case ACCESSOR_CONSTANT: {
4647 Handle<Object> value(descs->GetCallbacksObject(i), isolate); 4643 Handle<Object> value(descs->GetCallbacksObject(i), isolate);
4648 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); 4644 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4645 PropertyCellType::kInvalid);
4649 dictionary = NameDictionary::Add(dictionary, key, value, d); 4646 dictionary = NameDictionary::Add(dictionary, key, value, d);
4650 break; 4647 break;
4651 } 4648 }
4652 } 4649 }
4653 } 4650 }
4654 4651
4655 // Copy the next enumeration index from instance descriptor. 4652 // Copy the next enumeration index from instance descriptor.
4656 dictionary->SetNextEnumerationIndex(real_size + 1); 4653 dictionary->SetNextEnumerationIndex(real_size + 1);
4657 4654
4658 // From here on we cannot fail and we shouldn't GC anymore. 4655 // From here on we cannot fail and we shouldn't GC anymore.
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4871 Handle<FixedDoubleArray>::cast(array); 4868 Handle<FixedDoubleArray>::cast(array);
4872 if (double_array->is_the_hole(i)) { 4869 if (double_array->is_the_hole(i)) {
4873 value = factory->the_hole_value(); 4870 value = factory->the_hole_value();
4874 } else { 4871 } else {
4875 value = factory->NewHeapNumber(double_array->get_scalar(i)); 4872 value = factory->NewHeapNumber(double_array->get_scalar(i));
4876 } 4873 }
4877 } else { 4874 } else {
4878 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); 4875 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
4879 } 4876 }
4880 if (!value->IsTheHole()) { 4877 if (!value->IsTheHole()) {
4881 PropertyDetails details(NONE, DATA, 0); 4878 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kInvalid);
4882 dictionary = 4879 dictionary =
4883 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); 4880 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
4884 } 4881 }
4885 } 4882 }
4886 return dictionary; 4883 return dictionary;
4887 } 4884 }
4888 4885
4889 4886
4890 Handle<SeededNumberDictionary> JSObject::NormalizeElements( 4887 Handle<SeededNumberDictionary> JSObject::NormalizeElements(
4891 Handle<JSObject> object) { 4888 Handle<JSObject> object) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
5345 5342
5346 5343
5347 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, 5344 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
5348 Handle<Name> name) { 5345 Handle<Name> name) {
5349 DCHECK(!object->HasFastProperties()); 5346 DCHECK(!object->HasFastProperties());
5350 Isolate* isolate = object->GetIsolate(); 5347 Isolate* isolate = object->GetIsolate();
5351 Handle<NameDictionary> dictionary(object->property_dictionary()); 5348 Handle<NameDictionary> dictionary(object->property_dictionary());
5352 int entry = dictionary->FindEntry(name); 5349 int entry = dictionary->FindEntry(name);
5353 DCHECK_NE(NameDictionary::kNotFound, entry); 5350 DCHECK_NE(NameDictionary::kNotFound, entry);
5354 5351
5355 // If we have a global object set the cell to the hole. 5352 // If we have a global object, invalidate the cell and swap in a new one.
5356 if (object->IsGlobalObject()) { 5353 if (object->IsGlobalObject()) {
5357 DCHECK(dictionary->DetailsAt(entry).IsConfigurable()); 5354 auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
5358 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 5355 cell->set_value(isolate->heap()->the_hole_value());
5359 Handle<Object> value = isolate->factory()->the_hole_value(); 5356 // TODO(dcarney): InvalidateForDelete
5360 PropertyCell::SetValueInferType(cell, value); 5357 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type(
5358 PropertyCellType::kDeleted));
5361 return; 5359 return;
5362 } 5360 }
5363 5361
5364 NameDictionary::DeleteProperty(dictionary, entry); 5362 NameDictionary::DeleteProperty(dictionary, entry);
5365 Handle<NameDictionary> new_properties = 5363 Handle<NameDictionary> new_properties =
5366 NameDictionary::Shrink(dictionary, name); 5364 NameDictionary::Shrink(dictionary, name);
5367 object->set_properties(*new_properties); 5365 object->set_properties(*new_properties);
5368 } 5366 }
5369 5367
5370 5368
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
6423 Object* setter, 6421 Object* setter,
6424 PropertyAttributes attributes) { 6422 PropertyAttributes attributes) {
6425 int entry = dictionary->FindEntry(index); 6423 int entry = dictionary->FindEntry(index);
6426 if (entry != SeededNumberDictionary::kNotFound) { 6424 if (entry != SeededNumberDictionary::kNotFound) {
6427 Object* result = dictionary->ValueAt(entry); 6425 Object* result = dictionary->ValueAt(entry);
6428 PropertyDetails details = dictionary->DetailsAt(entry); 6426 PropertyDetails details = dictionary->DetailsAt(entry);
6429 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) { 6427 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) {
6430 DCHECK(details.IsConfigurable()); 6428 DCHECK(details.IsConfigurable());
6431 if (details.attributes() != attributes) { 6429 if (details.attributes() != attributes) {
6432 dictionary->DetailsAtPut( 6430 dictionary->DetailsAtPut(
6433 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index)); 6431 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index,
6432 PropertyCellType::kInvalid));
6434 } 6433 }
6435 AccessorPair::cast(result)->SetComponents(getter, setter); 6434 AccessorPair::cast(result)->SetComponents(getter, setter);
6436 return true; 6435 return true;
6437 } 6436 }
6438 } 6437 }
6439 return false; 6438 return false;
6440 } 6439 }
6441 6440
6442 6441
6443 void JSObject::DefineElementAccessor(Handle<JSObject> object, 6442 void JSObject::DefineElementAccessor(Handle<JSObject> object,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6525 6524
6526 return false; 6525 return false;
6527 } 6526 }
6528 6527
6529 6528
6530 void JSObject::SetElementCallback(Handle<JSObject> object, 6529 void JSObject::SetElementCallback(Handle<JSObject> object,
6531 uint32_t index, 6530 uint32_t index,
6532 Handle<Object> structure, 6531 Handle<Object> structure,
6533 PropertyAttributes attributes) { 6532 PropertyAttributes attributes) {
6534 Heap* heap = object->GetHeap(); 6533 Heap* heap = object->GetHeap();
6535 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); 6534 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6535 PropertyCellType::kInvalid);
6536 6536
6537 // Normalize elements to make this operation simple. 6537 // Normalize elements to make this operation simple.
6538 bool had_dictionary_elements = object->HasDictionaryElements(); 6538 bool had_dictionary_elements = object->HasDictionaryElements();
6539 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6539 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6540 DCHECK(object->HasDictionaryElements() || 6540 DCHECK(object->HasDictionaryElements() ||
6541 object->HasDictionaryArgumentsElements()); 6541 object->HasDictionaryArgumentsElements());
6542 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6542 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6543 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6543 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6544 details); 6544 details);
6545 dictionary->set_requires_slow_elements(); 6545 dictionary->set_requires_slow_elements();
(...skipping 24 matching lines...) Expand all
6570 void JSObject::SetPropertyCallback(Handle<JSObject> object, 6570 void JSObject::SetPropertyCallback(Handle<JSObject> object,
6571 Handle<Name> name, 6571 Handle<Name> name,
6572 Handle<Object> structure, 6572 Handle<Object> structure,
6573 PropertyAttributes attributes) { 6573 PropertyAttributes attributes) {
6574 PropertyNormalizationMode mode = object->map()->is_prototype_map() 6574 PropertyNormalizationMode mode = object->map()->is_prototype_map()
6575 ? KEEP_INOBJECT_PROPERTIES 6575 ? KEEP_INOBJECT_PROPERTIES
6576 : CLEAR_INOBJECT_PROPERTIES; 6576 : CLEAR_INOBJECT_PROPERTIES;
6577 // Normalize object to make this operation simple. 6577 // Normalize object to make this operation simple.
6578 NormalizeProperties(object, mode, 0, "SetPropertyCallback"); 6578 NormalizeProperties(object, mode, 0, "SetPropertyCallback");
6579 6579
6580 // For the global object allocate a new map to invalidate the global inline
6581 // caches which have a global property cell reference directly in the code.
6582 if (object->IsGlobalObject()) {
6583 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
6584 DCHECK(new_map->is_dictionary_map());
6585 #if TRACE_MAPS
6586 if (FLAG_trace_maps) {
6587 PrintF("[TraceMaps: GlobalPropertyCallback from= %p to= %p ]\n",
6588 reinterpret_cast<void*>(object->map()),
6589 reinterpret_cast<void*>(*new_map));
6590 }
6591 #endif
6592 JSObject::MigrateToMap(object, new_map);
6593
6594 // When running crankshaft, changing the map is not enough. We
6595 // need to deoptimize all functions that rely on this global
6596 // object.
6597 Deoptimizer::DeoptimizeGlobalObject(*object);
6598 }
6599 6580
6600 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6581 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6601 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); 6582 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6583 PropertyCellType::kMutable);
6602 SetNormalizedProperty(object, name, structure, details); 6584 SetNormalizedProperty(object, name, structure, details);
6603 6585
6604 ReoptimizeIfPrototype(object); 6586 ReoptimizeIfPrototype(object);
6605 } 6587 }
6606 6588
6607 6589
6608 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, 6590 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
6609 Handle<Name> name, 6591 Handle<Name> name,
6610 Handle<Object> getter, 6592 Handle<Object> getter,
6611 Handle<Object> setter, 6593 Handle<Object> setter,
(...skipping 6172 matching lines...) Expand 10 before | Expand all | Expand 10 after
12784 // If a value has not been initialized we allow writing to it even if it 12766 // If a value has not been initialized we allow writing to it even if it
12785 // is read-only (a declared const that has not been initialized). 12767 // is read-only (a declared const that has not been initialized).
12786 return WriteToReadOnlyProperty( 12768 return WriteToReadOnlyProperty(
12787 isolate, object, isolate->factory()->NewNumberFromUint(index), 12769 isolate, object, isolate->factory()->NewNumberFromUint(index),
12788 isolate->factory()->undefined_value(), language_mode); 12770 isolate->factory()->undefined_value(), language_mode);
12789 } else { 12771 } else {
12790 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || 12772 DCHECK(details.IsConfigurable() || !details.IsReadOnly() ||
12791 element->IsTheHole()); 12773 element->IsTheHole());
12792 dictionary->UpdateMaxNumberKey(index); 12774 dictionary->UpdateMaxNumberKey(index);
12793 if (set_mode == DEFINE_PROPERTY) { 12775 if (set_mode == DEFINE_PROPERTY) {
12794 details = PropertyDetails(attributes, DATA, details.dictionary_index()); 12776 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12777 PropertyCellType::kInvalid);
12795 dictionary->DetailsAtPut(entry, details); 12778 dictionary->DetailsAtPut(entry, details);
12796 } 12779 }
12797 12780
12798 // Elements of the arguments object in slow mode might be slow aliases. 12781 // Elements of the arguments object in slow mode might be slow aliases.
12799 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12782 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12800 Handle<AliasedArgumentsEntry> entry = 12783 Handle<AliasedArgumentsEntry> entry =
12801 Handle<AliasedArgumentsEntry>::cast(element); 12784 Handle<AliasedArgumentsEntry>::cast(element);
12802 Handle<Context> context(Context::cast(elements->get(0))); 12785 Handle<Context> context(Context::cast(elements->get(0)));
12803 int context_index = entry->aliased_context_slot(); 12786 int context_index = entry->aliased_context_slot();
12804 DCHECK(!context->get(context_index)->IsTheHole()); 12787 DCHECK(!context->get(context_index)->IsTheHole());
(...skipping 22 matching lines...) Expand all
12827 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12810 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12828 Handle<String> name = isolate->factory()->NumberToString(number); 12811 Handle<String> name = isolate->factory()->NumberToString(number);
12829 Handle<Object> args[] = {name}; 12812 Handle<Object> args[] = {name};
12830 THROW_NEW_ERROR(isolate, 12813 THROW_NEW_ERROR(isolate,
12831 NewTypeError("object_not_extensible", 12814 NewTypeError("object_not_extensible",
12832 HandleVector(args, arraysize(args))), 12815 HandleVector(args, arraysize(args))),
12833 Object); 12816 Object);
12834 } 12817 }
12835 } 12818 }
12836 12819
12837 PropertyDetails details(attributes, DATA, 0); 12820 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid);
12838 Handle<SeededNumberDictionary> new_dictionary = 12821 Handle<SeededNumberDictionary> new_dictionary =
12839 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12822 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12840 details); 12823 details);
12841 if (*dictionary != *new_dictionary) { 12824 if (*dictionary != *new_dictionary) {
12842 if (is_arguments) { 12825 if (is_arguments) {
12843 elements->set(1, *new_dictionary); 12826 elements->set(1, *new_dictionary);
12844 } else { 12827 } else {
12845 object->set_elements(*new_dictionary); 12828 object->set_elements(*new_dictionary);
12846 } 12829 }
12847 dictionary = new_dictionary; 12830 dictionary = new_dictionary;
(...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after
14912 return bailout; 14895 return bailout;
14913 } else { 14896 } else {
14914 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 14897 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14915 new_dict, key, value, details); 14898 new_dict, key, value, details);
14916 DCHECK(result.is_identical_to(new_dict)); 14899 DCHECK(result.is_identical_to(new_dict));
14917 USE(result); 14900 USE(result);
14918 } 14901 }
14919 } 14902 }
14920 14903
14921 uint32_t result = pos; 14904 uint32_t result = pos;
14922 PropertyDetails no_details(NONE, DATA, 0); 14905 PropertyDetails no_details(NONE, DATA, 0, PropertyCellType::kInvalid);
14923 while (undefs > 0) { 14906 while (undefs > 0) {
14924 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 14907 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14925 // Adding an entry with the key beyond smi-range requires 14908 // Adding an entry with the key beyond smi-range requires
14926 // allocation. Bailout. 14909 // allocation. Bailout.
14927 return bailout; 14910 return bailout;
14928 } 14911 }
14929 HandleScope scope(isolate); 14912 HandleScope scope(isolate);
14930 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 14913 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14931 new_dict, pos, isolate->factory()->undefined_value(), no_details); 14914 new_dict, pos, isolate->factory()->undefined_value(), no_details);
14932 DCHECK(result.is_identical_to(new_dict)); 14915 DCHECK(result.is_identical_to(new_dict));
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
15273 } 15256 }
15274 array->set(index, double_value); 15257 array->set(index, double_value);
15275 } 15258 }
15276 return array->GetIsolate()->factory()->NewNumber(double_value); 15259 return array->GetIsolate()->factory()->NewNumber(double_value);
15277 } 15260 }
15278 15261
15279 15262
15280 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, 15263 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
15281 Handle<Name> name) { 15264 Handle<Name> name) {
15282 DCHECK(!global->HasFastProperties()); 15265 DCHECK(!global->HasFastProperties());
15283 Isolate* isolate = global->GetIsolate(); 15266 auto dictionary = handle(global->property_dictionary());
15284 int entry = global->property_dictionary()->FindEntry(name); 15267 int entry = dictionary->FindEntry(name);
15285 if (entry != NameDictionary::kNotFound) { 15268 if (entry == NameDictionary::kNotFound) return;
15286 Handle<PropertyCell> cell( 15269 PropertyCell::InvalidateEntry(dictionary, entry);
15287 PropertyCell::cast(global->property_dictionary()->ValueAt(entry)));
15288
15289 Handle<Object> value(cell->value(), isolate);
15290 Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value);
15291 global->property_dictionary()->ValueAtPut(entry, *new_cell);
15292
15293 Handle<Object> hole = isolate->factory()->the_hole_value();
15294 if (*hole != *value) {
15295 PropertyCell::SetValueInferType(cell, hole);
15296 } else {
15297 // If property value was the hole, set it to any other value,
15298 // to ensure that LoadNonexistent ICs execute a miss.
15299 Handle<Object> undefined = isolate->factory()->undefined_value();
15300 PropertyCell::SetValueInferType(cell, undefined);
15301 }
15302 }
15303 } 15270 }
15304 15271
15305 15272
15273 // TODO(dcarney): rename to EnsureEmptyPropertyCell or something.
15306 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 15274 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
15307 Handle<GlobalObject> global, Handle<Name> name) { 15275 Handle<GlobalObject> global, Handle<Name> name) {
15308 DCHECK(!global->HasFastProperties()); 15276 DCHECK(!global->HasFastProperties());
15309 int entry = global->property_dictionary()->FindEntry(name); 15277 auto dictionary = handle(global->property_dictionary());
15310 if (entry == NameDictionary::kNotFound) { 15278 int entry = dictionary->FindEntry(name);
15311 Isolate* isolate = global->GetIsolate(); 15279 Handle<PropertyCell> cell;
15312 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCellWithHole(); 15280 if (entry != NameDictionary::kNotFound) {
15313 PropertyDetails details(NONE, DATA, 0); 15281 // Allow this call to be idempotent.
15314 Handle<NameDictionary> dictionary = NameDictionary::Add( 15282 auto type = dictionary->DetailsAt(entry).cell_type();
15315 handle(global->property_dictionary()), name, cell, details); 15283 if (type == PropertyCellType::kUninitialized ||
15316 global->set_properties(*dictionary); 15284 type == PropertyCellType::kDeleted) {
15285 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
15286 } else {
15287 CHECK(false);
15288 cell = PropertyCell::InvalidateEntry(dictionary, entry);
15289 }
15290 DCHECK(cell->value()->IsTheHole());
15317 return cell; 15291 return cell;
15318 } else {
15319 Object* value = global->property_dictionary()->ValueAt(entry);
15320 DCHECK(value->IsPropertyCell());
15321 return handle(PropertyCell::cast(value));
15322 } 15292 }
15293 Isolate* isolate = global->GetIsolate();
15294 cell = isolate->factory()->NewPropertyCell();
15295 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized);
15296 dictionary = NameDictionary::Add(dictionary, name, cell, details);
15297 global->set_properties(*dictionary);
15298 return cell;
15323 } 15299 }
15324 15300
15325 15301
15326 // This class is used for looking up two character strings in the string table. 15302 // This class is used for looking up two character strings in the string table.
15327 // If we don't have a hit we don't want to waste much time so we unroll the 15303 // If we don't have a hit we don't want to waste much time so we unroll the
15328 // string hash calculation loop here for speed. Doesn't work if the two 15304 // string hash calculation loop here for speed. Doesn't work if the two
15329 // characters form a decimal integer, since such strings have a different hash 15305 // characters form a decimal integer, since such strings have a different hash
15330 // algorithm. 15306 // algorithm.
15331 class TwoCharHashTableKey : public HashTableKey { 15307 class TwoCharHashTableKey : public HashTableKey {
15332 public: 15308 public:
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
15722 15698
15723 // Iterate over the dictionary using the enumeration order and update 15699 // Iterate over the dictionary using the enumeration order and update
15724 // the dictionary with new enumeration indices. 15700 // the dictionary with new enumeration indices.
15725 for (int i = 0; i < length; i++) { 15701 for (int i = 0; i < length; i++) {
15726 int index = Smi::cast(iteration_order->get(i))->value(); 15702 int index = Smi::cast(iteration_order->get(i))->value();
15727 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); 15703 DCHECK(dictionary->IsKey(dictionary->KeyAt(index)));
15728 15704
15729 int enum_index = PropertyDetails::kInitialIndex + i; 15705 int enum_index = PropertyDetails::kInitialIndex + i;
15730 15706
15731 PropertyDetails details = dictionary->DetailsAt(index); 15707 PropertyDetails details = dictionary->DetailsAt(index);
15732 PropertyDetails new_details = 15708 PropertyDetails new_details = details.set_index(enum_index);
15733 PropertyDetails(details.attributes(), details.type(), enum_index);
15734 dictionary->DetailsAtPut(index, new_details); 15709 dictionary->DetailsAtPut(index, new_details);
15735 } 15710 }
15736 15711
15737 // Set the next enumeration index. 15712 // Set the next enumeration index.
15738 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); 15713 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
15739 return iteration_order; 15714 return iteration_order;
15740 } 15715 }
15741 15716
15742 15717
15743 template<typename Derived, typename Shape, typename Key> 15718 template<typename Derived, typename Shape, typename Key>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
15776 if (entry != Dictionary::kNotFound) { 15751 if (entry != Dictionary::kNotFound) {
15777 dictionary->ValueAtPut(entry, *value); 15752 dictionary->ValueAtPut(entry, *value);
15778 return dictionary; 15753 return dictionary;
15779 } 15754 }
15780 15755
15781 // Check whether the dictionary should be extended. 15756 // Check whether the dictionary should be extended.
15782 dictionary = EnsureCapacity(dictionary, 1, key); 15757 dictionary = EnsureCapacity(dictionary, 1, key);
15783 #ifdef DEBUG 15758 #ifdef DEBUG
15784 USE(Shape::AsHandle(dictionary->GetIsolate(), key)); 15759 USE(Shape::AsHandle(dictionary->GetIsolate(), key));
15785 #endif 15760 #endif
15786 PropertyDetails details(NONE, DATA, 0); 15761 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kInvalid);
15787 15762
15788 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); 15763 AddEntry(dictionary, key, value, details, dictionary->Hash(key));
15789 return dictionary; 15764 return dictionary;
15790 } 15765 }
15791 15766
15792 15767
15793 template<typename Derived, typename Shape, typename Key> 15768 template<typename Derived, typename Shape, typename Key>
15794 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( 15769 Handle<Derived> Dictionary<Derived, Shape, Key>::Add(
15795 Handle<Derived> dictionary, 15770 Handle<Derived> dictionary,
15796 Key key, 15771 Key key,
(...skipping 19 matching lines...) Expand all
15816 uint32_t hash) { 15791 uint32_t hash) {
15817 // Compute the key object. 15792 // Compute the key object.
15818 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key); 15793 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
15819 15794
15820 uint32_t entry = dictionary->FindInsertionEntry(hash); 15795 uint32_t entry = dictionary->FindInsertionEntry(hash);
15821 // Insert element at empty or deleted entry 15796 // Insert element at empty or deleted entry
15822 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) { 15797 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
15823 // Assign an enumeration index to the property and update 15798 // Assign an enumeration index to the property and update
15824 // SetNextEnumerationIndex. 15799 // SetNextEnumerationIndex.
15825 int index = dictionary->NextEnumerationIndex(); 15800 int index = dictionary->NextEnumerationIndex();
15826 details = PropertyDetails(details.attributes(), details.type(), index); 15801 details = details.set_index(index);
15827 dictionary->SetNextEnumerationIndex(index + 1); 15802 dictionary->SetNextEnumerationIndex(index + 1);
15828 } 15803 }
15829 dictionary->SetEntry(entry, k, value, details); 15804 dictionary->SetEntry(entry, k, value, details);
15830 DCHECK((dictionary->KeyAt(entry)->IsNumber() || 15805 DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
15831 dictionary->KeyAt(entry)->IsName())); 15806 dictionary->KeyAt(entry)->IsName()));
15832 dictionary->ElementAdded(); 15807 dictionary->ElementAdded();
15833 } 15808 }
15834 15809
15835 15810
15836 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { 15811 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
(...skipping 25 matching lines...) Expand all
15862 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 15837 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15863 return Add(dictionary, key, value, details); 15838 return Add(dictionary, key, value, details);
15864 } 15839 }
15865 15840
15866 15841
15867 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( 15842 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
15868 Handle<UnseededNumberDictionary> dictionary, 15843 Handle<UnseededNumberDictionary> dictionary,
15869 uint32_t key, 15844 uint32_t key,
15870 Handle<Object> value) { 15845 Handle<Object> value) {
15871 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 15846 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15872 return Add(dictionary, key, value, PropertyDetails(NONE, DATA, 0)); 15847 return Add(dictionary, key, value,
15848 PropertyDetails(NONE, DATA, 0, PropertyCellType::kInvalid));
15873 } 15849 }
15874 15850
15875 15851
15876 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( 15852 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
15877 Handle<SeededNumberDictionary> dictionary, 15853 Handle<SeededNumberDictionary> dictionary,
15878 uint32_t key, 15854 uint32_t key,
15879 Handle<Object> value) { 15855 Handle<Object> value) {
15880 dictionary->UpdateMaxNumberKey(key); 15856 dictionary->UpdateMaxNumberKey(key);
15881 return AtPut(dictionary, key, value); 15857 return AtPut(dictionary, key, value);
15882 } 15858 }
(...skipping 10 matching lines...) Expand all
15893 Handle<SeededNumberDictionary> SeededNumberDictionary::Set( 15869 Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
15894 Handle<SeededNumberDictionary> dictionary, 15870 Handle<SeededNumberDictionary> dictionary,
15895 uint32_t key, 15871 uint32_t key,
15896 Handle<Object> value, 15872 Handle<Object> value,
15897 PropertyDetails details) { 15873 PropertyDetails details) {
15898 int entry = dictionary->FindEntry(key); 15874 int entry = dictionary->FindEntry(key);
15899 if (entry == kNotFound) { 15875 if (entry == kNotFound) {
15900 return AddNumberEntry(dictionary, key, value, details); 15876 return AddNumberEntry(dictionary, key, value, details);
15901 } 15877 }
15902 // Preserve enumeration index. 15878 // Preserve enumeration index.
15903 details = PropertyDetails(details.attributes(), 15879 details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
15904 details.type(),
15905 dictionary->DetailsAt(entry).dictionary_index());
15906 Handle<Object> object_key = 15880 Handle<Object> object_key =
15907 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); 15881 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
15908 dictionary->SetEntry(entry, object_key, value, details); 15882 dictionary->SetEntry(entry, object_key, value, details);
15909 return dictionary; 15883 return dictionary;
15910 } 15884 }
15911 15885
15912 15886
15913 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set( 15887 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
15914 Handle<UnseededNumberDictionary> dictionary, 15888 Handle<UnseededNumberDictionary> dictionary,
15915 uint32_t key, 15889 uint32_t key,
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
17073 Handle<Object> result(buffer(), GetIsolate()); 17047 Handle<Object> result(buffer(), GetIsolate());
17074 if (*result != Smi::FromInt(0)) { 17048 if (*result != Smi::FromInt(0)) {
17075 DCHECK(IsExternalArrayElementsKind(map()->elements_kind())); 17049 DCHECK(IsExternalArrayElementsKind(map()->elements_kind()));
17076 return Handle<JSArrayBuffer>::cast(result); 17050 return Handle<JSArrayBuffer>::cast(result);
17077 } 17051 }
17078 Handle<JSTypedArray> self(this); 17052 Handle<JSTypedArray> self(this);
17079 return MaterializeArrayBuffer(self); 17053 return MaterializeArrayBuffer(self);
17080 } 17054 }
17081 17055
17082 17056
17083 HeapType* PropertyCell::type() { 17057 Handle<PropertyCell> PropertyCell::InvalidateEntry(
17084 return static_cast<HeapType*>(type_raw()); 17058 Handle<NameDictionary> dictionary, int entry) {
17059 Isolate* isolate = dictionary->GetIsolate();
17060 // Swap with a copy.
17061 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
17062 auto new_cell = isolate->factory()->NewPropertyCell();
17063 new_cell->set_value(cell->value());
17064 dictionary->ValueAtPut(entry, *new_cell);
17065 bool is_the_hole = cell->value()->IsTheHole();
17066 // Cell is officially mutable henceforth.
17067 auto details = dictionary->DetailsAt(entry);
17068 details = details.set_cell_type(is_the_hole ? PropertyCellType::kDeleted
17069 : PropertyCellType::kMutable);
17070 dictionary->DetailsAtPut(entry, details);
17071 // Old cell is ready for invalidation.
17072 if (is_the_hole) {
17073 cell->set_value(isolate->heap()->undefined_value());
17074 } else {
17075 cell->set_value(isolate->heap()->the_hole_value());
17076 }
17077 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17078 isolate, DependentCode::kPropertyCellChangedGroup);
17079 return new_cell;
17085 } 17080 }
17086 17081
17087 17082
17088 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { 17083 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
17089 DCHECK(IsPropertyCell()); 17084 Handle<Object> value,
17090 set_type_raw(type, ignored); 17085 PropertyDetails details) {
17086 PropertyCellType type = details.cell_type();
17087 DCHECK(!value->IsTheHole());
17088 DCHECK_IMPLIES(cell->value()->IsTheHole(),
17089 type == PropertyCellType::kUninitialized ||
17090 type == PropertyCellType::kDeleted);
17091 switch (type) {
17092 // Only allow a cell to transition once into constant state.
17093 case PropertyCellType::kUninitialized:
17094 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17095 return PropertyCellType::kConstant;
17096 case PropertyCellType::kUndefined:
17097 return PropertyCellType::kConstant;
17098 case PropertyCellType::kConstant:
17099 // No transition.
17100 if (*value == cell->value()) return PropertyCellType::kConstant;
17101 // Fall through.
17102 case PropertyCellType::kMutable:
17103 return PropertyCellType::kMutable;
17104 }
17105 UNREACHABLE();
17106 return PropertyCellType::kMutable;
17091 } 17107 }
17092 17108
17093 17109
17094 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, 17110 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary,
17095 Handle<Object> value) { 17111 int entry, Handle<Object> value,
17096 Isolate* isolate = cell->GetIsolate(); 17112 PropertyDetails details) {
17097 Handle<HeapType> old_type(cell->type(), isolate); 17113 DCHECK(!value->IsTheHole());
17098 Handle<HeapType> new_type = HeapType::Constant(value, isolate); 17114 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
17115 const PropertyDetails original_details = dictionary->DetailsAt(entry);
17116 // Data accesses could be cached in ics or optimized code.
17117 bool invalidate =
17118 original_details.kind() == kData && details.kind() == kAccessor;
17119 int index = original_details.dictionary_index();
17120 auto old_type = original_details.cell_type();
17121 // Preserve the enumeration index unless the property was deleted or never
17122 // initialized.
17123 if (cell->value()->IsTheHole()) {
17124 index = dictionary->NextEnumerationIndex();
17125 dictionary->SetNextEnumerationIndex(index + 1);
17126 // Negative lookup cells must be invalidated.
17127 invalidate = true;
17128 }
17129 DCHECK(index > 0);
17130 details = details.set_index(index);
17099 17131
17100 if (new_type->Is(old_type)) return old_type;
17101
17102 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17103 isolate, DependentCode::kPropertyCellChangedGroup);
17104
17105 if (old_type->Is(HeapType::None()) || old_type->Is(HeapType::Undefined())) {
17106 return new_type;
17107 }
17108
17109 return HeapType::Any(isolate);
17110 }
17111
17112
17113 Handle<Object> PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
17114 Handle<Object> value) {
17115 // Heuristic: if a small-ish string is stored in a previously uninitialized 17132 // Heuristic: if a small-ish string is stored in a previously uninitialized
17116 // property cell, internalize it. 17133 // property cell, internalize it.
17117 const int kMaxLengthForInternalization = 200; 17134 const int kMaxLengthForInternalization = 200;
17118 if ((cell->type()->Is(HeapType::None()) || 17135 if ((old_type == PropertyCellType::kUninitialized ||
17119 cell->type()->Is(HeapType::Undefined())) && 17136 old_type == PropertyCellType::kUndefined) &&
17120 value->IsString()) { 17137 value->IsString()) {
17121 auto string = Handle<String>::cast(value); 17138 auto string = Handle<String>::cast(value);
17122 if (string->length() <= kMaxLengthForInternalization && 17139 if (string->length() <= kMaxLengthForInternalization) {
17123 !string->map()->is_undetectable()) {
17124 value = cell->GetIsolate()->factory()->InternalizeString(string); 17140 value = cell->GetIsolate()->factory()->InternalizeString(string);
17125 } 17141 }
17126 } 17142 }
17143
17144 auto new_type = UpdatedType(cell, value, original_details);
17145 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
17146
17147 // Install new property details and cell value.
17148 details = details.set_cell_type(new_type);
17149 dictionary->DetailsAtPut(entry, details);
17127 cell->set_value(*value); 17150 cell->set_value(*value);
17128 if (!HeapType::Any()->Is(cell->type())) { 17151
17129 Handle<HeapType> new_type = UpdatedType(cell, value); 17152 // Deopt when transitioning from a constant type.
17130 cell->set_type(*new_type); 17153 if (!invalidate && old_type == PropertyCellType::kConstant &&
17154 new_type != PropertyCellType::kConstant) {
17155 auto isolate = dictionary->GetIsolate();
17156 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17157 isolate, DependentCode::kPropertyCellChangedGroup);
17131 } 17158 }
17132 return value; 17159 return value;
17133 } 17160 }
17134 17161
17135 17162
17136 // static 17163 // static
17137 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, 17164 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell,
17138 CompilationInfo* info) { 17165 CompilationInfo* info) {
17139 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( 17166 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo(
17140 handle(cell->dependent_code(), info->isolate()), 17167 handle(cell->dependent_code(), info->isolate()),
17141 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); 17168 DependentCode::kPropertyCellChangedGroup, info->object_wrapper());
17142 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 17169 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
17143 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 17170 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
17144 cell, info->zone()); 17171 cell, info->zone());
17145 } 17172 }
17146 17173
17147 } } // namespace v8::internal 17174 } } // namespace v8::internal
OLDNEW
« src/hydrogen.cc ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698