| 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 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 it->GetHolder<JSObject>(), | 516 it->GetHolder<JSObject>(), |
| 517 it->GetAccessors(), language_mode); | 517 it->GetAccessors(), language_mode); |
| 518 } | 518 } |
| 519 | 519 |
| 520 it->isolate()->ReportFailedAccessCheck(checked); | 520 it->isolate()->ReportFailedAccessCheck(checked); |
| 521 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 521 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
| 522 return value; | 522 return value; |
| 523 } | 523 } |
| 524 | 524 |
| 525 | 525 |
| 526 static void ReplaceExistingPropertyCell(Handle<GlobalObject> global, int entry, |
| 527 Handle<Object> value) { |
| 528 Isolate* isolate = global->GetIsolate(); |
| 529 Handle<PropertyCell> cell( |
| 530 PropertyCell::cast(global->property_dictionary()->ValueAt(entry))); |
| 531 |
| 532 Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value); |
| 533 global->property_dictionary()->ValueAtPut(entry, *new_cell); |
| 534 |
| 535 Handle<Object> hole = isolate->factory()->the_hole_value(); |
| 536 if (*hole == cell->value()) { |
| 537 PropertyCell::SetValueInferType(cell, |
| 538 isolate->factory()->undefined_value()); |
| 539 } else { |
| 540 PropertyCell::SetValueInferType(cell, hole); |
| 541 } |
| 542 } |
| 543 |
| 544 |
| 545 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, |
| 546 Handle<Name> name) { |
| 547 DCHECK(!global->HasFastProperties()); |
| 548 int entry = global->property_dictionary()->FindEntry(name); |
| 549 if (entry != NameDictionary::kNotFound) { |
| 550 PropertyCell* cell = |
| 551 PropertyCell::cast(global->property_dictionary()->ValueAt(entry)); |
| 552 Handle<Object> value(cell->value(), global->GetIsolate()); |
| 553 ReplaceExistingPropertyCell(global, entry, value); |
| 554 } |
| 555 } |
| 556 |
| 557 |
| 526 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 558 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 527 Handle<Name> name, | 559 Handle<Name> name, |
| 528 Handle<Object> value, | 560 Handle<Object> value, |
| 529 PropertyDetails details) { | 561 PropertyDetails details) { |
| 530 DCHECK(!object->HasFastProperties()); | 562 DCHECK(!object->HasFastProperties()); |
| 531 Handle<NameDictionary> property_dictionary(object->property_dictionary()); | 563 Handle<NameDictionary> property_dictionary(object->property_dictionary()); |
| 532 | 564 |
| 533 if (!name->IsUniqueName()) { | 565 if (!name->IsUniqueName()) { |
| 534 name = object->GetIsolate()->factory()->InternalizeString( | 566 name = object->GetIsolate()->factory()->InternalizeString( |
| 535 Handle<String>::cast(name)); | 567 Handle<String>::cast(name)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 558 enumeration_index = original_details.dictionary_index(); | 590 enumeration_index = original_details.dictionary_index(); |
| 559 DCHECK(enumeration_index > 0); | 591 DCHECK(enumeration_index > 0); |
| 560 } | 592 } |
| 561 | 593 |
| 562 details = PropertyDetails( | 594 details = PropertyDetails( |
| 563 details.attributes(), details.type(), enumeration_index); | 595 details.attributes(), details.type(), enumeration_index); |
| 564 | 596 |
| 565 if (object->IsGlobalObject()) { | 597 if (object->IsGlobalObject()) { |
| 566 Handle<PropertyCell> cell( | 598 Handle<PropertyCell> cell( |
| 567 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 599 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
| 568 PropertyCell::SetValueInferType(cell, value); | 600 if (details.type() != property_dictionary->DetailsAt(entry).type()) { |
| 601 ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry, |
| 602 value); |
| 603 } else { |
| 604 PropertyCell::SetValueInferType(cell, value); |
| 605 } |
| 569 // Please note we have to update the property details. | 606 // Please note we have to update the property details. |
| 570 property_dictionary->DetailsAtPut(entry, details); | 607 property_dictionary->DetailsAtPut(entry, details); |
| 571 } else { | 608 } else { |
| 572 property_dictionary->SetEntry(entry, name, value, details); | 609 property_dictionary->SetEntry(entry, name, value, details); |
| 573 } | 610 } |
| 574 } | 611 } |
| 575 | 612 |
| 576 | 613 |
| 577 static MaybeHandle<JSObject> FindIndexedAllCanReadHolder( | 614 static MaybeHandle<JSObject> FindIndexedAllCanReadHolder( |
| 578 Isolate* isolate, Handle<JSObject> js_object, | 615 Isolate* isolate, Handle<JSObject> js_object, |
| (...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1769 Handle<Name> name, | 1806 Handle<Name> name, |
| 1770 Handle<Object> value, | 1807 Handle<Object> value, |
| 1771 PropertyAttributes attributes) { | 1808 PropertyAttributes attributes) { |
| 1772 DCHECK(!object->HasFastProperties()); | 1809 DCHECK(!object->HasFastProperties()); |
| 1773 Isolate* isolate = object->GetIsolate(); | 1810 Isolate* isolate = object->GetIsolate(); |
| 1774 Handle<NameDictionary> dict(object->property_dictionary()); | 1811 Handle<NameDictionary> dict(object->property_dictionary()); |
| 1775 if (object->IsGlobalObject()) { | 1812 if (object->IsGlobalObject()) { |
| 1776 // In case name is an orphaned property reuse the cell. | 1813 // In case name is an orphaned property reuse the cell. |
| 1777 int entry = dict->FindEntry(name); | 1814 int entry = dict->FindEntry(name); |
| 1778 if (entry != NameDictionary::kNotFound) { | 1815 if (entry != NameDictionary::kNotFound) { |
| 1779 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); | 1816 ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry, |
| 1780 PropertyCell::SetValueInferType(cell, value); | 1817 value); |
| 1781 // Assign an enumeration index to the property and update | 1818 // Assign an enumeration index to the property and update |
| 1782 // SetNextEnumerationIndex. | 1819 // SetNextEnumerationIndex. |
| 1783 int index = dict->NextEnumerationIndex(); | 1820 int index = dict->NextEnumerationIndex(); |
| 1784 PropertyDetails details(attributes, DATA, index); | 1821 PropertyDetails details(attributes, DATA, index); |
| 1785 dict->SetNextEnumerationIndex(index + 1); | 1822 dict->DetailsAtPut(entry, details); |
| 1786 dict->SetEntry(entry, name, cell, details); | |
| 1787 return; | 1823 return; |
| 1788 } | 1824 } |
| 1789 value = isolate->factory()->NewPropertyCell(value); | 1825 value = isolate->factory()->NewPropertyCell(value); |
| 1790 } | 1826 } |
| 1791 PropertyDetails details(attributes, DATA, 0); | 1827 PropertyDetails details(attributes, DATA, 0); |
| 1792 Handle<NameDictionary> result = | 1828 Handle<NameDictionary> result = |
| 1793 NameDictionary::Add(dict, name, value, details); | 1829 NameDictionary::Add(dict, name, value, details); |
| 1794 if (*dict != *result) object->set_properties(*result); | 1830 if (*dict != *result) object->set_properties(*result); |
| 1795 } | 1831 } |
| 1796 | 1832 |
| (...skipping 3508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5305 DCHECK(!object->HasFastProperties()); | 5341 DCHECK(!object->HasFastProperties()); |
| 5306 Isolate* isolate = object->GetIsolate(); | 5342 Isolate* isolate = object->GetIsolate(); |
| 5307 Handle<NameDictionary> dictionary(object->property_dictionary()); | 5343 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 5308 int entry = dictionary->FindEntry(name); | 5344 int entry = dictionary->FindEntry(name); |
| 5309 DCHECK_NE(NameDictionary::kNotFound, entry); | 5345 DCHECK_NE(NameDictionary::kNotFound, entry); |
| 5310 | 5346 |
| 5311 // If we have a global object set the cell to the hole. | 5347 // If we have a global object set the cell to the hole. |
| 5312 if (object->IsGlobalObject()) { | 5348 if (object->IsGlobalObject()) { |
| 5313 PropertyDetails details = dictionary->DetailsAt(entry); | 5349 PropertyDetails details = dictionary->DetailsAt(entry); |
| 5314 DCHECK(details.IsConfigurable()); | 5350 DCHECK(details.IsConfigurable()); |
| 5315 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 5351 ReplaceExistingPropertyCell(Handle<GlobalObject>::cast(object), entry, |
| 5316 Handle<Object> value = isolate->factory()->the_hole_value(); | 5352 isolate->factory()->the_hole_value()); |
| 5317 PropertyCell::SetValueInferType(cell, value); | |
| 5318 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 5353 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 5319 return; | 5354 return; |
| 5320 } | 5355 } |
| 5321 | 5356 |
| 5322 NameDictionary::DeleteProperty(dictionary, entry); | 5357 NameDictionary::DeleteProperty(dictionary, entry); |
| 5323 Handle<NameDictionary> new_properties = | 5358 Handle<NameDictionary> new_properties = |
| 5324 NameDictionary::Shrink(dictionary, name); | 5359 NameDictionary::Shrink(dictionary, name); |
| 5325 object->set_properties(*new_properties); | 5360 object->set_properties(*new_properties); |
| 5326 } | 5361 } |
| 5327 | 5362 |
| (...skipping 2097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7425 | 7460 |
| 7426 | 7461 |
| 7427 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, | 7462 Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map, |
| 7428 Handle<Name> name, | 7463 Handle<Name> name, |
| 7429 AccessorComponent component, | 7464 AccessorComponent component, |
| 7430 Handle<Object> accessor, | 7465 Handle<Object> accessor, |
| 7431 PropertyAttributes attributes) { | 7466 PropertyAttributes attributes) { |
| 7432 Isolate* isolate = name->GetIsolate(); | 7467 Isolate* isolate = name->GetIsolate(); |
| 7433 | 7468 |
| 7434 // Dictionary maps can always have additional data properties. | 7469 // Dictionary maps can always have additional data properties. |
| 7435 if (map->is_dictionary_map()) { | 7470 if (map->is_dictionary_map()) return map; |
| 7436 // For global objects, property cells are inlined. We need to change the | |
| 7437 // map. | |
| 7438 if (map->IsGlobalObjectMap()) return Copy(map, "GlobalAccessor"); | |
| 7439 return map; | |
| 7440 } | |
| 7441 | 7471 |
| 7442 // Migrate to the newest map before transitioning to the new property. | 7472 // Migrate to the newest map before transitioning to the new property. |
| 7443 map = Update(map); | 7473 map = Update(map); |
| 7444 | 7474 |
| 7445 PropertyNormalizationMode mode = map->is_prototype_map() | 7475 PropertyNormalizationMode mode = map->is_prototype_map() |
| 7446 ? KEEP_INOBJECT_PROPERTIES | 7476 ? KEEP_INOBJECT_PROPERTIES |
| 7447 : CLEAR_INOBJECT_PROPERTIES; | 7477 : CLEAR_INOBJECT_PROPERTIES; |
| 7448 | 7478 |
| 7449 int index = map->SearchTransition(kAccessor, *name, attributes); | 7479 int index = map->SearchTransition(kAccessor, *name, attributes); |
| 7450 if (index != TransitionArray::kNotFound) { | 7480 if (index != TransitionArray::kNotFound) { |
| (...skipping 7853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15304 // Clamp undefined to NaN (default). All other types have been | 15334 // Clamp undefined to NaN (default). All other types have been |
| 15305 // converted to a number type further up in the call chain. | 15335 // converted to a number type further up in the call chain. |
| 15306 DCHECK(value->IsUndefined()); | 15336 DCHECK(value->IsUndefined()); |
| 15307 } | 15337 } |
| 15308 array->set(index, double_value); | 15338 array->set(index, double_value); |
| 15309 } | 15339 } |
| 15310 return array->GetIsolate()->factory()->NewNumber(double_value); | 15340 return array->GetIsolate()->factory()->NewNumber(double_value); |
| 15311 } | 15341 } |
| 15312 | 15342 |
| 15313 | 15343 |
| 15314 void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global, | |
| 15315 Handle<Name> name) { | |
| 15316 DCHECK(!global->HasFastProperties()); | |
| 15317 Isolate* isolate = global->GetIsolate(); | |
| 15318 int entry = global->property_dictionary()->FindEntry(name); | |
| 15319 if (entry != NameDictionary::kNotFound) { | |
| 15320 Handle<PropertyCell> cell( | |
| 15321 PropertyCell::cast(global->property_dictionary()->ValueAt(entry))); | |
| 15322 | |
| 15323 Handle<Object> value(cell->value(), isolate); | |
| 15324 Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value); | |
| 15325 global->property_dictionary()->ValueAtPut(entry, *new_cell); | |
| 15326 | |
| 15327 Handle<Object> hole = isolate->factory()->the_hole_value(); | |
| 15328 if (*hole != *value) { | |
| 15329 PropertyCell::SetValueInferType(cell, hole); | |
| 15330 } else { | |
| 15331 // If property value was the hole, set it to any other value, | |
| 15332 // to ensure that LoadNonexistent ICs execute a miss. | |
| 15333 Handle<Object> undefined = isolate->factory()->undefined_value(); | |
| 15334 PropertyCell::SetValueInferType(cell, undefined); | |
| 15335 } | |
| 15336 } | |
| 15337 } | |
| 15338 | |
| 15339 | |
| 15340 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( | 15344 Handle<PropertyCell> GlobalObject::EnsurePropertyCell( |
| 15341 Handle<GlobalObject> global, Handle<Name> name) { | 15345 Handle<GlobalObject> global, Handle<Name> name) { |
| 15342 DCHECK(!global->HasFastProperties()); | 15346 DCHECK(!global->HasFastProperties()); |
| 15343 int entry = global->property_dictionary()->FindEntry(name); | 15347 int entry = global->property_dictionary()->FindEntry(name); |
| 15344 if (entry == NameDictionary::kNotFound) { | 15348 if (entry == NameDictionary::kNotFound) { |
| 15345 Isolate* isolate = global->GetIsolate(); | 15349 Isolate* isolate = global->GetIsolate(); |
| 15346 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCellWithHole(); | 15350 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCellWithHole(); |
| 15347 PropertyDetails details(NONE, DATA, 0); | 15351 PropertyDetails details(NONE, DATA, 0); |
| 15348 details = details.AsDeleted(); | 15352 details = details.AsDeleted(); |
| 15349 Handle<NameDictionary> dictionary = NameDictionary::Add( | 15353 Handle<NameDictionary> dictionary = NameDictionary::Add( |
| (...skipping 1807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17157 CompilationInfo* info) { | 17161 CompilationInfo* info) { |
| 17158 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( | 17162 Handle<DependentCode> codes = DependentCode::InsertCompilationInfo( |
| 17159 handle(cell->dependent_code(), info->isolate()), | 17163 handle(cell->dependent_code(), info->isolate()), |
| 17160 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); | 17164 DependentCode::kPropertyCellChangedGroup, info->object_wrapper()); |
| 17161 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17165 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
| 17162 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17166 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
| 17163 cell, info->zone()); | 17167 cell, info->zone()); |
| 17164 } | 17168 } |
| 17165 | 17169 |
| 17166 } } // namespace v8::internal | 17170 } } // namespace v8::internal |
| OLD | NEW |