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

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: cleanup 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
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2741 matching lines...) Expand 10 before | Expand all | Expand 10 after
4549 Handle<NameDictionary> dictionary = 4542 Handle<NameDictionary> dictionary =
4550 NameDictionary::New(isolate, property_count); 4543 NameDictionary::New(isolate, property_count);
4551 4544
4552 Handle<DescriptorArray> descs(map->instance_descriptors()); 4545 Handle<DescriptorArray> descs(map->instance_descriptors());
4553 for (int i = 0; i < real_size; i++) { 4546 for (int i = 0; i < real_size; i++) {
4554 PropertyDetails details = descs->GetDetails(i); 4547 PropertyDetails details = descs->GetDetails(i);
4555 Handle<Name> key(descs->GetKey(i)); 4548 Handle<Name> key(descs->GetKey(i));
4556 switch (details.type()) { 4549 switch (details.type()) {
4557 case DATA_CONSTANT: { 4550 case DATA_CONSTANT: {
4558 Handle<Object> value(descs->GetConstant(i), isolate); 4551 Handle<Object> value(descs->GetConstant(i), isolate);
4559 PropertyDetails d(details.attributes(), DATA, i + 1); 4552 PropertyDetails d(details.attributes(), DATA, i + 1,
4553 PropertyCellType::kInvalid);
4560 dictionary = NameDictionary::Add(dictionary, key, value, d); 4554 dictionary = NameDictionary::Add(dictionary, key, value, d);
4561 break; 4555 break;
4562 } 4556 }
4563 case DATA: { 4557 case DATA: {
4564 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4558 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4565 Handle<Object> value; 4559 Handle<Object> value;
4566 if (object->IsUnboxedDoubleField(index)) { 4560 if (object->IsUnboxedDoubleField(index)) {
4567 double old_value = object->RawFastDoublePropertyAt(index); 4561 double old_value = object->RawFastDoublePropertyAt(index);
4568 value = isolate->factory()->NewHeapNumber(old_value); 4562 value = isolate->factory()->NewHeapNumber(old_value);
4569 } else { 4563 } else {
4570 value = handle(object->RawFastPropertyAt(index), isolate); 4564 value = handle(object->RawFastPropertyAt(index), isolate);
4571 if (details.representation().IsDouble()) { 4565 if (details.representation().IsDouble()) {
4572 DCHECK(value->IsMutableHeapNumber()); 4566 DCHECK(value->IsMutableHeapNumber());
4573 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); 4567 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
4574 value = isolate->factory()->NewHeapNumber(old->value()); 4568 value = isolate->factory()->NewHeapNumber(old->value());
4575 } 4569 }
4576 } 4570 }
4577 PropertyDetails d(details.attributes(), DATA, i + 1); 4571 PropertyDetails d(details.attributes(), DATA, i + 1,
4572 PropertyCellType::kInvalid);
4578 dictionary = NameDictionary::Add(dictionary, key, value, d); 4573 dictionary = NameDictionary::Add(dictionary, key, value, d);
4579 break; 4574 break;
4580 } 4575 }
4581 case ACCESSOR: { 4576 case ACCESSOR: {
4582 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4577 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4583 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 4578 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
4584 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); 4579 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4580 PropertyCellType::kInvalid);
4585 dictionary = NameDictionary::Add(dictionary, key, value, d); 4581 dictionary = NameDictionary::Add(dictionary, key, value, d);
4586 break; 4582 break;
4587 } 4583 }
4588 case ACCESSOR_CONSTANT: { 4584 case ACCESSOR_CONSTANT: {
4589 Handle<Object> value(descs->GetCallbacksObject(i), isolate); 4585 Handle<Object> value(descs->GetCallbacksObject(i), isolate);
4590 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1); 4586 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4587 PropertyCellType::kInvalid);
4591 dictionary = NameDictionary::Add(dictionary, key, value, d); 4588 dictionary = NameDictionary::Add(dictionary, key, value, d);
4592 break; 4589 break;
4593 } 4590 }
4594 } 4591 }
4595 } 4592 }
4596 4593
4597 // Copy the next enumeration index from instance descriptor. 4594 // Copy the next enumeration index from instance descriptor.
4598 dictionary->SetNextEnumerationIndex(real_size + 1); 4595 dictionary->SetNextEnumerationIndex(real_size + 1);
4599 4596
4600 // From here on we cannot fail and we shouldn't GC anymore. 4597 // From here on we cannot fail and we shouldn't GC anymore.
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
4813 Handle<FixedDoubleArray>::cast(array); 4810 Handle<FixedDoubleArray>::cast(array);
4814 if (double_array->is_the_hole(i)) { 4811 if (double_array->is_the_hole(i)) {
4815 value = factory->the_hole_value(); 4812 value = factory->the_hole_value();
4816 } else { 4813 } else {
4817 value = factory->NewHeapNumber(double_array->get_scalar(i)); 4814 value = factory->NewHeapNumber(double_array->get_scalar(i));
4818 } 4815 }
4819 } else { 4816 } else {
4820 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate); 4817 value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
4821 } 4818 }
4822 if (!value->IsTheHole()) { 4819 if (!value->IsTheHole()) {
4823 PropertyDetails details(NONE, DATA, 0); 4820 PropertyDetails details = PropertyDetails::Empty();
4824 dictionary = 4821 dictionary =
4825 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); 4822 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
4826 } 4823 }
4827 } 4824 }
4828 return dictionary; 4825 return dictionary;
4829 } 4826 }
4830 4827
4831 4828
4832 Handle<SeededNumberDictionary> JSObject::NormalizeElements( 4829 Handle<SeededNumberDictionary> JSObject::NormalizeElements(
4833 Handle<JSObject> object) { 4830 Handle<JSObject> object) {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 5284
5288 5285
5289 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object, 5286 void JSObject::DeleteNormalizedProperty(Handle<JSObject> object,
5290 Handle<Name> name) { 5287 Handle<Name> name) {
5291 DCHECK(!object->HasFastProperties()); 5288 DCHECK(!object->HasFastProperties());
5292 Isolate* isolate = object->GetIsolate(); 5289 Isolate* isolate = object->GetIsolate();
5293 Handle<NameDictionary> dictionary(object->property_dictionary()); 5290 Handle<NameDictionary> dictionary(object->property_dictionary());
5294 int entry = dictionary->FindEntry(name); 5291 int entry = dictionary->FindEntry(name);
5295 DCHECK_NE(NameDictionary::kNotFound, entry); 5292 DCHECK_NE(NameDictionary::kNotFound, entry);
5296 5293
5297 // If we have a global object set the cell to the hole. 5294 // If we have a global object, invalidate the cell and swap in a new one.
5298 if (object->IsGlobalObject()) { 5295 if (object->IsGlobalObject()) {
5299 DCHECK(dictionary->DetailsAt(entry).IsConfigurable()); 5296 auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
5300 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 5297 cell->set_value(isolate->heap()->the_hole_value());
5301 Handle<Object> value = isolate->factory()->the_hole_value(); 5298 // TODO(dcarney): InvalidateForDelete
5302 PropertyCell::SetValueInferType(cell, value); 5299 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type(
5300 PropertyCellType::kDeleted));
5303 return; 5301 return;
5304 } 5302 }
5305 5303
5306 NameDictionary::DeleteProperty(dictionary, entry); 5304 NameDictionary::DeleteProperty(dictionary, entry);
5307 Handle<NameDictionary> new_properties = 5305 Handle<NameDictionary> new_properties =
5308 NameDictionary::Shrink(dictionary, name); 5306 NameDictionary::Shrink(dictionary, name);
5309 object->set_properties(*new_properties); 5307 object->set_properties(*new_properties);
5310 } 5308 }
5311 5309
5312 5310
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
6365 Object* setter, 6363 Object* setter,
6366 PropertyAttributes attributes) { 6364 PropertyAttributes attributes) {
6367 int entry = dictionary->FindEntry(index); 6365 int entry = dictionary->FindEntry(index);
6368 if (entry != SeededNumberDictionary::kNotFound) { 6366 if (entry != SeededNumberDictionary::kNotFound) {
6369 Object* result = dictionary->ValueAt(entry); 6367 Object* result = dictionary->ValueAt(entry);
6370 PropertyDetails details = dictionary->DetailsAt(entry); 6368 PropertyDetails details = dictionary->DetailsAt(entry);
6371 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) { 6369 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) {
6372 DCHECK(details.IsConfigurable()); 6370 DCHECK(details.IsConfigurable());
6373 if (details.attributes() != attributes) { 6371 if (details.attributes() != attributes) {
6374 dictionary->DetailsAtPut( 6372 dictionary->DetailsAtPut(
6375 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index)); 6373 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index,
6374 PropertyCellType::kInvalid));
6376 } 6375 }
6377 AccessorPair::cast(result)->SetComponents(getter, setter); 6376 AccessorPair::cast(result)->SetComponents(getter, setter);
6378 return true; 6377 return true;
6379 } 6378 }
6380 } 6379 }
6381 return false; 6380 return false;
6382 } 6381 }
6383 6382
6384 6383
6385 void JSObject::DefineElementAccessor(Handle<JSObject> object, 6384 void JSObject::DefineElementAccessor(Handle<JSObject> object,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6467 6466
6468 return false; 6467 return false;
6469 } 6468 }
6470 6469
6471 6470
6472 void JSObject::SetElementCallback(Handle<JSObject> object, 6471 void JSObject::SetElementCallback(Handle<JSObject> object,
6473 uint32_t index, 6472 uint32_t index,
6474 Handle<Object> structure, 6473 Handle<Object> structure,
6475 PropertyAttributes attributes) { 6474 PropertyAttributes attributes) {
6476 Heap* heap = object->GetHeap(); 6475 Heap* heap = object->GetHeap();
6477 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); 6476 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6477 PropertyCellType::kInvalid);
6478 6478
6479 // Normalize elements to make this operation simple. 6479 // Normalize elements to make this operation simple.
6480 bool had_dictionary_elements = object->HasDictionaryElements(); 6480 bool had_dictionary_elements = object->HasDictionaryElements();
6481 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6481 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6482 DCHECK(object->HasDictionaryElements() || 6482 DCHECK(object->HasDictionaryElements() ||
6483 object->HasDictionaryArgumentsElements()); 6483 object->HasDictionaryArgumentsElements());
6484 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6484 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6485 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6485 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6486 details); 6486 details);
6487 dictionary->set_requires_slow_elements(); 6487 dictionary->set_requires_slow_elements();
(...skipping 24 matching lines...) Expand all
6512 void JSObject::SetPropertyCallback(Handle<JSObject> object, 6512 void JSObject::SetPropertyCallback(Handle<JSObject> object,
6513 Handle<Name> name, 6513 Handle<Name> name,
6514 Handle<Object> structure, 6514 Handle<Object> structure,
6515 PropertyAttributes attributes) { 6515 PropertyAttributes attributes) {
6516 PropertyNormalizationMode mode = object->map()->is_prototype_map() 6516 PropertyNormalizationMode mode = object->map()->is_prototype_map()
6517 ? KEEP_INOBJECT_PROPERTIES 6517 ? KEEP_INOBJECT_PROPERTIES
6518 : CLEAR_INOBJECT_PROPERTIES; 6518 : CLEAR_INOBJECT_PROPERTIES;
6519 // Normalize object to make this operation simple. 6519 // Normalize object to make this operation simple.
6520 NormalizeProperties(object, mode, 0, "SetPropertyCallback"); 6520 NormalizeProperties(object, mode, 0, "SetPropertyCallback");
6521 6521
6522 // For the global object allocate a new map to invalidate the global inline
6523 // caches which have a global property cell reference directly in the code.
6524 if (object->IsGlobalObject()) {
6525 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
6526 DCHECK(new_map->is_dictionary_map());
6527 #if TRACE_MAPS
6528 if (FLAG_trace_maps) {
6529 PrintF("[TraceMaps: GlobalPropertyCallback from= %p to= %p ]\n",
6530 reinterpret_cast<void*>(object->map()),
6531 reinterpret_cast<void*>(*new_map));
6532 }
6533 #endif
6534 JSObject::MigrateToMap(object, new_map);
6535
6536 // When running crankshaft, changing the map is not enough. We
6537 // need to deoptimize all functions that rely on this global
6538 // object.
6539 Deoptimizer::DeoptimizeGlobalObject(*object);
6540 }
6541 6522
6542 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6523 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6543 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0); 6524 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6525 PropertyCellType::kMutable);
6544 SetNormalizedProperty(object, name, structure, details); 6526 SetNormalizedProperty(object, name, structure, details);
6545 6527
6546 ReoptimizeIfPrototype(object); 6528 ReoptimizeIfPrototype(object);
6547 } 6529 }
6548 6530
6549 6531
6550 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object, 6532 MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
6551 Handle<Name> name, 6533 Handle<Name> name,
6552 Handle<Object> getter, 6534 Handle<Object> getter,
6553 Handle<Object> setter, 6535 Handle<Object> setter,
(...skipping 6172 matching lines...) Expand 10 before | Expand all | Expand 10 after
12726 // If a value has not been initialized we allow writing to it even if it 12708 // If a value has not been initialized we allow writing to it even if it
12727 // is read-only (a declared const that has not been initialized). 12709 // is read-only (a declared const that has not been initialized).
12728 return WriteToReadOnlyProperty( 12710 return WriteToReadOnlyProperty(
12729 isolate, object, isolate->factory()->NewNumberFromUint(index), 12711 isolate, object, isolate->factory()->NewNumberFromUint(index),
12730 isolate->factory()->undefined_value(), language_mode); 12712 isolate->factory()->undefined_value(), language_mode);
12731 } else { 12713 } else {
12732 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || 12714 DCHECK(details.IsConfigurable() || !details.IsReadOnly() ||
12733 element->IsTheHole()); 12715 element->IsTheHole());
12734 dictionary->UpdateMaxNumberKey(index); 12716 dictionary->UpdateMaxNumberKey(index);
12735 if (set_mode == DEFINE_PROPERTY) { 12717 if (set_mode == DEFINE_PROPERTY) {
12736 details = PropertyDetails(attributes, DATA, details.dictionary_index()); 12718 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12719 PropertyCellType::kInvalid);
12737 dictionary->DetailsAtPut(entry, details); 12720 dictionary->DetailsAtPut(entry, details);
12738 } 12721 }
12739 12722
12740 // Elements of the arguments object in slow mode might be slow aliases. 12723 // Elements of the arguments object in slow mode might be slow aliases.
12741 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12724 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12742 Handle<AliasedArgumentsEntry> entry = 12725 Handle<AliasedArgumentsEntry> entry =
12743 Handle<AliasedArgumentsEntry>::cast(element); 12726 Handle<AliasedArgumentsEntry>::cast(element);
12744 Handle<Context> context(Context::cast(elements->get(0))); 12727 Handle<Context> context(Context::cast(elements->get(0)));
12745 int context_index = entry->aliased_context_slot(); 12728 int context_index = entry->aliased_context_slot();
12746 DCHECK(!context->get(context_index)->IsTheHole()); 12729 DCHECK(!context->get(context_index)->IsTheHole());
(...skipping 22 matching lines...) Expand all
12769 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12752 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12770 Handle<String> name = isolate->factory()->NumberToString(number); 12753 Handle<String> name = isolate->factory()->NumberToString(number);
12771 Handle<Object> args[] = {name}; 12754 Handle<Object> args[] = {name};
12772 THROW_NEW_ERROR(isolate, 12755 THROW_NEW_ERROR(isolate,
12773 NewTypeError("object_not_extensible", 12756 NewTypeError("object_not_extensible",
12774 HandleVector(args, arraysize(args))), 12757 HandleVector(args, arraysize(args))),
12775 Object); 12758 Object);
12776 } 12759 }
12777 } 12760 }
12778 12761
12779 PropertyDetails details(attributes, DATA, 0); 12762 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid);
12780 Handle<SeededNumberDictionary> new_dictionary = 12763 Handle<SeededNumberDictionary> new_dictionary =
12781 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12764 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12782 details); 12765 details);
12783 if (*dictionary != *new_dictionary) { 12766 if (*dictionary != *new_dictionary) {
12784 if (is_arguments) { 12767 if (is_arguments) {
12785 elements->set(1, *new_dictionary); 12768 elements->set(1, *new_dictionary);
12786 } else { 12769 } else {
12787 object->set_elements(*new_dictionary); 12770 object->set_elements(*new_dictionary);
12788 } 12771 }
12789 dictionary = new_dictionary; 12772 dictionary = new_dictionary;
(...skipping 2064 matching lines...) Expand 10 before | Expand all | Expand 10 after
14854 return bailout; 14837 return bailout;
14855 } else { 14838 } else {
14856 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 14839 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14857 new_dict, key, value, details); 14840 new_dict, key, value, details);
14858 DCHECK(result.is_identical_to(new_dict)); 14841 DCHECK(result.is_identical_to(new_dict));
14859 USE(result); 14842 USE(result);
14860 } 14843 }
14861 } 14844 }
14862 14845
14863 uint32_t result = pos; 14846 uint32_t result = pos;
14864 PropertyDetails no_details(NONE, DATA, 0); 14847 PropertyDetails no_details = PropertyDetails::Empty();
14865 while (undefs > 0) { 14848 while (undefs > 0) {
14866 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 14849 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14867 // Adding an entry with the key beyond smi-range requires 14850 // Adding an entry with the key beyond smi-range requires
14868 // allocation. Bailout. 14851 // allocation. Bailout.
14869 return bailout; 14852 return bailout;
14870 } 14853 }
14871 HandleScope scope(isolate); 14854 HandleScope scope(isolate);
14872 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 14855 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14873 new_dict, pos, isolate->factory()->undefined_value(), no_details); 14856 new_dict, pos, isolate->factory()->undefined_value(), no_details);
14874 DCHECK(result.is_identical_to(new_dict)); 14857 DCHECK(result.is_identical_to(new_dict));
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
15215 } 15198 }
15216 array->set(index, double_value); 15199 array->set(index, double_value);
15217 } 15200 }
15218 return array->GetIsolate()->factory()->NewNumber(double_value); 15201 return array->GetIsolate()->factory()->NewNumber(double_value);
15219 } 15202 }
15220 15203
15221 15204
15222 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, 15205 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
15223 Handle<Name> name) { 15206 Handle<Name> name) {
15224 DCHECK(!global->HasFastProperties()); 15207 DCHECK(!global->HasFastProperties());
15225 Isolate* isolate = global->GetIsolate(); 15208 auto dictionary = handle(global->property_dictionary());
15226 int entry = global->property_dictionary()->FindEntry(name); 15209 int entry = dictionary->FindEntry(name);
15227 if (entry != NameDictionary::kNotFound) { 15210 if (entry == NameDictionary::kNotFound) return;
15228 Handle<PropertyCell> cell( 15211 PropertyCell::InvalidateEntry(dictionary, entry);
15229 PropertyCell::cast(global->property_dictionary()->ValueAt(entry)));
15230
15231 Handle<Object> value(cell->value(), isolate);
15232 Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value);
15233 global->property_dictionary()->ValueAtPut(entry, *new_cell);
15234
15235 Handle<Object> hole = isolate->factory()->the_hole_value();
15236 if (*hole != *value) {
15237 PropertyCell::SetValueInferType(cell, hole);
15238 } else {
15239 // If property value was the hole, set it to any other value,
15240 // to ensure that LoadNonexistent ICs execute a miss.
15241 Handle<Object> undefined = isolate->factory()->undefined_value();
15242 PropertyCell::SetValueInferType(cell, undefined);
15243 }
15244 }
15245 } 15212 }
15246 15213
15247 15214
15215 // TODO(dcarney): rename to EnsureEmptyPropertyCell or something.
15248 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( 15216 Handle<PropertyCell> GlobalObject::EnsurePropertyCell(
15249 Handle<GlobalObject> global, Handle<Name> name) { 15217 Handle<GlobalObject> global, Handle<Name> name) {
15250 DCHECK(!global->HasFastProperties()); 15218 DCHECK(!global->HasFastProperties());
15251 int entry = global->property_dictionary()->FindEntry(name); 15219 auto dictionary = handle(global->property_dictionary());
15252 if (entry == NameDictionary::kNotFound) { 15220 int entry = dictionary->FindEntry(name);
15253 Isolate* isolate = global->GetIsolate(); 15221 Handle<PropertyCell> cell;
15254 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCellWithHole(); 15222 if (entry != NameDictionary::kNotFound) {
15255 PropertyDetails details(NONE, DATA, 0); 15223 // This call should be idempotent.
15256 Handle<NameDictionary> dictionary = NameDictionary::Add( 15224 DCHECK(dictionary->DetailsAt(entry).cell_type() ==
15257 handle(global->property_dictionary()), name, cell, details); 15225 PropertyCellType::kUninitialized ||
15258 global->set_properties(*dictionary); 15226 dictionary->DetailsAt(entry).cell_type() ==
15227 PropertyCellType::kDeleted);
15228 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
15229 DCHECK(cell->value()->IsTheHole());
15259 return cell; 15230 return cell;
15260 } else {
15261 Object* value = global->property_dictionary()->ValueAt(entry);
15262 DCHECK(value->IsPropertyCell());
15263 return handle(PropertyCell::cast(value));
15264 } 15231 }
15232 Isolate* isolate = global->GetIsolate();
15233 cell = isolate->factory()->NewPropertyCell();
15234 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized);
15235 dictionary = NameDictionary::Add(dictionary, name, cell, details);
15236 global->set_properties(*dictionary);
15237 return cell;
15265 } 15238 }
15266 15239
15267 15240
15268 // This class is used for looking up two character strings in the string table. 15241 // This class is used for looking up two character strings in the string table.
15269 // If we don't have a hit we don't want to waste much time so we unroll the 15242 // If we don't have a hit we don't want to waste much time so we unroll the
15270 // string hash calculation loop here for speed. Doesn't work if the two 15243 // string hash calculation loop here for speed. Doesn't work if the two
15271 // characters form a decimal integer, since such strings have a different hash 15244 // characters form a decimal integer, since such strings have a different hash
15272 // algorithm. 15245 // algorithm.
15273 class TwoCharHashTableKey : public HashTableKey { 15246 class TwoCharHashTableKey : public HashTableKey {
15274 public: 15247 public:
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
15664 15637
15665 // Iterate over the dictionary using the enumeration order and update 15638 // Iterate over the dictionary using the enumeration order and update
15666 // the dictionary with new enumeration indices. 15639 // the dictionary with new enumeration indices.
15667 for (int i = 0; i < length; i++) { 15640 for (int i = 0; i < length; i++) {
15668 int index = Smi::cast(iteration_order->get(i))->value(); 15641 int index = Smi::cast(iteration_order->get(i))->value();
15669 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); 15642 DCHECK(dictionary->IsKey(dictionary->KeyAt(index)));
15670 15643
15671 int enum_index = PropertyDetails::kInitialIndex + i; 15644 int enum_index = PropertyDetails::kInitialIndex + i;
15672 15645
15673 PropertyDetails details = dictionary->DetailsAt(index); 15646 PropertyDetails details = dictionary->DetailsAt(index);
15674 PropertyDetails new_details = 15647 PropertyDetails new_details = details.set_index(enum_index);
15675 PropertyDetails(details.attributes(), details.type(), enum_index);
15676 dictionary->DetailsAtPut(index, new_details); 15648 dictionary->DetailsAtPut(index, new_details);
15677 } 15649 }
15678 15650
15679 // Set the next enumeration index. 15651 // Set the next enumeration index.
15680 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); 15652 dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
15681 return iteration_order; 15653 return iteration_order;
15682 } 15654 }
15683 15655
15684 15656
15685 template<typename Derived, typename Shape, typename Key> 15657 template<typename Derived, typename Shape, typename Key>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
15718 if (entry != Dictionary::kNotFound) { 15690 if (entry != Dictionary::kNotFound) {
15719 dictionary->ValueAtPut(entry, *value); 15691 dictionary->ValueAtPut(entry, *value);
15720 return dictionary; 15692 return dictionary;
15721 } 15693 }
15722 15694
15723 // Check whether the dictionary should be extended. 15695 // Check whether the dictionary should be extended.
15724 dictionary = EnsureCapacity(dictionary, 1, key); 15696 dictionary = EnsureCapacity(dictionary, 1, key);
15725 #ifdef DEBUG 15697 #ifdef DEBUG
15726 USE(Shape::AsHandle(dictionary->GetIsolate(), key)); 15698 USE(Shape::AsHandle(dictionary->GetIsolate(), key));
15727 #endif 15699 #endif
15728 PropertyDetails details(NONE, DATA, 0); 15700 PropertyDetails details = PropertyDetails::Empty();
15729 15701
15730 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); 15702 AddEntry(dictionary, key, value, details, dictionary->Hash(key));
15731 return dictionary; 15703 return dictionary;
15732 } 15704 }
15733 15705
15734 15706
15735 template<typename Derived, typename Shape, typename Key> 15707 template<typename Derived, typename Shape, typename Key>
15736 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( 15708 Handle<Derived> Dictionary<Derived, Shape, Key>::Add(
15737 Handle<Derived> dictionary, 15709 Handle<Derived> dictionary,
15738 Key key, 15710 Key key,
(...skipping 19 matching lines...) Expand all
15758 uint32_t hash) { 15730 uint32_t hash) {
15759 // Compute the key object. 15731 // Compute the key object.
15760 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key); 15732 Handle<Object> k = Shape::AsHandle(dictionary->GetIsolate(), key);
15761 15733
15762 uint32_t entry = dictionary->FindInsertionEntry(hash); 15734 uint32_t entry = dictionary->FindInsertionEntry(hash);
15763 // Insert element at empty or deleted entry 15735 // Insert element at empty or deleted entry
15764 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) { 15736 if (details.dictionary_index() == 0 && Shape::kIsEnumerable) {
15765 // Assign an enumeration index to the property and update 15737 // Assign an enumeration index to the property and update
15766 // SetNextEnumerationIndex. 15738 // SetNextEnumerationIndex.
15767 int index = dictionary->NextEnumerationIndex(); 15739 int index = dictionary->NextEnumerationIndex();
15768 details = PropertyDetails(details.attributes(), details.type(), index); 15740 details = details.set_index(index);
15769 dictionary->SetNextEnumerationIndex(index + 1); 15741 dictionary->SetNextEnumerationIndex(index + 1);
15770 } 15742 }
15771 dictionary->SetEntry(entry, k, value, details); 15743 dictionary->SetEntry(entry, k, value, details);
15772 DCHECK((dictionary->KeyAt(entry)->IsNumber() || 15744 DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
15773 dictionary->KeyAt(entry)->IsName())); 15745 dictionary->KeyAt(entry)->IsName()));
15774 dictionary->ElementAdded(); 15746 dictionary->ElementAdded();
15775 } 15747 }
15776 15748
15777 15749
15778 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { 15750 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) {
(...skipping 25 matching lines...) Expand all
15804 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 15776 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15805 return Add(dictionary, key, value, details); 15777 return Add(dictionary, key, value, details);
15806 } 15778 }
15807 15779
15808 15780
15809 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( 15781 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry(
15810 Handle<UnseededNumberDictionary> dictionary, 15782 Handle<UnseededNumberDictionary> dictionary,
15811 uint32_t key, 15783 uint32_t key,
15812 Handle<Object> value) { 15784 Handle<Object> value) {
15813 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); 15785 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
15814 return Add(dictionary, key, value, PropertyDetails(NONE, DATA, 0)); 15786 return Add(dictionary, key, value, PropertyDetails::Empty());
15815 } 15787 }
15816 15788
15817 15789
15818 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( 15790 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut(
15819 Handle<SeededNumberDictionary> dictionary, 15791 Handle<SeededNumberDictionary> dictionary,
15820 uint32_t key, 15792 uint32_t key,
15821 Handle<Object> value) { 15793 Handle<Object> value) {
15822 dictionary->UpdateMaxNumberKey(key); 15794 dictionary->UpdateMaxNumberKey(key);
15823 return AtPut(dictionary, key, value); 15795 return AtPut(dictionary, key, value);
15824 } 15796 }
(...skipping 10 matching lines...) Expand all
15835 Handle<SeededNumberDictionary> SeededNumberDictionary::Set( 15807 Handle<SeededNumberDictionary> SeededNumberDictionary::Set(
15836 Handle<SeededNumberDictionary> dictionary, 15808 Handle<SeededNumberDictionary> dictionary,
15837 uint32_t key, 15809 uint32_t key,
15838 Handle<Object> value, 15810 Handle<Object> value,
15839 PropertyDetails details) { 15811 PropertyDetails details) {
15840 int entry = dictionary->FindEntry(key); 15812 int entry = dictionary->FindEntry(key);
15841 if (entry == kNotFound) { 15813 if (entry == kNotFound) {
15842 return AddNumberEntry(dictionary, key, value, details); 15814 return AddNumberEntry(dictionary, key, value, details);
15843 } 15815 }
15844 // Preserve enumeration index. 15816 // Preserve enumeration index.
15845 details = PropertyDetails(details.attributes(), 15817 details = details.set_index(dictionary->DetailsAt(entry).dictionary_index());
15846 details.type(),
15847 dictionary->DetailsAt(entry).dictionary_index());
15848 Handle<Object> object_key = 15818 Handle<Object> object_key =
15849 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); 15819 SeededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
15850 dictionary->SetEntry(entry, object_key, value, details); 15820 dictionary->SetEntry(entry, object_key, value, details);
15851 return dictionary; 15821 return dictionary;
15852 } 15822 }
15853 15823
15854 15824
15855 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set( 15825 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
15856 Handle<UnseededNumberDictionary> dictionary, 15826 Handle<UnseededNumberDictionary> dictionary,
15857 uint32_t key, 15827 uint32_t key,
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
17015 Handle<Object> result(buffer(), GetIsolate()); 16985 Handle<Object> result(buffer(), GetIsolate());
17016 if (*result != Smi::FromInt(0)) { 16986 if (*result != Smi::FromInt(0)) {
17017 DCHECK(IsExternalArrayElementsKind(map()->elements_kind())); 16987 DCHECK(IsExternalArrayElementsKind(map()->elements_kind()));
17018 return Handle<JSArrayBuffer>::cast(result); 16988 return Handle<JSArrayBuffer>::cast(result);
17019 } 16989 }
17020 Handle<JSTypedArray> self(this); 16990 Handle<JSTypedArray> self(this);
17021 return MaterializeArrayBuffer(self); 16991 return MaterializeArrayBuffer(self);
17022 } 16992 }
17023 16993
17024 16994
17025 HeapType* PropertyCell::type() { 16995 Handle<PropertyCell> PropertyCell::InvalidateEntry(
17026 return static_cast<HeapType*>(type_raw()); 16996 Handle<NameDictionary> dictionary, int entry) {
16997 Isolate* isolate = dictionary->GetIsolate();
16998 // Swap with a copy.
16999 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
17000 auto new_cell = isolate->factory()->NewPropertyCell();
17001 new_cell->set_value(cell->value());
17002 dictionary->ValueAtPut(entry, *new_cell);
17003 bool is_the_hole = cell->value()->IsTheHole();
17004 // Cell is officially mutable henceforth.
17005 auto details = dictionary->DetailsAt(entry);
17006 details = details.set_cell_type(is_the_hole ? PropertyCellType::kDeleted
17007 : PropertyCellType::kMutable);
17008 dictionary->DetailsAtPut(entry, details);
17009 // Old cell is ready for invalidation.
17010 if (is_the_hole) {
17011 cell->set_value(isolate->heap()->undefined_value());
17012 } else {
17013 cell->set_value(isolate->heap()->the_hole_value());
17014 }
17015 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17016 isolate, DependentCode::kPropertyCellChangedGroup);
17017 return new_cell;
17027 } 17018 }
17028 17019
17029 17020
17030 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { 17021 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
17031 DCHECK(IsPropertyCell()); 17022 Handle<Object> value,
17032 set_type_raw(type, ignored); 17023 PropertyDetails details) {
17024 PropertyCellType type = details.cell_type();
17025 DCHECK(!value->IsTheHole());
17026 DCHECK_IMPLIES(cell->value()->IsTheHole(),
17027 type == PropertyCellType::kUninitialized ||
17028 type == PropertyCellType::kDeleted);
17029 switch (type) {
17030 // Only allow a cell to transition once into constant state.
17031 case PropertyCellType::kUninitialized:
17032 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17033 return PropertyCellType::kConstant;
17034 case PropertyCellType::kUndefined:
17035 return PropertyCellType::kConstant;
17036 case PropertyCellType::kConstant:
17037 // No transition.
17038 if (*value == cell->value()) return PropertyCellType::kConstant;
17039 // Fall through.
17040 case PropertyCellType::kMutable:
17041 return PropertyCellType::kMutable;
17042 }
17043 UNREACHABLE();
17044 return PropertyCellType::kMutable;
17033 } 17045 }
17034 17046
17035 17047
17036 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, 17048 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary,
17037 Handle<Object> value) { 17049 int entry, Handle<Object> value,
17038 Isolate* isolate = cell->GetIsolate(); 17050 PropertyDetails details) {
17039 Handle<HeapType> old_type(cell->type(), isolate); 17051 DCHECK(!value->IsTheHole());
17040 Handle<HeapType> new_type = HeapType::Constant(value, isolate); 17052 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
17053 const PropertyDetails original_details = dictionary->DetailsAt(entry);
17054 // Data accesses could be cached in ics or optimized code.
17055 bool invalidate =
17056 original_details.kind() == kData && details.kind() == kAccessor;
17057 int index = original_details.dictionary_index();
17058 auto old_type = original_details.cell_type();
17059 // Preserve the enumeration index unless the property was deleted or never
17060 // initialized.
17061 if (cell->value()->IsTheHole()) {
17062 index = dictionary->NextEnumerationIndex();
17063 dictionary->SetNextEnumerationIndex(index + 1);
17064 // Negative lookup cells must be invalidated.
17065 invalidate = true;
17066 }
17067 DCHECK(index > 0);
17068 details = details.set_index(index);
17041 17069
17042 if (new_type->Is(old_type)) return old_type;
17043
17044 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17045 isolate, DependentCode::kPropertyCellChangedGroup);
17046
17047 if (old_type->Is(HeapType::None()) || old_type->Is(HeapType::Undefined())) {
17048 return new_type;
17049 }
17050
17051 return HeapType::Any(isolate);
17052 }
17053
17054
17055 Handle<Object> PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
17056 Handle<Object> value) {
17057 // Heuristic: if a small-ish string is stored in a previously uninitialized 17070 // Heuristic: if a small-ish string is stored in a previously uninitialized
17058 // property cell, internalize it. 17071 // property cell, internalize it.
17059 const int kMaxLengthForInternalization = 200; 17072 const int kMaxLengthForInternalization = 200;
17060 if ((cell->type()->Is(HeapType::None()) || 17073 if ((old_type == PropertyCellType::kUninitialized ||
17061 cell->type()->Is(HeapType::Undefined())) && 17074 old_type == PropertyCellType::kUndefined) &&
17062 value->IsString()) { 17075 value->IsString()) {
17063 auto string = Handle<String>::cast(value); 17076 auto string = Handle<String>::cast(value);
17064 if (string->length() <= kMaxLengthForInternalization && 17077 if (string->length() <= kMaxLengthForInternalization) {
17065 !string->map()->is_undetectable()) {
17066 value = cell->GetIsolate()->factory()->InternalizeString(string); 17078 value = cell->GetIsolate()->factory()->InternalizeString(string);
17067 } 17079 }
17068 } 17080 }
17081
17082 auto new_type = UpdatedType(cell, value, original_details);
17083 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
17084
17085 // Install new property details and cell value.
17086 details = details.set_cell_type(new_type);
17087 dictionary->DetailsAtPut(entry, details);
17069 cell->set_value(*value); 17088 cell->set_value(*value);
17070 if (!HeapType::Any()->Is(cell->type())) { 17089
17071 Handle<HeapType> new_type = UpdatedType(cell, value); 17090 // Deopt when transitioning from a constant type.
17072 cell->set_type(*new_type); 17091 if (!invalidate && old_type == PropertyCellType::kConstant &&
17092 new_type != PropertyCellType::kConstant) {
17093 auto isolate = dictionary->GetIsolate();
17094 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17095 isolate, DependentCode::kPropertyCellChangedGroup);
17073 } 17096 }
17074 return value; 17097 return value;
17075 } 17098 }
17076 17099
17077 17100
17078 // static 17101 // static
17079 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell, 17102 void PropertyCell::AddDependentCompilationInfo(Handle<PropertyCell> cell,
17080 CompilationInfo* info) { 17103 CompilationInfo* info) {
17081 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( 17104 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo(
17082 handle(cell->dependent_code(), info->isolate()), 17105 handle(cell->dependent_code(), info->isolate()),
17083 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); 17106 DependentCode::kPropertyCellChangedGroup, info->object_wrapper());
17084 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); 17107 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes);
17085 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 17108 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
17086 cell, info->zone()); 17109 cell, info->zone());
17087 } 17110 }
17088 17111
17089 } } // namespace v8::internal 17112 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698