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

Side by Side Diff: src/objects.cc

Issue 10695120: Ensure that all descriptors have a valid enumeration index, and replace NextEnumIndex with LastAdde… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment. Created 8 years, 5 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 | « src/objects.h ('k') | src/objects-inl.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 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 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1539 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1540 } 1540 }
1541 return AddSlowProperty(name, value, attributes); 1541 return AddSlowProperty(name, value, attributes);
1542 } 1542 }
1543 1543
1544 DescriptorArray* old_descriptors = map()->instance_descriptors(); 1544 DescriptorArray* old_descriptors = map()->instance_descriptors();
1545 // Compute the new index for new field. 1545 // Compute the new index for new field.
1546 int index = map()->NextFreePropertyIndex(); 1546 int index = map()->NextFreePropertyIndex();
1547 1547
1548 // Allocate new instance descriptors with (name, index) added 1548 // Allocate new instance descriptors with (name, index) added
1549 FieldDescriptor new_field(name, index, attributes); 1549 FieldDescriptor new_field(name, index, attributes, 0);
1550 DescriptorArray* new_descriptors; 1550 DescriptorArray* new_descriptors;
1551 { MaybeObject* maybe_new_descriptors = 1551 { MaybeObject* maybe_new_descriptors =
1552 old_descriptors->CopyInsert(&new_field); 1552 old_descriptors->CopyInsert(&new_field);
1553 if (!maybe_new_descriptors->To(&new_descriptors)) { 1553 if (!maybe_new_descriptors->To(&new_descriptors)) {
1554 return maybe_new_descriptors; 1554 return maybe_new_descriptors;
1555 } 1555 }
1556 } 1556 }
1557 1557
1558 // Only allow map transition if the object isn't the global object and there 1558 // Only allow map transition if the object isn't the global object.
1559 // is not a transition for the name, or there's a transition for the name but
1560 // it's unrelated to properties.
1561 int descriptor_index = old_descriptors->SearchWithCache(name);
1562
1563 // Element transitions are stored in the descriptor for property "", which is
1564 // not a identifier and should have forced a switch to slow properties above.
1565 bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound;
1566 bool allow_map_transition = 1559 bool allow_map_transition =
1567 can_insert_transition &&
1568 (isolate->context()->global_context()->object_function()->map() != map()); 1560 (isolate->context()->global_context()->object_function()->map() != map());
1569 1561
1562 ASSERT(old_descriptors->Search(name) == DescriptorArray::kNotFound);
1570 ASSERT(index < map()->inobject_properties() || 1563 ASSERT(index < map()->inobject_properties() ||
1571 (index - map()->inobject_properties()) < properties()->length() || 1564 (index - map()->inobject_properties()) < properties()->length() ||
1572 map()->unused_property_fields() == 0); 1565 map()->unused_property_fields() == 0);
1573 // Allocate a new map for the object. 1566 // Allocate a new map for the object.
1574 Object* r; 1567 Object* r;
1575 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); 1568 { MaybeObject* maybe_r = map()->CopyDropDescriptors();
1576 if (!maybe_r->ToObject(&r)) return maybe_r; 1569 if (!maybe_r->ToObject(&r)) return maybe_r;
1577 } 1570 }
1578 Map* new_map = Map::cast(r); 1571 Map* new_map = Map::cast(r);
1579 1572
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 set_map(new_map); 1608 set_map(new_map);
1616 return FastPropertyAtPut(index, value); 1609 return FastPropertyAtPut(index, value);
1617 } 1610 }
1618 1611
1619 1612
1620 MaybeObject* JSObject::AddConstantFunctionProperty( 1613 MaybeObject* JSObject::AddConstantFunctionProperty(
1621 String* name, 1614 String* name,
1622 JSFunction* function, 1615 JSFunction* function,
1623 PropertyAttributes attributes) { 1616 PropertyAttributes attributes) {
1624 // Allocate new instance descriptors with (name, function) added 1617 // Allocate new instance descriptors with (name, function) added
1625 ConstantFunctionDescriptor d(name, function, attributes); 1618 ConstantFunctionDescriptor d(name, function, attributes, 0);
1626 DescriptorArray* new_descriptors; 1619 DescriptorArray* new_descriptors;
1627 { MaybeObject* maybe_new_descriptors = 1620 { MaybeObject* maybe_new_descriptors =
1628 map()->instance_descriptors()->CopyInsert(&d); 1621 map()->instance_descriptors()->CopyInsert(&d);
1629 if (!maybe_new_descriptors->To(&new_descriptors)) { 1622 if (!maybe_new_descriptors->To(&new_descriptors)) {
1630 return maybe_new_descriptors; 1623 return maybe_new_descriptors;
1631 } 1624 }
1632 } 1625 }
1633 1626
1634 // Allocate a new map for the object. 1627 // Allocate a new map for the object.
1635 Map* new_map; 1628 Map* new_map;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { 1851 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) {
1859 Object* obj; 1852 Object* obj;
1860 { MaybeObject* maybe_obj = 1853 { MaybeObject* maybe_obj =
1861 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1854 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1862 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1855 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1863 } 1856 }
1864 return ReplaceSlowProperty(name, new_value, attributes); 1857 return ReplaceSlowProperty(name, new_value, attributes);
1865 } 1858 }
1866 1859
1867 int index = map()->NextFreePropertyIndex(); 1860 int index = map()->NextFreePropertyIndex();
1868 FieldDescriptor new_field(name, index, attributes); 1861 FieldDescriptor new_field(name, index, attributes, 0);
1869 // Make a new DescriptorArray replacing an entry with FieldDescriptor. 1862 // Make a new DescriptorArray replacing an entry with FieldDescriptor.
1870 Object* descriptors_unchecked; 1863 Object* descriptors_unchecked;
1871 { MaybeObject* maybe_descriptors_unchecked = 1864 { MaybeObject* maybe_descriptors_unchecked =
1872 map()->instance_descriptors()->CopyInsert(&new_field); 1865 map()->instance_descriptors()->CopyInsert(&new_field);
1873 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { 1866 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
1874 return maybe_descriptors_unchecked; 1867 return maybe_descriptors_unchecked;
1875 } 1868 }
1876 } 1869 }
1877 DescriptorArray* new_descriptors = 1870 DescriptorArray* new_descriptors =
1878 DescriptorArray::cast(descriptors_unchecked); 1871 DescriptorArray::cast(descriptors_unchecked);
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 } 2924 }
2932 return self->SetPropertyWithCallback(transition, 2925 return self->SetPropertyWithCallback(transition,
2933 *name, 2926 *name,
2934 *value, 2927 *value,
2935 result->holder(), 2928 result->holder(),
2936 strict_mode); 2929 strict_mode);
2937 } 2930 }
2938 2931
2939 Map* transition_map = Map::cast(transition); 2932 Map* transition_map = Map::cast(transition);
2940 DescriptorArray* descriptors = transition_map->instance_descriptors(); 2933 DescriptorArray* descriptors = transition_map->instance_descriptors();
2941 int descriptor = descriptors->SearchWithCache(*name); 2934 int descriptor = descriptors->LastAdded();
2942 PropertyDetails details = descriptors->GetDetails(descriptor); 2935 PropertyDetails details = descriptors->GetDetails(descriptor);
2943 ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); 2936 ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION);
2944 2937
2945 if (details.type() == FIELD) { 2938 if (details.type() == FIELD) {
2946 if (attributes == details.attributes()) { 2939 if (attributes == details.attributes()) {
2947 int field_index = descriptors->GetFieldIndex(descriptor); 2940 int field_index = descriptors->GetFieldIndex(descriptor);
2948 return self->AddFastPropertyUsingMap(transition_map, 2941 return self->AddFastPropertyUsingMap(transition_map,
2949 *name, 2942 *name,
2950 *value, 2943 *value,
2951 field_index); 2944 field_index);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
3055 return ConvertDescriptorToField(name, value, attributes); 3048 return ConvertDescriptorToField(name, value, attributes);
3056 case TRANSITION: { 3049 case TRANSITION: {
3057 Object* transition = result.GetTransitionValue(); 3050 Object* transition = result.GetTransitionValue();
3058 3051
3059 if (transition->IsAccessorPair()) { 3052 if (transition->IsAccessorPair()) {
3060 return ConvertDescriptorToField(name, value, attributes); 3053 return ConvertDescriptorToField(name, value, attributes);
3061 } 3054 }
3062 3055
3063 Map* transition_map = Map::cast(transition); 3056 Map* transition_map = Map::cast(transition);
3064 DescriptorArray* descriptors = transition_map->instance_descriptors(); 3057 DescriptorArray* descriptors = transition_map->instance_descriptors();
3065 int descriptor = descriptors->Search(name); 3058 int descriptor = descriptors->LastAdded();
3066 PropertyDetails details = descriptors->GetDetails(descriptor); 3059 PropertyDetails details = descriptors->GetDetails(descriptor);
3067 ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); 3060 ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION);
3068 3061
3069 if (details.type() == FIELD) { 3062 if (details.type() == FIELD) {
3070 if (attributes == details.attributes()) { 3063 if (attributes == details.attributes()) {
3071 int field_index = descriptors->GetFieldIndex(descriptor); 3064 int field_index = descriptors->GetFieldIndex(descriptor);
3072 return AddFastPropertyUsingMap(transition_map, 3065 return AddFastPropertyUsingMap(transition_map,
3073 name, 3066 name,
3074 value, 3067 value,
3075 field_index); 3068 field_index);
(...skipping 1527 matching lines...) Expand 10 before | Expand all | Expand 10 after
4603 // step 1: create a new getter/setter pair with only the accessor in it 4596 // step 1: create a new getter/setter pair with only the accessor in it
4604 Heap* heap = obj->GetHeap(); 4597 Heap* heap = obj->GetHeap();
4605 AccessorPair* accessors2; 4598 AccessorPair* accessors2;
4606 { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); 4599 { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair();
4607 if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; 4600 if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2;
4608 } 4601 }
4609 accessors2->set(component, accessor); 4602 accessors2->set(component, accessor);
4610 4603
4611 // step 2: create a copy of the descriptors, incl. the new getter/setter pair 4604 // step 2: create a copy of the descriptors, incl. the new getter/setter pair
4612 Map* map1 = obj->map(); 4605 Map* map1 = obj->map();
4613 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes); 4606 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0);
4614 DescriptorArray* descriptors2; 4607 DescriptorArray* descriptors2;
4615 { MaybeObject* maybe_descriptors2 = 4608 { MaybeObject* maybe_descriptors2 =
4616 map1->instance_descriptors()->CopyInsert(&callbacks_descr2); 4609 map1->instance_descriptors()->CopyInsert(&callbacks_descr2);
4617 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; 4610 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2;
4618 } 4611 }
4619 4612
4620 // step 3: create a new map with the new descriptors 4613 // step 3: create a new map with the new descriptors
4621 Map* map2; 4614 Map* map2;
4622 { MaybeObject* maybe_map2 = map1->CopyDropDescriptors(); 4615 { MaybeObject* maybe_map2 = map1->CopyDropDescriptors();
4623 if (!maybe_map2->To(&map2)) return maybe_map2; 4616 if (!maybe_map2->To(&map2)) return maybe_map2;
(...skipping 26 matching lines...) Expand all
4650 return obj; 4643 return obj;
4651 } 4644 }
4652 4645
4653 4646
4654 static bool TransitionToSameAccessor(Object* map, 4647 static bool TransitionToSameAccessor(Object* map,
4655 String* name, 4648 String* name,
4656 AccessorComponent component, 4649 AccessorComponent component,
4657 Object* accessor, 4650 Object* accessor,
4658 PropertyAttributes attributes ) { 4651 PropertyAttributes attributes ) {
4659 DescriptorArray* descs = Map::cast(map)->instance_descriptors(); 4652 DescriptorArray* descs = Map::cast(map)->instance_descriptors();
4660 int number = descs->SearchWithCache(name); 4653 int number = descs->LastAdded();
4661 ASSERT(number != DescriptorArray::kNotFound); 4654 ASSERT(number != DescriptorArray::kNotFound);
4662 Object* target_accessor = 4655 Object* target_accessor =
4663 AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); 4656 AccessorPair::cast(descs->GetCallbacksObject(number))->get(component);
4664 PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); 4657 PropertyAttributes target_attributes = descs->GetDetails(number).attributes();
4665 return target_accessor == accessor && target_attributes == attributes; 4658 return target_accessor == accessor && target_attributes == attributes;
4666 } 4659 }
4667 4660
4668 4661
4669 static MaybeObject* NewCallbackTransition(JSObject* obj, 4662 static MaybeObject* NewCallbackTransition(JSObject* obj,
4670 String* name, 4663 String* name,
4671 AccessorComponent component, 4664 AccessorComponent component,
4672 Object* accessor, 4665 Object* accessor,
4673 PropertyAttributes attributes, 4666 PropertyAttributes attributes,
4674 AccessorPair* accessors2) { 4667 AccessorPair* accessors2) {
4675 // step 1: copy the old getter/setter pair and set the new accessor 4668 // step 1: copy the old getter/setter pair and set the new accessor
4676 AccessorPair* accessors3; 4669 AccessorPair* accessors3;
4677 { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions(); 4670 { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions();
4678 if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3; 4671 if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3;
4679 } 4672 }
4680 accessors3->set(component, accessor); 4673 accessors3->set(component, accessor);
4681 4674
4682 // step 2: create a copy of the descriptors, incl. the new getter/setter pair 4675 // step 2: create a copy of the descriptors, incl. the new getter/setter pair
4683 Map* map2 = obj->map(); 4676 Map* map2 = obj->map();
4684 CallbacksDescriptor callbacks_descr3(name, accessors3, attributes); 4677 CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0);
4685 DescriptorArray* descriptors3; 4678 DescriptorArray* descriptors3;
4686 { MaybeObject* maybe_descriptors3 = 4679 { MaybeObject* maybe_descriptors3 =
4687 map2->instance_descriptors()->CopyInsert(&callbacks_descr3); 4680 map2->instance_descriptors()->CopyInsert(&callbacks_descr3);
4688 if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; 4681 if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3;
4689 } 4682 }
4690 4683
4691 // step 3: create a new map with the new descriptors 4684 // step 3: create a new map with the new descriptors
4692 Map* map3; 4685 Map* map3;
4693 { MaybeObject* maybe_map3 = map2->CopyDropDescriptors(); 4686 { MaybeObject* maybe_map3 = map2->CopyDropDescriptors();
4694 if (!maybe_map3->To(&map3)) return maybe_map3; 4687 if (!maybe_map3->To(&map3)) return maybe_map3;
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after
5810 FixedArray* result; 5803 FixedArray* result;
5811 if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) { 5804 if (number_of_descriptors == 0 && shared_mode == MAY_BE_SHARED) {
5812 return heap->empty_descriptor_array(); 5805 return heap->empty_descriptor_array();
5813 } 5806 }
5814 // Allocate the array of keys. 5807 // Allocate the array of keys.
5815 { MaybeObject* maybe_array = 5808 { MaybeObject* maybe_array =
5816 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); 5809 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors));
5817 if (!maybe_array->To(&result)) return maybe_array; 5810 if (!maybe_array->To(&result)) return maybe_array;
5818 } 5811 }
5819 5812
5820 result->set(kEnumerationIndexIndex, 5813 result->set(kLastAddedIndex, Smi::FromInt(-1));
5821 Smi::FromInt(PropertyDetails::kInitialIndex));
5822 result->set(kTransitionsIndex, Smi::FromInt(0)); 5814 result->set(kTransitionsIndex, Smi::FromInt(0));
5823 return result; 5815 return result;
5824 } 5816 }
5825 5817
5826 5818
5827 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 5819 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
5828 FixedArray* new_cache, 5820 FixedArray* new_cache,
5829 Object* new_index_cache) { 5821 Object* new_index_cache) {
5830 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 5822 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
5831 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); 5823 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
5832 if (HasEnumCache()) { 5824 if (HasEnumCache()) {
5833 FixedArray::cast(get(kEnumerationIndexIndex))-> 5825 FixedArray::cast(get(kLastAddedIndex))->
5834 set(kEnumCacheBridgeCacheIndex, new_cache); 5826 set(kEnumCacheBridgeCacheIndex, new_cache);
5835 FixedArray::cast(get(kEnumerationIndexIndex))-> 5827 FixedArray::cast(get(kLastAddedIndex))->
5836 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); 5828 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
5837 } else { 5829 } else {
5838 if (IsEmpty()) return; // Do nothing for empty descriptor array. 5830 if (IsEmpty()) return; // Do nothing for empty descriptor array.
5839 FixedArray::cast(bridge_storage)-> 5831 FixedArray::cast(bridge_storage)->
5840 set(kEnumCacheBridgeCacheIndex, new_cache); 5832 set(kEnumCacheBridgeCacheIndex, new_cache);
5841 FixedArray::cast(bridge_storage)-> 5833 FixedArray::cast(bridge_storage)->
5842 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); 5834 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
5843 NoWriteBarrierSet(FixedArray::cast(bridge_storage), 5835 NoWriteBarrierSet(FixedArray::cast(bridge_storage),
5844 kEnumCacheBridgeEnumIndex, 5836 kEnumCacheBridgeLastAdded,
5845 get(kEnumerationIndexIndex)); 5837 get(kLastAddedIndex));
5846 set(kEnumerationIndexIndex, bridge_storage); 5838 set(kLastAddedIndex, bridge_storage);
5847 } 5839 }
5848 } 5840 }
5849 5841
5850 5842
5851 static bool InsertionPointFound(String* key1, String* key2) { 5843 static bool InsertionPointFound(String* key1, String* key2) {
5852 return key1->Hash() > key2->Hash() || key1 == key2; 5844 return key1->Hash() > key2->Hash() || key1 == key2;
5853 } 5845 }
5854 5846
5855 5847
5856 void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst, 5848 void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
5903 5895
5904 DescriptorArray* new_descriptors; 5896 DescriptorArray* new_descriptors;
5905 { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); 5897 { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED);
5906 if (!maybe_result->To(&new_descriptors)) return maybe_result; 5898 if (!maybe_result->To(&new_descriptors)) return maybe_result;
5907 } 5899 }
5908 5900
5909 FixedArray::WhitenessWitness witness(new_descriptors); 5901 FixedArray::WhitenessWitness witness(new_descriptors);
5910 5902
5911 // Set the enumeration index in the descriptors and set the enumeration index 5903 // Set the enumeration index in the descriptors and set the enumeration index
5912 // in the result. 5904 // in the result.
5913 int enumeration_index = NextEnumerationIndex();
5914 if (keep_enumeration_index) { 5905 if (keep_enumeration_index) {
5915 descriptor->SetEnumerationIndex(GetDetails(index).index()); 5906 descriptor->SetEnumerationIndex(GetDetails(index).index());
5916 } else { 5907 } else {
5917 descriptor->SetEnumerationIndex(enumeration_index); 5908 descriptor->SetEnumerationIndex(NextEnumerationIndex());
5918 ++enumeration_index;
5919 } 5909 }
5920 new_descriptors->SetNextEnumerationIndex(enumeration_index);
5921 5910
5922 // Copy the descriptors, inserting or replacing a descriptor. 5911 // Copy the descriptors, inserting or replacing a descriptor.
5923 int to_index = 0; 5912 int to_index = 0;
5924 int insertion_index = -1; 5913 int insertion_index = -1;
5925 int from_index = 0; 5914 int from_index = 0;
5926 while (from_index < number_of_descriptors()) { 5915 while (from_index < number_of_descriptors()) {
5927 if (insertion_index < 0 && 5916 if (insertion_index < 0 &&
5928 InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { 5917 InsertionPointFound(GetKey(from_index), descriptor->GetKey())) {
5929 insertion_index = to_index++; 5918 insertion_index = to_index++;
5930 if (replacing) from_index++; 5919 if (replacing) from_index++;
5931 } else { 5920 } else {
5932 MaybeObject* copy_result = 5921 MaybeObject* copy_result =
5933 new_descriptors->CopyFrom(to_index++, this, from_index, witness); 5922 new_descriptors->CopyFrom(to_index++, this, from_index, witness);
5934 if (copy_result->IsFailure()) return copy_result; 5923 if (copy_result->IsFailure()) return copy_result;
5935 from_index++; 5924 from_index++;
5936 } 5925 }
5937 } 5926 }
5938 if (insertion_index < 0) insertion_index = to_index++; 5927 if (insertion_index < 0) insertion_index = to_index++;
5939 5928
5940 ASSERT(insertion_index < new_descriptors->number_of_descriptors()); 5929 ASSERT(insertion_index < new_descriptors->number_of_descriptors());
5941 new_descriptors->Set(insertion_index, descriptor, witness); 5930 new_descriptors->Set(insertion_index, descriptor, witness);
5931 if (!replacing) {
5932 new_descriptors->SetLastAdded(insertion_index);
5933 } else {
5934 new_descriptors->SetLastAdded(LastAdded());
5935 }
5942 5936
5943 ASSERT(to_index == new_descriptors->number_of_descriptors()); 5937 ASSERT(to_index == new_descriptors->number_of_descriptors());
5944 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); 5938 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
5945 5939
5946 return new_descriptors; 5940 return new_descriptors;
5947 } 5941 }
5948 5942
5949 5943
5950 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { 5944 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) {
5951 // Allocate the new descriptor array. 5945 // Allocate the new descriptor array.
5952 int number_of_descriptors = this->number_of_descriptors(); 5946 int number_of_descriptors = this->number_of_descriptors();
5953 DescriptorArray* new_descriptors; 5947 DescriptorArray* new_descriptors;
5954 { MaybeObject* maybe_result = Allocate(number_of_descriptors, 5948 { MaybeObject* maybe_result = Allocate(number_of_descriptors,
5955 shared_mode); 5949 shared_mode);
5956 if (!maybe_result->To(&new_descriptors)) return maybe_result; 5950 if (!maybe_result->To(&new_descriptors)) return maybe_result;
5957 } 5951 }
5958 5952
5959 // Copy the content. 5953 // Copy the content.
5960 if (number_of_descriptors > 0) { 5954 if (number_of_descriptors > 0) {
5961 FixedArray::WhitenessWitness witness(new_descriptors); 5955 FixedArray::WhitenessWitness witness(new_descriptors);
5962 for (int i = 0; i < number_of_descriptors; i++) { 5956 for (int i = 0; i < number_of_descriptors; i++) {
5963 MaybeObject* copy_result = 5957 MaybeObject* copy_result =
5964 new_descriptors->CopyFrom(i, this, i, witness); 5958 new_descriptors->CopyFrom(i, this, i, witness);
5965 if (copy_result->IsFailure()) return copy_result; 5959 if (copy_result->IsFailure()) return copy_result;
5966 } 5960 }
5961 new_descriptors->SetLastAdded(LastAdded());
5967 } 5962 }
5968 new_descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 5963
5969 return new_descriptors; 5964 return new_descriptors;
5970 } 5965 }
5971 5966
5972 // We need the whiteness witness since sort will reshuffle the entries in the 5967 // We need the whiteness witness since sort will reshuffle the entries in the
5973 // descriptor array. If the descriptor array were to be black, the shuffling 5968 // descriptor array. If the descriptor array were to be black, the shuffling
5974 // would move a slot that was already recorded as pointing into an evacuation 5969 // would move a slot that was already recorded as pointing into an evacuation
5975 // candidate. This would result in missing updates upon evacuation. 5970 // candidate. This would result in missing updates upon evacuation.
5976 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) { 5971 void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
5977 // In-place heap sort. 5972 // In-place heap sort.
5978 int len = number_of_descriptors(); 5973 int len = number_of_descriptors();
5974 // Nothing to sort.
5975 if (len == 0) return;
5979 5976
5980 // Bottom-up max-heap construction. 5977 // Bottom-up max-heap construction.
5981 // Index of the last node with children 5978 // Index of the last node with children
5982 const int max_parent_index = (len / 2) - 1; 5979 const int max_parent_index = (len / 2) - 1;
5983 for (int i = max_parent_index; i >= 0; --i) { 5980 for (int i = max_parent_index; i >= 0; --i) {
5984 int parent_index = i; 5981 int parent_index = i;
5985 const uint32_t parent_hash = GetKey(i)->Hash(); 5982 const uint32_t parent_hash = GetKey(i)->Hash();
5986 while (parent_index <= max_parent_index) { 5983 while (parent_index <= max_parent_index) {
5987 int child_index = 2 * parent_index + 1; 5984 int child_index = 2 * parent_index + 1;
5988 uint32_t child_hash = GetKey(child_index)->Hash(); 5985 uint32_t child_hash = GetKey(child_index)->Hash();
(...skipping 27 matching lines...) Expand all
6016 if (right_child_hash > child_hash) { 6013 if (right_child_hash > child_hash) {
6017 child_index++; 6014 child_index++;
6018 child_hash = right_child_hash; 6015 child_hash = right_child_hash;
6019 } 6016 }
6020 } 6017 }
6021 if (child_hash <= parent_hash) break; 6018 if (child_hash <= parent_hash) break;
6022 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index); 6019 NoIncrementalWriteBarrierSwapDescriptors(parent_index, child_index);
6023 parent_index = child_index; 6020 parent_index = child_index;
6024 } 6021 }
6025 } 6022 }
6023
6024 int last_enum_index = -1;
6025 int last_added = -1;
6026 for (int i = 0; i < len; ++i) {
6027 int current_enum = GetDetails(i).index();
6028 if (current_enum > last_enum_index) {
6029 last_added = i;
6030 last_enum_index = current_enum;
6031 }
6032 }
6033 SetLastAdded(last_added);
6034
6035 ASSERT(LastAdded() != -1);
6026 } 6036 }
6027 6037
6028 6038
6029 void DescriptorArray::Sort(const WhitenessWitness& witness) { 6039 void DescriptorArray::Sort(const WhitenessWitness& witness) {
6030 SortUnchecked(witness); 6040 SortUnchecked(witness);
6031 SLOW_ASSERT(IsSortedNoDuplicates()); 6041 SLOW_ASSERT(IsSortedNoDuplicates());
6032 } 6042 }
6033 6043
6034 6044
6035 MaybeObject* AccessorPair::CopyWithoutTransitions() { 6045 MaybeObject* AccessorPair::CopyWithoutTransitions() {
(...skipping 6677 matching lines...) Expand 10 before | Expand all | Expand 10 after
12713 if (!maybe_key->ToObject(&key)) return maybe_key; 12723 if (!maybe_key->ToObject(&key)) return maybe_key;
12714 } 12724 }
12715 PropertyDetails details = DetailsAt(i); 12725 PropertyDetails details = DetailsAt(i);
12716 PropertyType type = details.type(); 12726 PropertyType type = details.type();
12717 12727
12718 if (value->IsJSFunction() && !heap->InNewSpace(value)) { 12728 if (value->IsJSFunction() && !heap->InNewSpace(value)) {
12719 ConstantFunctionDescriptor d(String::cast(key), 12729 ConstantFunctionDescriptor d(String::cast(key),
12720 JSFunction::cast(value), 12730 JSFunction::cast(value),
12721 details.attributes(), 12731 details.attributes(),
12722 details.index()); 12732 details.index());
12723 descriptors->Set(next_descriptor++, &d, witness); 12733 descriptors->Set(next_descriptor, &d, witness);
12724 } else if (type == NORMAL) { 12734 } else if (type == NORMAL) {
12725 if (current_offset < inobject_props) { 12735 if (current_offset < inobject_props) {
12726 obj->InObjectPropertyAtPut(current_offset, 12736 obj->InObjectPropertyAtPut(current_offset,
12727 value, 12737 value,
12728 UPDATE_WRITE_BARRIER); 12738 UPDATE_WRITE_BARRIER);
12729 } else { 12739 } else {
12730 int offset = current_offset - inobject_props; 12740 int offset = current_offset - inobject_props;
12731 FixedArray::cast(fields)->set(offset, value); 12741 FixedArray::cast(fields)->set(offset, value);
12732 } 12742 }
12733 FieldDescriptor d(String::cast(key), 12743 FieldDescriptor d(String::cast(key),
12734 current_offset++, 12744 current_offset++,
12735 details.attributes(), 12745 details.attributes(),
12736 details.index()); 12746 details.index());
12737 descriptors->Set(next_descriptor++, &d, witness); 12747 descriptors->Set(next_descriptor, &d, witness);
12738 } else if (type == CALLBACKS) { 12748 } else if (type == CALLBACKS) {
12739 if (value->IsAccessorPair()) { 12749 if (value->IsAccessorPair()) {
12740 MaybeObject* maybe_copy = 12750 MaybeObject* maybe_copy =
12741 AccessorPair::cast(value)->CopyWithoutTransitions(); 12751 AccessorPair::cast(value)->CopyWithoutTransitions();
12742 if (!maybe_copy->To(&value)) return maybe_copy; 12752 if (!maybe_copy->To(&value)) return maybe_copy;
12743 } 12753 }
12744 CallbacksDescriptor d(String::cast(key), 12754 CallbacksDescriptor d(String::cast(key),
12745 value, 12755 value,
12746 details.attributes(), 12756 details.attributes(),
12747 details.index()); 12757 details.index());
12748 descriptors->Set(next_descriptor++, &d, witness); 12758 descriptors->Set(next_descriptor, &d, witness);
12749 } else { 12759 } else {
12750 UNREACHABLE(); 12760 UNREACHABLE();
12751 } 12761 }
12762 ++next_descriptor;
12752 } 12763 }
12753 } 12764 }
12754 ASSERT(current_offset == number_of_fields); 12765 ASSERT(current_offset == number_of_fields);
12755 12766
12756 descriptors->Sort(witness); 12767 descriptors->Sort(witness);
12757 // Allocate new map. 12768 // Allocate new map.
12758 Object* new_map; 12769 Object* new_map;
12759 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors(); 12770 { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
12760 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 12771 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
12761 } 12772 }
12762 12773
12763 // Transform the object. 12774 // Transform the object.
12764 obj->set_map(Map::cast(new_map)); 12775 obj->set_map(Map::cast(new_map));
12765 obj->map()->set_instance_descriptors(descriptors); 12776 obj->map()->set_instance_descriptors(descriptors);
12766 obj->map()->set_unused_property_fields(unused_property_fields); 12777 obj->map()->set_unused_property_fields(unused_property_fields);
12767 12778
12768 obj->set_properties(FixedArray::cast(fields)); 12779 obj->set_properties(FixedArray::cast(fields));
12769 ASSERT(obj->IsJSObject()); 12780 ASSERT(obj->IsJSObject());
12770 12781
12771 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
12772 // Check that it really works. 12782 // Check that it really works.
12773 ASSERT(obj->HasFastProperties()); 12783 ASSERT(obj->HasFastProperties());
12774 12784
12775 return obj; 12785 return obj;
12776 } 12786 }
12777 12787
12778 12788
12779 bool ObjectHashSet::Contains(Object* key) { 12789 bool ObjectHashSet::Contains(Object* key) {
12780 ASSERT(IsKey(key)); 12790 ASSERT(IsKey(key));
12781 12791
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
13273 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13283 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13274 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13284 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13275 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13285 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13276 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13286 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13277 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13287 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13278 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13288 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13279 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13289 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13280 } 13290 }
13281 13291
13282 } } // namespace v8::internal 13292 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698