| OLD | NEW | 
|      1 // Copyright 2013 the V8 project authors. All rights reserved. |      1 // Copyright 2013 the V8 project authors. All rights reserved. | 
|      2 // Use of this source code is governed by a BSD-style license that can be |      2 // Use of this source code is governed by a BSD-style license that can be | 
|      3 // found in the LICENSE file. |      3 // found in the LICENSE file. | 
|      4  |      4  | 
|      5 #include <iomanip> |      5 #include <iomanip> | 
|      6 #include <sstream> |      6 #include <sstream> | 
|      7  |      7  | 
|      8 #include "src/v8.h" |      8 #include "src/v8.h" | 
|      9  |      9  | 
|     10 #include "src/accessors.h" |     10 #include "src/accessors.h" | 
| (...skipping 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   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  Loading... | 
|   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  Loading... | 
|   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  Loading... | 
|   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  Loading... | 
|   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  Loading... | 
|  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  Loading... | 
|  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  Loading... | 
|  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  Loading... | 
|  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  Loading... | 
|  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 | 
| OLD | NEW |