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

Side by Side Diff: src/objects.cc

Issue 1062163005: 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 2785 matching lines...) Expand 10 before | Expand all | Expand 10 after
4585 NameDictionary::New(isolate, property_count); 4585 NameDictionary::New(isolate, property_count);
4586 4586
4587 Handle<DescriptorArray> descs(map->instance_descriptors()); 4587 Handle<DescriptorArray> descs(map->instance_descriptors());
4588 for (int i = 0; i < real_size; i++) { 4588 for (int i = 0; i < real_size; i++) {
4589 PropertyDetails details = descs->GetDetails(i); 4589 PropertyDetails details = descs->GetDetails(i);
4590 Handle<Name> key(descs->GetKey(i)); 4590 Handle<Name> key(descs->GetKey(i));
4591 switch (details.type()) { 4591 switch (details.type()) {
4592 case DATA_CONSTANT: { 4592 case DATA_CONSTANT: {
4593 Handle<Object> value(descs->GetConstant(i), isolate); 4593 Handle<Object> value(descs->GetConstant(i), isolate);
4594 PropertyDetails d(details.attributes(), DATA, i + 1, 4594 PropertyDetails d(details.attributes(), DATA, i + 1,
4595 PropertyCellType::kInvalid); 4595 PropertyCellType::kNoCell);
4596 dictionary = NameDictionary::Add(dictionary, key, value, d); 4596 dictionary = NameDictionary::Add(dictionary, key, value, d);
4597 break; 4597 break;
4598 } 4598 }
4599 case DATA: { 4599 case DATA: {
4600 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4600 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4601 Handle<Object> value; 4601 Handle<Object> value;
4602 if (object->IsUnboxedDoubleField(index)) { 4602 if (object->IsUnboxedDoubleField(index)) {
4603 double old_value = object->RawFastDoublePropertyAt(index); 4603 double old_value = object->RawFastDoublePropertyAt(index);
4604 value = isolate->factory()->NewHeapNumber(old_value); 4604 value = isolate->factory()->NewHeapNumber(old_value);
4605 } else { 4605 } else {
4606 value = handle(object->RawFastPropertyAt(index), isolate); 4606 value = handle(object->RawFastPropertyAt(index), isolate);
4607 if (details.representation().IsDouble()) { 4607 if (details.representation().IsDouble()) {
4608 DCHECK(value->IsMutableHeapNumber()); 4608 DCHECK(value->IsMutableHeapNumber());
4609 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); 4609 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
4610 value = isolate->factory()->NewHeapNumber(old->value()); 4610 value = isolate->factory()->NewHeapNumber(old->value());
4611 } 4611 }
4612 } 4612 }
4613 PropertyDetails d(details.attributes(), DATA, i + 1, 4613 PropertyDetails d(details.attributes(), DATA, i + 1,
4614 PropertyCellType::kInvalid); 4614 PropertyCellType::kNoCell);
4615 dictionary = NameDictionary::Add(dictionary, key, value, d); 4615 dictionary = NameDictionary::Add(dictionary, key, value, d);
4616 break; 4616 break;
4617 } 4617 }
4618 case ACCESSOR: { 4618 case ACCESSOR: {
4619 FieldIndex index = FieldIndex::ForDescriptor(*map, i); 4619 FieldIndex index = FieldIndex::ForDescriptor(*map, i);
4620 Handle<Object> value(object->RawFastPropertyAt(index), isolate); 4620 Handle<Object> value(object->RawFastPropertyAt(index), isolate);
4621 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, 4621 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4622 PropertyCellType::kInvalid); 4622 PropertyCellType::kNoCell);
4623 dictionary = NameDictionary::Add(dictionary, key, value, d); 4623 dictionary = NameDictionary::Add(dictionary, key, value, d);
4624 break; 4624 break;
4625 } 4625 }
4626 case ACCESSOR_CONSTANT: { 4626 case ACCESSOR_CONSTANT: {
4627 Handle<Object> value(descs->GetCallbacksObject(i), isolate); 4627 Handle<Object> value(descs->GetCallbacksObject(i), isolate);
4628 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1, 4628 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1,
4629 PropertyCellType::kInvalid); 4629 PropertyCellType::kNoCell);
4630 dictionary = NameDictionary::Add(dictionary, key, value, d); 4630 dictionary = NameDictionary::Add(dictionary, key, value, d);
4631 break; 4631 break;
4632 } 4632 }
4633 } 4633 }
4634 } 4634 }
4635 4635
4636 // Copy the next enumeration index from instance descriptor. 4636 // Copy the next enumeration index from instance descriptor.
4637 dictionary->SetNextEnumerationIndex(real_size + 1); 4637 dictionary->SetNextEnumerationIndex(real_size + 1);
4638 4638
4639 // From here on we cannot fail and we shouldn't GC anymore. 4639 // From here on we cannot fail and we shouldn't GC anymore.
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
5344 Handle<NameDictionary> dictionary(object->property_dictionary()); 5344 Handle<NameDictionary> dictionary(object->property_dictionary());
5345 int entry = dictionary->FindEntry(name); 5345 int entry = dictionary->FindEntry(name);
5346 DCHECK_NE(NameDictionary::kNotFound, entry); 5346 DCHECK_NE(NameDictionary::kNotFound, entry);
5347 5347
5348 // If we have a global object, invalidate the cell and swap in a new one. 5348 // If we have a global object, invalidate the cell and swap in a new one.
5349 if (object->IsGlobalObject()) { 5349 if (object->IsGlobalObject()) {
5350 auto cell = PropertyCell::InvalidateEntry(dictionary, entry); 5350 auto cell = PropertyCell::InvalidateEntry(dictionary, entry);
5351 cell->set_value(isolate->heap()->the_hole_value()); 5351 cell->set_value(isolate->heap()->the_hole_value());
5352 // TODO(dcarney): InvalidateForDelete 5352 // TODO(dcarney): InvalidateForDelete
5353 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type( 5353 dictionary->DetailsAtPut(entry, dictionary->DetailsAt(entry).set_cell_type(
5354 PropertyCellType::kDeleted)); 5354 PropertyCellType::kInvalidated));
5355 return; 5355 return;
5356 } 5356 }
5357 5357
5358 NameDictionary::DeleteProperty(dictionary, entry); 5358 NameDictionary::DeleteProperty(dictionary, entry);
5359 Handle<NameDictionary> new_properties = 5359 Handle<NameDictionary> new_properties =
5360 NameDictionary::Shrink(dictionary, name); 5360 NameDictionary::Shrink(dictionary, name);
5361 object->set_properties(*new_properties); 5361 object->set_properties(*new_properties);
5362 } 5362 }
5363 5363
5364 5364
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
6418 PropertyAttributes attributes) { 6418 PropertyAttributes attributes) {
6419 int entry = dictionary->FindEntry(index); 6419 int entry = dictionary->FindEntry(index);
6420 if (entry != SeededNumberDictionary::kNotFound) { 6420 if (entry != SeededNumberDictionary::kNotFound) {
6421 Object* result = dictionary->ValueAt(entry); 6421 Object* result = dictionary->ValueAt(entry);
6422 PropertyDetails details = dictionary->DetailsAt(entry); 6422 PropertyDetails details = dictionary->DetailsAt(entry);
6423 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) { 6423 if (details.type() == ACCESSOR_CONSTANT && result->IsAccessorPair()) {
6424 DCHECK(details.IsConfigurable()); 6424 DCHECK(details.IsConfigurable());
6425 if (details.attributes() != attributes) { 6425 if (details.attributes() != attributes) {
6426 dictionary->DetailsAtPut( 6426 dictionary->DetailsAtPut(
6427 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index, 6427 entry, PropertyDetails(attributes, ACCESSOR_CONSTANT, index,
6428 PropertyCellType::kInvalid)); 6428 PropertyCellType::kNoCell));
6429 } 6429 }
6430 AccessorPair::cast(result)->SetComponents(getter, setter); 6430 AccessorPair::cast(result)->SetComponents(getter, setter);
6431 return true; 6431 return true;
6432 } 6432 }
6433 } 6433 }
6434 return false; 6434 return false;
6435 } 6435 }
6436 6436
6437 6437
6438 void JSObject::DefineElementAccessor(Handle<JSObject> object, 6438 void JSObject::DefineElementAccessor(Handle<JSObject> object,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
6521 return false; 6521 return false;
6522 } 6522 }
6523 6523
6524 6524
6525 void JSObject::SetElementCallback(Handle<JSObject> object, 6525 void JSObject::SetElementCallback(Handle<JSObject> object,
6526 uint32_t index, 6526 uint32_t index,
6527 Handle<Object> structure, 6527 Handle<Object> structure,
6528 PropertyAttributes attributes) { 6528 PropertyAttributes attributes) {
6529 Heap* heap = object->GetHeap(); 6529 Heap* heap = object->GetHeap();
6530 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0, 6530 PropertyDetails details = PropertyDetails(attributes, ACCESSOR_CONSTANT, 0,
6531 PropertyCellType::kInvalid); 6531 PropertyCellType::kNoCell);
6532 6532
6533 // Normalize elements to make this operation simple. 6533 // Normalize elements to make this operation simple.
6534 bool had_dictionary_elements = object->HasDictionaryElements(); 6534 bool had_dictionary_elements = object->HasDictionaryElements();
6535 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6535 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6536 DCHECK(object->HasDictionaryElements() || 6536 DCHECK(object->HasDictionaryElements() ||
6537 object->HasDictionaryArgumentsElements()); 6537 object->HasDictionaryArgumentsElements());
6538 // Update the dictionary with the new ACCESSOR_CONSTANT property. 6538 // Update the dictionary with the new ACCESSOR_CONSTANT property.
6539 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6539 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6540 details); 6540 details);
6541 dictionary->set_requires_slow_elements(); 6541 dictionary->set_requires_slow_elements();
(...skipping 6342 matching lines...) Expand 10 before | Expand all | Expand 10 after
12884 // is read-only (a declared const that has not been initialized). 12884 // is read-only (a declared const that has not been initialized).
12885 return WriteToReadOnlyProperty( 12885 return WriteToReadOnlyProperty(
12886 isolate, object, isolate->factory()->NewNumberFromUint(index), 12886 isolate, object, isolate->factory()->NewNumberFromUint(index),
12887 isolate->factory()->undefined_value(), language_mode); 12887 isolate->factory()->undefined_value(), language_mode);
12888 } else { 12888 } else {
12889 DCHECK(details.IsConfigurable() || !details.IsReadOnly() || 12889 DCHECK(details.IsConfigurable() || !details.IsReadOnly() ||
12890 element->IsTheHole()); 12890 element->IsTheHole());
12891 dictionary->UpdateMaxNumberKey(index); 12891 dictionary->UpdateMaxNumberKey(index);
12892 if (set_mode == DEFINE_PROPERTY) { 12892 if (set_mode == DEFINE_PROPERTY) {
12893 details = PropertyDetails(attributes, DATA, details.dictionary_index(), 12893 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12894 PropertyCellType::kInvalid); 12894 PropertyCellType::kNoCell);
12895 dictionary->DetailsAtPut(entry, details); 12895 dictionary->DetailsAtPut(entry, details);
12896 } 12896 }
12897 12897
12898 // Elements of the arguments object in slow mode might be slow aliases. 12898 // Elements of the arguments object in slow mode might be slow aliases.
12899 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12899 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12900 Handle<AliasedArgumentsEntry> entry = 12900 Handle<AliasedArgumentsEntry> entry =
12901 Handle<AliasedArgumentsEntry>::cast(element); 12901 Handle<AliasedArgumentsEntry>::cast(element);
12902 Handle<Context> context(Context::cast(elements->get(0))); 12902 Handle<Context> context(Context::cast(elements->get(0)));
12903 int context_index = entry->aliased_context_slot(); 12903 int context_index = entry->aliased_context_slot();
12904 DCHECK(!context->get(context_index)->IsTheHole()); 12904 DCHECK(!context->get(context_index)->IsTheHole());
(...skipping 22 matching lines...) Expand all
12927 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12927 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12928 Handle<String> name = isolate->factory()->NumberToString(number); 12928 Handle<String> name = isolate->factory()->NumberToString(number);
12929 Handle<Object> args[] = {name}; 12929 Handle<Object> args[] = {name};
12930 THROW_NEW_ERROR(isolate, 12930 THROW_NEW_ERROR(isolate,
12931 NewTypeError("object_not_extensible", 12931 NewTypeError("object_not_extensible",
12932 HandleVector(args, arraysize(args))), 12932 HandleVector(args, arraysize(args))),
12933 Object); 12933 Object);
12934 } 12934 }
12935 } 12935 }
12936 12936
12937 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kInvalid); 12937 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
12938 Handle<SeededNumberDictionary> new_dictionary = 12938 Handle<SeededNumberDictionary> new_dictionary =
12939 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12939 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12940 details); 12940 details);
12941 if (*dictionary != *new_dictionary) { 12941 if (*dictionary != *new_dictionary) {
12942 if (is_arguments) { 12942 if (is_arguments) {
12943 elements->set(1, *new_dictionary); 12943 elements->set(1, *new_dictionary);
12944 } else { 12944 } else {
12945 object->set_elements(*new_dictionary); 12945 object->set_elements(*new_dictionary);
12946 } 12946 }
12947 dictionary = new_dictionary; 12947 dictionary = new_dictionary;
(...skipping 2411 matching lines...) Expand 10 before | Expand all | Expand 10 after
15359 Handle<GlobalObject> global, Handle<Name> name) { 15359 Handle<GlobalObject> global, Handle<Name> name) {
15360 DCHECK(!global->HasFastProperties()); 15360 DCHECK(!global->HasFastProperties());
15361 auto dictionary = handle(global->property_dictionary()); 15361 auto dictionary = handle(global->property_dictionary());
15362 int entry = dictionary->FindEntry(name); 15362 int entry = dictionary->FindEntry(name);
15363 Handle<PropertyCell> cell; 15363 Handle<PropertyCell> cell;
15364 if (entry != NameDictionary::kNotFound) { 15364 if (entry != NameDictionary::kNotFound) {
15365 // This call should be idempotent. 15365 // This call should be idempotent.
15366 DCHECK(dictionary->DetailsAt(entry).cell_type() == 15366 DCHECK(dictionary->DetailsAt(entry).cell_type() ==
15367 PropertyCellType::kUninitialized || 15367 PropertyCellType::kUninitialized ||
15368 dictionary->DetailsAt(entry).cell_type() == 15368 dictionary->DetailsAt(entry).cell_type() ==
15369 PropertyCellType::kDeleted); 15369 PropertyCellType::kInvalidated);
15370 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 15370 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
15371 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry))); 15371 cell = handle(PropertyCell::cast(dictionary->ValueAt(entry)));
15372 DCHECK(cell->value()->IsTheHole()); 15372 DCHECK(cell->value()->IsTheHole());
15373 return cell; 15373 return cell;
15374 } 15374 }
15375 Isolate* isolate = global->GetIsolate(); 15375 Isolate* isolate = global->GetIsolate();
15376 cell = isolate->factory()->NewPropertyCell(); 15376 cell = isolate->factory()->NewPropertyCell();
15377 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized); 15377 PropertyDetails details(NONE, DATA, 0, PropertyCellType::kUninitialized);
15378 dictionary = NameDictionary::Add(dictionary, name, cell, details); 15378 dictionary = NameDictionary::Add(dictionary, name, cell, details);
15379 global->set_properties(*dictionary); 15379 global->set_properties(*dictionary);
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after
16994 Isolate* isolate = dictionary->GetIsolate(); 16994 Isolate* isolate = dictionary->GetIsolate();
16995 // Swap with a copy. 16995 // Swap with a copy.
16996 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); 16996 DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
16997 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); 16997 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
16998 auto new_cell = isolate->factory()->NewPropertyCell(); 16998 auto new_cell = isolate->factory()->NewPropertyCell();
16999 new_cell->set_value(cell->value()); 16999 new_cell->set_value(cell->value());
17000 dictionary->ValueAtPut(entry, *new_cell); 17000 dictionary->ValueAtPut(entry, *new_cell);
17001 bool is_the_hole = cell->value()->IsTheHole(); 17001 bool is_the_hole = cell->value()->IsTheHole();
17002 // Cell is officially mutable henceforth. 17002 // Cell is officially mutable henceforth.
17003 auto details = dictionary->DetailsAt(entry); 17003 auto details = dictionary->DetailsAt(entry);
17004 details = details.set_cell_type(is_the_hole ? PropertyCellType::kDeleted 17004 details = details.set_cell_type(is_the_hole ? PropertyCellType::kInvalidated
17005 : PropertyCellType::kMutable); 17005 : PropertyCellType::kMutable);
17006 dictionary->DetailsAtPut(entry, details); 17006 dictionary->DetailsAtPut(entry, details);
17007 // Old cell is ready for invalidation. 17007 // Old cell is ready for invalidation.
17008 if (is_the_hole) { 17008 if (is_the_hole) {
17009 cell->set_value(isolate->heap()->undefined_value()); 17009 cell->set_value(isolate->heap()->undefined_value());
17010 } else { 17010 } else {
17011 cell->set_value(isolate->heap()->the_hole_value()); 17011 cell->set_value(isolate->heap()->the_hole_value());
17012 } 17012 }
17013 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17013 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17014 isolate, DependentCode::kPropertyCellChangedGroup); 17014 isolate, DependentCode::kPropertyCellChangedGroup);
17015 return new_cell; 17015 return new_cell;
17016 } 17016 }
17017 17017
17018 17018
17019 PropertyCellConstantType PropertyCell::GetConstantType() {
17020 if (value()->IsSmi()) return PropertyCellConstantType::kSmi;
17021 return PropertyCellConstantType::kStableMap;
17022 }
17023
17024
17025 static bool RemainsConstantType(Handle<PropertyCell> cell,
17026 Handle<Object> value) {
17027 // TODO(dcarney): double->smi and smi->double transition from kConstant
17028 if (cell->value()->IsSmi() && value->IsSmi()) {
17029 return true;
17030 } else if (cell->value()->IsHeapObject() && value->IsHeapObject()) {
17031 return HeapObject::cast(cell->value())->map() ==
17032 HeapObject::cast(*value)->map() &&
17033 HeapObject::cast(*value)->map()->is_stable();
17034 }
17035 return false;
17036 }
17037
17038
17019 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell, 17039 PropertyCellType PropertyCell::UpdatedType(Handle<PropertyCell> cell,
17020 Handle<Object> value, 17040 Handle<Object> value,
17021 PropertyDetails details) { 17041 PropertyDetails details) {
17022 PropertyCellType type = details.cell_type(); 17042 PropertyCellType type = details.cell_type();
17023 DCHECK(!value->IsTheHole()); 17043 DCHECK(!value->IsTheHole());
17024 DCHECK_IMPLIES(cell->value()->IsTheHole(), 17044 if (cell->value()->IsTheHole()) {
17025 type == PropertyCellType::kUninitialized || 17045 switch (type) {
17026 type == PropertyCellType::kDeleted); 17046 // Only allow a cell to transition once into constant state.
17047 case PropertyCellType::kUninitialized:
17048 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17049 return PropertyCellType::kConstant;
17050 case PropertyCellType::kInvalidated:
17051 return PropertyCellType::kMutable;
17052 default:
17053 UNREACHABLE();
17054 return PropertyCellType::kMutable;
17055 }
17056 }
17027 switch (type) { 17057 switch (type) {
17028 // Only allow a cell to transition once into constant state.
17029 case PropertyCellType::kUninitialized:
17030 if (value->IsUndefined()) return PropertyCellType::kUndefined;
17031 return PropertyCellType::kConstant;
17032 case PropertyCellType::kUndefined: 17058 case PropertyCellType::kUndefined:
17033 return PropertyCellType::kConstant; 17059 return PropertyCellType::kConstant;
17034 case PropertyCellType::kConstant: 17060 case PropertyCellType::kConstant:
17035 // No transition.
17036 if (*value == cell->value()) return PropertyCellType::kConstant; 17061 if (*value == cell->value()) return PropertyCellType::kConstant;
17037 // Fall through. 17062 // Fall through.
17063 case PropertyCellType::kConstantType:
17064 if (RemainsConstantType(cell, value)) {
17065 return PropertyCellType::kConstantType;
17066 }
17067 // Fall through.
17038 case PropertyCellType::kMutable: 17068 case PropertyCellType::kMutable:
17039 return PropertyCellType::kMutable; 17069 return PropertyCellType::kMutable;
17040 } 17070 }
17041 UNREACHABLE(); 17071 UNREACHABLE();
17042 return PropertyCellType::kMutable; 17072 return PropertyCellType::kMutable;
17043 } 17073 }
17044 17074
17045 17075
17046 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary, 17076 Handle<Object> PropertyCell::UpdateCell(Handle<NameDictionary> dictionary,
17047 int entry, Handle<Object> value, 17077 int entry, Handle<Object> value,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
17080 17110
17081 auto new_type = UpdatedType(cell, value, original_details); 17111 auto new_type = UpdatedType(cell, value, original_details);
17082 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry); 17112 if (invalidate) cell = PropertyCell::InvalidateEntry(dictionary, entry);
17083 17113
17084 // Install new property details and cell value. 17114 // Install new property details and cell value.
17085 details = details.set_cell_type(new_type); 17115 details = details.set_cell_type(new_type);
17086 dictionary->DetailsAtPut(entry, details); 17116 dictionary->DetailsAtPut(entry, details);
17087 cell->set_value(*value); 17117 cell->set_value(*value);
17088 17118
17089 // Deopt when transitioning from a constant type. 17119 // Deopt when transitioning from a constant type.
17090 if (!invalidate && old_type == PropertyCellType::kConstant && 17120 if (!invalidate && (old_type != new_type)) {
17091 new_type != PropertyCellType::kConstant) {
17092 auto isolate = dictionary->GetIsolate(); 17121 auto isolate = dictionary->GetIsolate();
17093 cell->dependent_code()->DeoptimizeDependentCodeGroup( 17122 cell->dependent_code()->DeoptimizeDependentCodeGroup(
17094 isolate, DependentCode::kPropertyCellChangedGroup); 17123 isolate, DependentCode::kPropertyCellChangedGroup);
17095 } 17124 }
17096 return value; 17125 return value;
17097 } 17126 }
17098 17127
17099 } } // namespace v8::internal 17128 } } // 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