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

Side by Side Diff: src/objects.cc

Issue 11094044: Fix transition conversion from CONSTANT_FUNCTION to FIELD. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/objects-printer.cc » ('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 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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698