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

Side by Side Diff: src/objects.cc

Issue 1102543002: Reland: track global accesses to constant types (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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/property-details.h » ('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 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after
1779 } 1779 }
1780 1780
1781 1781
1782 void JSObject::AddSlowProperty(Handle<JSObject> object, 1782 void JSObject::AddSlowProperty(Handle<JSObject> object,
1783 Handle<Name> name, 1783 Handle<Name> name,
1784 Handle<Object> value, 1784 Handle<Object> value,
1785 PropertyAttributes attributes) { 1785 PropertyAttributes attributes) {
1786 DCHECK(!object->HasFastProperties()); 1786 DCHECK(!object->HasFastProperties());
1787 Isolate* isolate = object->GetIsolate(); 1787 Isolate* isolate = object->GetIsolate();
1788 Handle<NameDictionary> dict(object->property_dictionary()); 1788 Handle<NameDictionary> dict(object->property_dictionary());
1789 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid); 1789 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1790 if (object->IsGlobalObject()) { 1790 if (object->IsGlobalObject()) {
1791 int entry = dict->FindEntry(name); 1791 int entry = dict->FindEntry(name);
1792 // If there's a cell there, just invalidate and set the property. 1792 // If there's a cell there, just invalidate and set the property.
1793 if (entry != NameDictionary::kNotFound) { 1793 if (entry != NameDictionary::kNotFound) {
1794 PropertyCell::UpdateCell(dict, entry, value, details); 1794 PropertyCell::UpdateCell(dict, entry, value, details);
1795 // TODO(dcarney): move this to UpdateCell. 1795 // TODO(dcarney): move this to UpdateCell.
1796 // Need to adjust the details. 1796 // Need to adjust the details.
1797 int index = dict->NextEnumerationIndex(); 1797 int index = dict->NextEnumerationIndex();
1798 dict->SetNextEnumerationIndex(index + 1); 1798 dict->SetNextEnumerationIndex(index + 1);
1799 details = dict->DetailsAt(entry).set_index(index); 1799 details = dict->DetailsAt(entry).set_index(index);
(...skipping 2787 matching lines...) Expand 10 before | Expand all | Expand 10 after
4587 NameDictionary::New(isolate, property_count); 4587 NameDictionary::New(isolate, property_count);
4588 4588
4589 Handle<DescriptorArray> descs(map->instance_descriptors()); 4589 Handle<DescriptorArray> descs(map->instance_descriptors());
4590 for (int i = 0; i < real_size; i++) { 4590 for (int i = 0; i < real_size; i++) {
4591 PropertyDetails details = descs->GetDetails(i); 4591 PropertyDetails details = descs->GetDetails(i);
4592 Handle<Name> key(descs->GetKey(i)); 4592 Handle<Name> key(descs->GetKey(i));
4593 switch (details.type()) { 4593 switch (details.type()) {
4594 case DATA_CONSTANT: { 4594 case DATA_CONSTANT: {
4595 Handle<Object> value(descs->GetConstant(i), isolate); 4595 Handle<Object> value(descs->GetConstant(i), isolate);
4596 PropertyDetails d(details.attributes(), DATA, i + 1, 4596 PropertyDetails d(details.attributes(), DATA, i + 1,
4597 PropertyCellType::kInvalid); 4597 PropertyCellType::kNoCell);
4598 dictionary = NameDictionary::Add(dictionary, key, value, d); 4598 dictionary = NameDictionary::Add(dictionary, key, value, d);
4599 break; 4599 break;
4600 } 4600 }
4601 case DATA: { 4601 case DATA: {
4602 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4602 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4603 Handle<Object> value; 4603 Handle<Object> value;
4604 if (object->IsUnboxedDoubleField(index)) { 4604 if (object->IsUnboxedDoubleField(index)) {
4605 double old_value = object->RawFastDoublePropertyAt(index); 4605 double old_value = object->RawFastDoublePropertyAt(index);
4606 value = isolate->factory()->NewHeapNumber(old_value); 4606 value = isolate->factory()->NewHeapNumber(old_value);
4607 } else { 4607 } else {
4608 value = handle(object->RawFastPropertyAt(index), isolate); 4608 value = handle(object->RawFastPropertyAt(index), isolate);
4609 if (details.representation().IsDouble()) { 4609 if (details.representation().IsDouble()) {
4610 DCHECK(value->IsMutableHeapNumber()); 4610 DCHECK(value->IsMutableHeapNumber());
4611 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); 4611 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
4612 value = isolate->factory()->NewHeapNumber(old->value()); 4612 value = isolate->factory()->NewHeapNumber(old->value());
4613 } 4613 }
4614 } 4614 }
4615 PropertyDetails d(details.attributes(), DATA, i + 1, 4615 PropertyDetails d(details.attributes(), DATA, i + 1,
4616 PropertyCellType::kInvalid); 4616 PropertyCellType::kNoCell);
4617 dictionary = NameDictionary::Add(dictionary, key, value, d); 4617 dictionary = NameDictionary::Add(dictionary, key, value, d);
4618 break; 4618 break;
4619 } 4619 }
4620 case ACCESSOR: { 4620 case ACCESSOR: {
4621 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4621 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4622 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 4622 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
4623 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, 4623 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4624 PropertyCellType::kInvalid); 4624 PropertyCellType::kNoCell);
4625 dictionary = NameDictionary::Add(dictionary, key, value, d); 4625 dictionary = NameDictionary::Add(dictionary, key, value, d);
4626 break; 4626 break;
4627 } 4627 }
4628 case ACCESSOR_CONSTANT: { 4628 case ACCESSOR_CONSTANT: {
4629 Handle<Object> value(descs->GetCallbacksObject(i), isolate); 4629 Handle<Object> value(descs->GetCallbacksObject(i), isolate);
4630 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, 4630 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4631 PropertyCellType::kInvalid); 4631 PropertyCellType::kNoCell);
4632 dictionary = NameDictionary::Add(dictionary, key, value, d); 4632 dictionary = NameDictionary::Add(dictionary, key, value, d);
4633 break; 4633 break;
4634 } 4634 }
4635 } 4635 }
4636 } 4636 }
4637 4637
4638 // Copy the next enumeration index from instance descriptor. 4638 // Copy the next enumeration index from instance descriptor.
4639 dictionary->SetNextEnumerationIndex(real_size + 1); 4639 dictionary->SetNextEnumerationIndex(real_size + 1);
4640 4640
4641 // From here on we cannot fail and we shouldn't GC anymore. 4641 // From here on we cannot fail and we shouldn't GC anymore.
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
5351 Handle<NameDictionary> dictionary(object->property_dictionary()); 5351 Handle<NameDictionary> dictionary(object->property_dictionary());
5352 int entry = dictionary->FindEntry(name); 5352 int entry = dictionary->FindEntry(name);
5353 DCHECK_NE(NameDictionary::kNotFound, entry); 5353 DCHECK_NE(NameDictionary::kNotFound, entry);
5354 5354
5355 // If we have a global object, invalidate the cell and swap in a new one. 5355 // If we have a global object, invalidate the cell and swap in a new one.
5356 if (object->IsGlobalObject()) { 5356 if (object->IsGlobalObject()) {
5357 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); 5357 auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
5358 cell->set_value(isolate->heap()->the_hole_value()); 5358 cell->set_value(isolate->heap()->the_hole_value());
5359 // TODO(dcarney): InvalidateForDelete 5359 // TODO(dcarney): InvalidateForDelete
5360 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( 5360 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type(
5361 PropertyCellType::kDeleted)); 5361 PropertyCellType::kInvalidated));
5362 return; 5362 return;
5363 } 5363 }
5364 5364
5365 NameDictionary::DeleteProperty(dictionary, entry); 5365 NameDictionary::DeleteProperty(dictionary, entry);
5366 Handle<NameDictionary> new_properties = 5366 Handle<NameDictionary> new_properties =
5367 NameDictionary::Shrink(dictionary, name); 5367 NameDictionary::Shrink(dictionary, name);
5368 object->set_properties(*new_properties); 5368 object->set_properties(*new_properties);
5369 } 5369 }
5370 5370
5371 5371
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
6426 PropertyAttributes attributes) { 6426 PropertyAttributes attributes) {
6427 int entry = dictionary->FindEntry(index); 6427 int entry = dictionary->FindEntry(index);
6428 if (entry != SeededNumberDictionary::kNotFound) { 6428 if (entry != SeededNumberDictionary::kNotFound) {
6429 Object* result = dictionary->ValueAt(entry); 6429 Object* result = dictionary->ValueAt(entry);
6430 PropertyDetails details = dictionary->DetailsAt(entry); 6430 PropertyDetails details = dictionary->DetailsAt(entry);
6431 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) { 6431 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) {
6432 DCHECK(details.IsConfigurable()); 6432 DCHECK(details.IsConfigurable());
6433 if (details.attributes() != attributes) { 6433 if (details.attributes() != attributes) {
6434 dictionary->DetailsAtPut( 6434 dictionary->DetailsAtPut(
6435 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index, 6435 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index,
6436 PropertyCellType::kInvalid)); 6436 PropertyCellType::kNoCell));
6437 } 6437 }
6438 AccessorPair::cast(result)->SetComponents(getter, setter); 6438 AccessorPair::cast(result)->SetComponents(getter, setter);
6439 return true; 6439 return true;
6440 } 6440 }
6441 } 6441 }
6442 return false; 6442 return false;
6443 } 6443 }
6444 6444
6445 6445
6446 void JSObject::DefineElementAccessor(Handle<JSObject> object, 6446 void JSObject::DefineElementAccessor(Handle<JSObject> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
6529 return false; 6529 return false;
6530 } 6530 }
6531 6531
6532 6532
6533 void JSObject::SetElementCallback(Handle<JSObject> object, 6533 void JSObject::SetElementCallback(Handle<JSObject> object,
6534 uint32_t index, 6534 uint32_t index,
6535 Handle<Object> structure, 6535 Handle<Object> structure,
6536 PropertyAttributes attributes) { 6536 PropertyAttributes attributes) {
6537 Heap* heap = object->GetHeap(); 6537 Heap* heap = object->GetHeap();
6538 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, 6538 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6539 PropertyCellType::kInvalid); 6539 PropertyCellType::kNoCell);
6540 6540
6541 // Normalize elements to make this operation simple. 6541 // Normalize elements to make this operation simple.
6542 bool had_dictionary_elements = object->HasDictionaryElements(); 6542 bool had_dictionary_elements = object->HasDictionaryElements();
6543 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6543 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6544 DCHECK(object->HasDictionaryElements() || 6544 DCHECK(object->HasDictionaryElements() ||
6545 object->HasDictionaryArgumentsElements()); 6545 object->HasDictionaryArgumentsElements());
6546 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6546 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6547 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6547 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6548 details); 6548 details);
6549 dictionary->set_requires_slow_elements(); 6549 dictionary->set_requires_slow_elements();
(...skipping 6368 matching lines...) Expand 10 before | Expand all | Expand 10 after
12918 // is read-only (a declared const that has not been initialized). 12918 // is read-only (a declared const that has not been initialized).
12919 return WriteToReadOnlyProperty( 12919 return WriteToReadOnlyProperty(
12920 isolate, object, isolate->factory()->NewNumberFromUint(index), 12920 isolate, object, isolate->factory()->NewNumberFromUint(index),
12921 isolate->factory()->undefined_value(), language_mode); 12921 isolate->factory()->undefined_value(), language_mode);
12922 } else { 12922 } else {
12923 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || 12923 DCHECK(details.IsConfigurable() || !details.IsReadOnly() ||
12924 element->IsTheHole()); 12924 element->IsTheHole());
12925 dictionary->UpdateMaxNumberKey(index); 12925 dictionary->UpdateMaxNumberKey(index);
12926 if (set_mode == DEFINE_PROPERTY) { 12926 if (set_mode == DEFINE_PROPERTY) {
12927 details = PropertyDetails(attributes, DATA, details.dictionary_index(), 12927 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12928 PropertyCellType::kInvalid); 12928 PropertyCellType::kNoCell);
12929 dictionary->DetailsAtPut(entry, details); 12929 dictionary->DetailsAtPut(entry, details);
12930 } 12930 }
12931 12931
12932 // Elements of the arguments object in slow mode might be slow aliases. 12932 // Elements of the arguments object in slow mode might be slow aliases.
12933 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12933 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12934 Handle<AliasedArgumentsEntry> entry = 12934 Handle<AliasedArgumentsEntry> entry =
12935 Handle<AliasedArgumentsEntry>::cast(element); 12935 Handle<AliasedArgumentsEntry>::cast(element);
12936 Handle<Context> context(Context::cast(elements->get(0))); 12936 Handle<Context> context(Context::cast(elements->get(0)));
12937 int context_index = entry->aliased_context_slot(); 12937 int context_index = entry->aliased_context_slot();
12938 DCHECK(!context->get(context_index)->IsTheHole()); 12938 DCHECK(!context->get(context_index)->IsTheHole());
(...skipping 22 matching lines...) Expand all
12961 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12961 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12962 Handle<String> name = isolate->factory()->NumberToString(number); 12962 Handle<String> name = isolate->factory()->NumberToString(number);
12963 Handle<Object> args[] = {name}; 12963 Handle<Object> args[] = {name};
12964 THROW_NEW_ERROR(isolate, 12964 THROW_NEW_ERROR(isolate,
12965 NewTypeError("object_not_extensible", 12965 NewTypeError("object_not_extensible",
12966 HandleVector(args, arraysize(args))), 12966 HandleVector(args, arraysize(args))),
12967 Object); 12967 Object);
12968 } 12968 }
12969 } 12969 }
12970 12970
12971 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid); 12971 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
12972 Handle<SeededNumberDictionary> new_dictionary = 12972 Handle<SeededNumberDictionary> new_dictionary =
12973 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12973 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12974 details); 12974 details);
12975 if (*dictionary != *new_dictionary) { 12975 if (*dictionary != *new_dictionary) {
12976 if (is_arguments) { 12976 if (is_arguments) {
12977 elements->set(1, *new_dictionary); 12977 elements->set(1, *new_dictionary);
12978 } else { 12978 } else {
12979 object->set_elements(*new_dictionary); 12979 object->set_elements(*new_dictionary);
12980 } 12980 }
12981 dictionary = new_dictionary; 12981 dictionary = new_dictionary;
(...skipping 2426 matching lines...) Expand 10 before | Expand all | Expand 10 after
15408 Handle<GlobalObject> global, Handle<Name> name) { 15408 Handle<GlobalObject> global, Handle<Name> name) {
15409 DCHECK(!global->HasFastProperties()); 15409 DCHECK(!global->HasFastProperties());
15410 auto dictionary = handle(global->property_dictionary()); 15410 auto dictionary = handle(global->property_dictionary());
15411 int entry = dictionary->FindEntry(name); 15411 int entry = dictionary->FindEntry(name);
15412 Handle<PropertyCell> cell; 15412 Handle<PropertyCell> cell;
15413 if (entry != NameDictionary::kNotFound) { 15413 if (entry != NameDictionary::kNotFound) {
15414 // This call should be idempotent. 15414 // This call should be idempotent.
15415 DCHECK(dictionary->DetailsAt(entry).cell_type() == 15415 DCHECK(dictionary->DetailsAt(entry).cell_type() ==
15416 PropertyCellType::kUninitialized || 15416 PropertyCellType::kUninitialized ||
15417 dictionary->DetailsAt(entry).cell_type() == 15417 dictionary->DetailsAt(entry).cell_type() ==
15418 PropertyCellType::kDeleted); 15418 PropertyCellType::kInvalidated);
15419 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 15419 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
15420 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); 15420 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
15421 DCHECK(cell->value()->IsTheHole()); 15421 DCHECK(cell->value()->IsTheHole());
15422 return cell; 15422 return cell;
15423 } 15423 }
15424 Isolate* isolate = global->GetIsolate(); 15424 Isolate* isolate = global->GetIsolate();
15425 cell = isolate->factory()->NewPropertyCell(); 15425 cell = isolate->factory()->NewPropertyCell();
15426 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); 15426 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized);
15427 dictionary = NameDictionary::Add(dictionary, name, cell, details); 15427 dictionary = NameDictionary::Add(dictionary, name, cell, details);
15428 global->set_properties(*dictionary); 15428 global->set_properties(*dictionary);
(...skipping 1587 matching lines...) Expand 10 before | Expand all | Expand 10 after
17016 Isolate* isolate = dictionary->GetIsolate(); 17016 Isolate* isolate = dictionary->GetIsolate();
17017 // Swap with a copy. 17017 // Swap with a copy.
17018 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 17018 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
17019 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 17019 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
17020 auto new_cell = isolate->factory()->NewPropertyCell(); 17020 auto new_cell = isolate->factory()->NewPropertyCell();
17021 new_cell->set_value(cell->value()); 17021 new_cell->set_value(cell->value());
17022 dictionary->ValueAtPut(entry, *new_cell); 17022 dictionary->ValueAtPut(entry, *new_cell);
17023 bool is_the_hole = cell->value()->IsTheHole(); 17023 bool is_the_hole = cell->value()->IsTheHole();
17024 // Cell is officially mutable henceforth. 17024 // Cell is officially mutable henceforth.
17025 auto details = dictionary->DetailsAt(entry); 17025 auto details = dictionary->DetailsAt(entry);
17026 details = details.set_cell_type(is_the_hole ? PropertyCellType::kDeleted 17026 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated
17027 : PropertyCellType::kMutable); 17027 : PropertyCellType::kMutable);
17028 dictionary->DetailsAtPut(entry, details); 17028 dictionary->DetailsAtPut(entry, details);
17029 // Old cell is ready for invalidation. 17029 // Old cell is ready for invalidation.
17030 if (is_the_hole) { 17030 if (is_the_hole) {
17031 cell->set_value(isolate->heap()->undefined_value()); 17031 cell->set_value(isolate->heap()->undefined_value());
17032 } else { 17032 } else {
17033 cell->set_value(isolate->heap()->the_hole_value()); 17033 cell->set_value(isolate->heap()->the_hole_value());
17034 } 17034 }
17035 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17035 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17036 isolate, DependentCode::kPropertyCellChangedGroup); 17036 isolate, DependentCode::kPropertyCellChangedGroup);
17037 return new_cell; 17037 return new_cell;
17038 } 17038 }
17039 17039
17040 17040
17041 PropertyCellConstantType PropertyCell::GetConstantType() {
17042 if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
17043 return PropertyCellConstantType::kStableMap;
17044 }
17045
17046
17047 static bool RemainsConstantType(Handle<PropertyCell> cell,
17048 Handle<Object> value) {
17049 // TODO(dcarney): double->smi and smi->double transition from kConstant
17050 if (cell->value()->IsSmi() && value->IsSmi()) {
17051 return true;
17052 } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
17053 return HeapObject::cast(cell->value())->map() ==
17054 HeapObject::cast(*value)->map() &&
17055 HeapObject::cast(*value)->map()->is_stable();
17056 }
17057 return false;
17058 }
17059
17060
17041 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell, 17061 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
17042 Handle<Object> value, 17062 Handle<Object> value,
17043 PropertyDetails details) { 17063 PropertyDetails details) {
17044 PropertyCellType type = details.cell_type(); 17064 PropertyCellType type = details.cell_type();
17045 DCHECK(!value->IsTheHole()); 17065 DCHECK(!value->IsTheHole());
17046 DCHECK_IMPLIES(cell->value()->IsTheHole(), 17066 if (cell->value()->IsTheHole()) {
17047 type == PropertyCellType::kUninitialized || 17067 switch (type) {
17048 type == PropertyCellType::kDeleted); 17068 // Only allow a cell to transition once into constant state.
17069 case PropertyCellType::kUninitialized:
17070 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17071 return PropertyCellType::kConstant;
17072 case PropertyCellType::kInvalidated:
17073 return PropertyCellType::kMutable;
17074 default:
17075 UNREACHABLE();
17076 return PropertyCellType::kMutable;
17077 }
17078 }
17049 switch (type) { 17079 switch (type) {
17050 // Only allow a cell to transition once into constant state.
17051 case PropertyCellType::kUninitialized:
17052 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17053 return PropertyCellType::kConstant;
17054 case PropertyCellType::kUndefined: 17080 case PropertyCellType::kUndefined:
17055 return PropertyCellType::kConstant; 17081 return PropertyCellType::kConstant;
17056 case PropertyCellType::kConstant: 17082 case PropertyCellType::kConstant:
17057 // No transition.
17058 if (*value == cell->value()) return PropertyCellType::kConstant; 17083 if (*value == cell->value()) return PropertyCellType::kConstant;
17059 // Fall through. 17084 // Fall through.
17085 case PropertyCellType::kConstantType:
17086 if (RemainsConstantType(cell, value)) {
17087 return PropertyCellType::kConstantType;
17088 }
17089 // Fall through.
17060 case PropertyCellType::kMutable: 17090 case PropertyCellType::kMutable:
17061 return PropertyCellType::kMutable; 17091 return PropertyCellType::kMutable;
17062 } 17092 }
17063 UNREACHABLE(); 17093 UNREACHABLE();
17064 return PropertyCellType::kMutable; 17094 return PropertyCellType::kMutable;
17065 } 17095 }
17066 17096
17067 17097
17068 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary, 17098 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary,
17069 int entry, Handle<Object> value, 17099 int entry, Handle<Object> value,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
17102 17132
17103 auto new_type = UpdatedType(cell, value, original_details); 17133 auto new_type = UpdatedType(cell, value, original_details);
17104 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); 17134 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
17105 17135
17106 // Install new property details and cell value. 17136 // Install new property details and cell value.
17107 details = details.set_cell_type(new_type); 17137 details = details.set_cell_type(new_type);
17108 dictionary->DetailsAtPut(entry, details); 17138 dictionary->DetailsAtPut(entry, details);
17109 cell->set_value(*value); 17139 cell->set_value(*value);
17110 17140
17111 // Deopt when transitioning from a constant type. 17141 // Deopt when transitioning from a constant type.
17112 if (!invalidate && old_type == PropertyCellType::kConstant && 17142 if (!invalidate && (old_type != new_type)) {
17113 new_type != PropertyCellType::kConstant) {
17114 auto isolate = dictionary->GetIsolate(); 17143 auto isolate = dictionary->GetIsolate();
17115 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17144 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17116 isolate, DependentCode::kPropertyCellChangedGroup); 17145 isolate, DependentCode::kPropertyCellChangedGroup);
17117 } 17146 }
17118 return value; 17147 return value;
17119 } 17148 }
17120 17149
17121 17150
17122 // static 17151 // static
17123 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, 17152 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell,
17124 Handle<Object> new_value) { 17153 Handle<Object> new_value) {
17125 if (cell->value() != *new_value) { 17154 if (cell->value() != *new_value) {
17126 cell->set_value(*new_value); 17155 cell->set_value(*new_value);
17127 Isolate* isolate = cell->GetIsolate(); 17156 Isolate* isolate = cell->GetIsolate();
17128 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17157 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17129 isolate, DependentCode::kPropertyCellChangedGroup); 17158 isolate, DependentCode::kPropertyCellChangedGroup);
17130 } 17159 }
17131 } 17160 }
17132 } } // namespace v8::internal 17161 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/property-details.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698