| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 Map* old_target = old_map->GetTransition(transition_index); | 1764 Map* old_target = old_map->GetTransition(transition_index); |
| 1765 Object* result; | 1765 Object* result; |
| 1766 | 1766 |
| 1767 // To sever a transition to a map with which the descriptors are shared, the | 1767 // To sever a transition to a map with which the descriptors are shared, the |
| 1768 // larger map (more descriptors) needs to store its own descriptors array. | 1768 // larger map (more descriptors) needs to store its own descriptors array. |
| 1769 // Both sides of the severed chain need to have their own descriptors pointer | 1769 // Both sides of the severed chain need to have their own descriptors pointer |
| 1770 // to store distinct descriptor arrays. | 1770 // to store distinct descriptor arrays. |
| 1771 | 1771 |
| 1772 // If the old_target did not yet store its own descriptors, the new | 1772 // If the old_target did not yet store its own descriptors, the new |
| 1773 // descriptors pointer is created for the old_target by temporarily clearing | 1773 // descriptors pointer is created for the old_target by temporarily clearing |
| 1774 // the back pointer and setting its descriptor array. The ownership of the | 1774 // the back pointer and setting its descriptor array. |
| 1775 // descriptor array is returned to the smaller maps by installing a reduced | |
| 1776 // copy of the descriptor array in the old_map. | |
| 1777 | 1775 |
| 1778 // This phase is executed before creating the new map since it requires | 1776 // This phase is executed before creating the new map since it requires |
| 1779 // allocation that may fail. | 1777 // allocation that may fail. |
| 1780 if (!old_target->StoresOwnDescriptors()) { | 1778 if (!old_target->StoresOwnDescriptors()) { |
| 1781 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 1779 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 1782 | 1780 |
| 1783 old_target->SetBackPointer(GetHeap()->undefined_value()); | 1781 old_target->SetBackPointer(GetHeap()->undefined_value()); |
| 1784 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); | 1782 MaybeObject* maybe_failure = old_target->SetDescriptors(old_descriptors); |
| 1785 // Reset the backpointer before returning failure, otherwise the map ends up | 1783 // Reset the backpointer before returning failure, otherwise the map ends up |
| 1786 // with an undefined backpointer and no descriptors, losing its own | 1784 // with an undefined backpointer and no descriptors, losing its own |
| 1787 // descriptors. Setting the backpointer always succeeds. | 1785 // descriptors. Setting the backpointer always succeeds. |
| 1788 old_target->SetBackPointer(old_map); | 1786 old_target->SetBackPointer(old_map); |
| 1789 if (maybe_failure->IsFailure()) return maybe_failure; | 1787 if (maybe_failure->IsFailure()) return maybe_failure; |
| 1790 | |
| 1791 old_map->set_owns_descriptors(true); | |
| 1792 } | 1788 } |
| 1793 | 1789 |
| 1794 MaybeObject* maybe_result = | 1790 MaybeObject* maybe_result = |
| 1795 ConvertDescriptorToField(name, new_value, attributes); | 1791 ConvertDescriptorToField(name, new_value, attributes); |
| 1796 if (!maybe_result->To(&result)) return maybe_result; | 1792 if (!maybe_result->To(&result)) return maybe_result; |
| 1797 | 1793 |
| 1798 if (!HasFastProperties()) return result; | 1794 if (!HasFastProperties()) return result; |
| 1799 | 1795 |
| 1800 // This method should only be used to convert existing transitions. Objects | 1796 // This method should only be used to convert existing transitions. Objects |
| 1801 // with the map of "new Object()" cannot have transitions in the first place. | 1797 // with the map of "new Object()" cannot have transitions in the first place. |
| 1802 Map* new_map = map(); | 1798 Map* new_map = map(); |
| 1803 ASSERT(new_map != GetIsolate()->empty_object_map()); | 1799 ASSERT(new_map != GetIsolate()->empty_object_map()); |
| 1804 | 1800 |
| 1805 // TODO(verwaest): From here on we lose existing map transitions, causing | 1801 // TODO(verwaest): From here on we lose existing map transitions, causing |
| 1806 // invalid back pointers. This will change once we can store multiple | 1802 // invalid back pointers. This will change once we can store multiple |
| 1807 // transitions with the same key. | 1803 // transitions with the same key. |
| 1808 | 1804 |
| 1809 if (old_map->owns_descriptors()) { | 1805 if (old_map->owns_descriptors()) { |
| 1810 // If the old map owns its own descriptors, transfer ownership to the | 1806 // If the old map owns its own descriptors, transfer ownership to the |
| 1811 // new_map and install its descriptors in the old_map. Since the old_map | 1807 // new_map and install its descriptors in the old_map. Since the old_map |
| 1812 // stores the descriptors for the new_map, remove the transition array of | 1808 // stores the descriptors for the new_map, remove the transition array of |
| 1813 // the new_map that is only in place to store the descriptors. | 1809 // the new_map that is only in place to store the descriptors. |
| 1814 old_map->transitions()->descriptors_pointer()->set_value( | 1810 old_map->transitions()->descriptors_pointer()->set_value( |
| 1815 new_map->instance_descriptors()); | 1811 new_map->instance_descriptors()); |
| 1816 new_map->ClearTransitions(GetHeap()); | 1812 new_map->ClearTransitions(GetHeap()); |
| 1817 old_map->set_owns_descriptors(false); | 1813 old_map->set_owns_descriptors(false); |
| 1818 Map* map; | |
| 1819 JSGlobalPropertyCell* pointer = | |
| 1820 old_map->transitions()->descriptors_pointer(); | |
| 1821 for (Object* current = old_map; | |
| 1822 !current->IsUndefined(); | |
| 1823 current = map->GetBackPointer()) { | |
| 1824 map = Map::cast(current); | |
| 1825 if (!map->HasTransitionArray()) break; | |
| 1826 TransitionArray* transitions = map->transitions(); | |
| 1827 if (transitions->descriptors_pointer() != pointer) break; | |
| 1828 map->SetEnumLength(Map::kInvalidEnumCache); | |
| 1829 } | |
| 1830 } else if (old_target->instance_descriptors() == | 1814 } else if (old_target->instance_descriptors() == |
| 1831 old_map->instance_descriptors()) { | 1815 old_map->instance_descriptors()) { |
| 1832 // Since the conversion above generated a new fast map with an additional | 1816 // Since the conversion above generated a new fast map with an additional |
| 1833 // property which can be shared as well, install this descriptor pointer | 1817 // property which can be shared as well, install this descriptor pointer |
| 1834 // along the entire chain of smaller maps; and remove the transition array | 1818 // along the entire chain of smaller maps; and remove the transition array |
| 1835 // that is only in place to hold the descriptor array in the new map. | 1819 // that is only in place to hold the descriptor array in the new map. |
| 1836 Map* map; | 1820 Map* map; |
| 1837 JSGlobalPropertyCell* new_pointer = | 1821 JSGlobalPropertyCell* new_pointer = |
| 1838 new_map->transitions()->descriptors_pointer(); | 1822 new_map->transitions()->descriptors_pointer(); |
| 1839 JSGlobalPropertyCell* old_pointer = | 1823 JSGlobalPropertyCell* old_pointer = |
| (...skipping 3148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4988 result->set_is_shared(false); | 4972 result->set_is_shared(false); |
| 4989 result->ClearCodeCache(GetHeap()); | 4973 result->ClearCodeCache(GetHeap()); |
| 4990 return result; | 4974 return result; |
| 4991 } | 4975 } |
| 4992 | 4976 |
| 4993 | 4977 |
| 4994 MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) { | 4978 MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) { |
| 4995 // Sanity check. This path is only to be taken if the map owns its descriptor | 4979 // Sanity check. This path is only to be taken if the map owns its descriptor |
| 4996 // array, implying that its NumberOfOwnDescriptors equals the number of | 4980 // array, implying that its NumberOfOwnDescriptors equals the number of |
| 4997 // descriptors in the descriptor array. | 4981 // descriptors in the descriptor array. |
| 4998 ASSERT(NumberOfOwnDescriptors() == | 4982 if (NumberOfOwnDescriptors() != |
| 4999 instance_descriptors()->number_of_descriptors()); | 4983 instance_descriptors()->number_of_descriptors()) { |
| 4984 Isolate::Current()->PushStackTraceAndDie( |
| 4985 0xDEAD0002, GetBackPointer(), this, 0xDEAD0003); |
| 4986 } |
| 5000 Map* result; | 4987 Map* result; |
| 5001 MaybeObject* maybe_result = CopyDropDescriptors(); | 4988 MaybeObject* maybe_result = CopyDropDescriptors(); |
| 5002 if (!maybe_result->To(&result)) return maybe_result; | 4989 if (!maybe_result->To(&result)) return maybe_result; |
| 5003 | 4990 |
| 5004 String* name = descriptor->GetKey(); | 4991 String* name = descriptor->GetKey(); |
| 5005 | 4992 |
| 5006 TransitionArray* transitions; | 4993 TransitionArray* transitions; |
| 5007 MaybeObject* maybe_transitions = | 4994 MaybeObject* maybe_transitions = |
| 5008 AddTransition(name, result, SIMPLE_TRANSITION); | 4995 AddTransition(name, result, SIMPLE_TRANSITION); |
| 5009 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 4996 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5079 ? SIMPLE_TRANSITION | 5066 ? SIMPLE_TRANSITION |
| 5080 : FULL_TRANSITION; | 5067 : FULL_TRANSITION; |
| 5081 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); | 5068 MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); |
| 5082 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 5069 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
| 5083 | 5070 |
| 5084 if (descriptors->IsEmpty()) { | 5071 if (descriptors->IsEmpty()) { |
| 5085 if (owns_descriptors()) { | 5072 if (owns_descriptors()) { |
| 5086 // If the copied map has no added fields, and the parent map owns its | 5073 // If the copied map has no added fields, and the parent map owns its |
| 5087 // descriptors, those descriptors have to be empty. In that case, | 5074 // descriptors, those descriptors have to be empty. In that case, |
| 5088 // transfer ownership of the descriptors to the new child. | 5075 // transfer ownership of the descriptors to the new child. |
| 5089 ASSERT(instance_descriptors()->IsEmpty()); | 5076 CHECK(instance_descriptors()->IsEmpty()); |
| 5090 set_owns_descriptors(false); | 5077 set_owns_descriptors(false); |
| 5091 } else { | 5078 } else { |
| 5092 // If the parent did not own its own descriptors, it may share a larger | 5079 // If the parent did not own its own descriptors, it may share a larger |
| 5093 // descriptors array already. In that case, force a split by setting | 5080 // descriptors array already. In that case, force a split by setting |
| 5094 // the descriptor array of the new map to the empty descriptor array. | 5081 // the descriptor array of the new map to the empty descriptor array. |
| 5095 MaybeObject* maybe_failure = | 5082 MaybeObject* maybe_failure = |
| 5096 result->SetDescriptors(GetHeap()->empty_descriptor_array()); | 5083 result->SetDescriptors(GetHeap()->empty_descriptor_array()); |
| 5097 if (maybe_failure->IsFailure()) return maybe_failure; | 5084 if (maybe_failure->IsFailure()) return maybe_failure; |
| 5098 } | 5085 } |
| 5099 } | 5086 } |
| (...skipping 8450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13550 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13537 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13551 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13538 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13552 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13539 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13553 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13540 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13554 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13541 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13555 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13542 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13556 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13543 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13557 } | 13544 } |
| 13558 | 13545 |
| 13559 } } // namespace v8::internal | 13546 } } // namespace v8::internal |
| OLD | NEW |