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 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 return AddSlowProperty(name, value, attributes); | 1546 return AddSlowProperty(name, value, attributes); |
1547 } | 1547 } |
1548 | 1548 |
1549 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1549 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
1550 // Compute the new index for new field. | 1550 // Compute the new index for new field. |
1551 int index = map()->NextFreePropertyIndex(); | 1551 int index = map()->NextFreePropertyIndex(); |
1552 | 1552 |
1553 // Allocate new instance descriptors with (name, index) added | 1553 // Allocate new instance descriptors with (name, index) added |
1554 FieldDescriptor new_field(name, index, attributes, 0); | 1554 FieldDescriptor new_field(name, index, attributes, 0); |
1555 DescriptorArray* new_descriptors; | 1555 DescriptorArray* new_descriptors; |
1556 { MaybeObject* maybe_new_descriptors = | 1556 { MaybeObject* maybe_new_descriptors = old_descriptors->CopyAdd(&new_field); |
1557 old_descriptors->CopyInsert(&new_field); | |
1558 if (!maybe_new_descriptors->To(&new_descriptors)) { | 1557 if (!maybe_new_descriptors->To(&new_descriptors)) { |
1559 return maybe_new_descriptors; | 1558 return maybe_new_descriptors; |
1560 } | 1559 } |
1561 } | 1560 } |
1562 | 1561 |
1563 // Only allow map transition if the object isn't the global object. | 1562 // Only allow map transition if the object isn't the global object. |
1564 bool allow_map_transition = | 1563 bool allow_map_transition = |
1565 (isolate->context()->global_context()->object_function()->map() != map()); | 1564 (isolate->context()->global_context()->object_function()->map() != map()); |
1566 | 1565 |
1567 ASSERT(index < map()->inobject_properties() || | 1566 ASSERT(index < map()->inobject_properties() || |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1608 | 1607 |
1609 | 1608 |
1610 MaybeObject* JSObject::AddConstantFunctionProperty( | 1609 MaybeObject* JSObject::AddConstantFunctionProperty( |
1611 String* name, | 1610 String* name, |
1612 JSFunction* function, | 1611 JSFunction* function, |
1613 PropertyAttributes attributes) { | 1612 PropertyAttributes attributes) { |
1614 // Allocate new instance descriptors with (name, function) added | 1613 // Allocate new instance descriptors with (name, function) added |
1615 ConstantFunctionDescriptor d(name, function, attributes, 0); | 1614 ConstantFunctionDescriptor d(name, function, attributes, 0); |
1616 DescriptorArray* new_descriptors; | 1615 DescriptorArray* new_descriptors; |
1617 { MaybeObject* maybe_new_descriptors = | 1616 { MaybeObject* maybe_new_descriptors = |
1618 map()->instance_descriptors()->CopyInsert(&d); | 1617 map()->instance_descriptors()->CopyAdd(&d); |
1619 if (!maybe_new_descriptors->To(&new_descriptors)) { | 1618 if (!maybe_new_descriptors->To(&new_descriptors)) { |
1620 return maybe_new_descriptors; | 1619 return maybe_new_descriptors; |
1621 } | 1620 } |
1622 } | 1621 } |
1623 | 1622 |
1624 // Allocate a new map for the object. | 1623 // Allocate a new map for the object. |
1625 Map* new_map; | 1624 Map* new_map; |
1626 { MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(new_descriptors); | 1625 { MaybeObject* maybe_new_map = map()->CopyReplaceDescriptors(new_descriptors); |
1627 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 1626 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
1628 } | 1627 } |
(...skipping 2958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4587 { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); | 4586 { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); |
4588 if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; | 4587 if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; |
4589 } | 4588 } |
4590 accessors2->set(component, accessor); | 4589 accessors2->set(component, accessor); |
4591 | 4590 |
4592 // step 2: create a copy of the descriptors, incl. the new getter/setter pair | 4591 // step 2: create a copy of the descriptors, incl. the new getter/setter pair |
4593 Map* map1 = obj->map(); | 4592 Map* map1 = obj->map(); |
4594 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); | 4593 CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); |
4595 DescriptorArray* descriptors2; | 4594 DescriptorArray* descriptors2; |
4596 { MaybeObject* maybe_descriptors2 = | 4595 { MaybeObject* maybe_descriptors2 = |
4597 map1->instance_descriptors()->CopyInsert(&callbacks_descr2); | 4596 map1->instance_descriptors()->CopyAdd(&callbacks_descr2); |
4598 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; | 4597 if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; |
4599 } | 4598 } |
4600 | 4599 |
4601 // step 3: create a new map with the new descriptors | 4600 // step 3: create a new map with the new descriptors |
4602 Map* map2; | 4601 Map* map2; |
4603 { MaybeObject* maybe_map2 = map1->CopyReplaceDescriptors(descriptors2); | 4602 { MaybeObject* maybe_map2 = map1->CopyReplaceDescriptors(descriptors2); |
4604 if (!maybe_map2->To(&map2)) return maybe_map2; | 4603 if (!maybe_map2->To(&map2)) return maybe_map2; |
4605 } | 4604 } |
4606 | 4605 |
4607 // step 4: create a new getter/setter pair with a transition to the new map | 4606 // step 4: create a new getter/setter pair with a transition to the new map |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5856 if (details.type() == CALLBACKS && value->IsAccessorPair()) { | 5855 if (details.type() == CALLBACKS && value->IsAccessorPair()) { |
5857 MaybeObject* maybe_copy = | 5856 MaybeObject* maybe_copy = |
5858 AccessorPair::cast(value)->CopyWithoutTransitions(); | 5857 AccessorPair::cast(value)->CopyWithoutTransitions(); |
5859 if (!maybe_copy->To(&value)) return maybe_copy; | 5858 if (!maybe_copy->To(&value)) return maybe_copy; |
5860 } | 5859 } |
5861 Descriptor desc(src->GetKey(src_index), value, details); | 5860 Descriptor desc(src->GetKey(src_index), value, details); |
5862 Set(dst_index, &desc, witness); | 5861 Set(dst_index, &desc, witness); |
5863 return this; | 5862 return this; |
5864 } | 5863 } |
5865 | 5864 |
| 5865 MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, |
| 5866 int insertion_index) { |
| 5867 ASSERT(0 <= insertion_index && insertion_index < number_of_descriptors()); |
| 5868 |
| 5869 // Ensure the key is a symbol. |
| 5870 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
| 5871 if (maybe_result->IsFailure()) return maybe_result; |
| 5872 } |
| 5873 |
| 5874 int size = number_of_descriptors(); |
| 5875 |
| 5876 DescriptorArray* new_descriptors; |
| 5877 { MaybeObject* maybe_result = Allocate(size, MAY_BE_SHARED); |
| 5878 if (!maybe_result->To(&new_descriptors)) return maybe_result; |
| 5879 } |
| 5880 |
| 5881 FixedArray::WhitenessWitness witness(new_descriptors); |
| 5882 |
| 5883 // Copy the descriptors, replacing a descriptor. |
| 5884 for (int index = 0; index < size; ++index) { |
| 5885 if (index == insertion_index) continue; |
| 5886 MaybeObject* copy_result = |
| 5887 new_descriptors->CopyFrom(index, this, index, witness); |
| 5888 if (copy_result->IsFailure()) return copy_result; |
| 5889 } |
| 5890 |
| 5891 descriptor->SetEnumerationIndex(GetDetails(insertion_index).index()); |
| 5892 new_descriptors->Set(insertion_index, descriptor, witness); |
| 5893 new_descriptors->SetLastAdded(LastAdded()); |
| 5894 |
| 5895 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
| 5896 |
| 5897 return new_descriptors; |
| 5898 } |
| 5899 |
5866 | 5900 |
5867 MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) { | 5901 MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) { |
5868 // Ensure the key is a symbol. | 5902 // Ensure the key is a symbol. |
5869 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 5903 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
5870 if (maybe_result->IsFailure()) return maybe_result; | 5904 if (maybe_result->IsFailure()) return maybe_result; |
5871 } | 5905 } |
5872 | 5906 |
5873 int new_size = number_of_descriptors(); | 5907 // We replace the key if it is already present. |
| 5908 int index = SearchWithCache(descriptor->GetKey()); |
| 5909 if (index == kNotFound) return CopyAdd(descriptor); |
| 5910 return CopyReplace(descriptor, index); |
| 5911 } |
5874 | 5912 |
5875 // If key is in descriptor, we replace it in-place when filtering. | 5913 |
5876 // Count a null descriptor for key as inserted, not replaced. | 5914 MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { |
5877 int index = SearchWithCache(descriptor->GetKey()); | 5915 // Ensure the key is a symbol. |
5878 const bool replacing = (index != kNotFound); | 5916 { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
5879 bool keep_enumeration_index = false; | 5917 if (maybe_result->IsFailure()) return maybe_result; |
5880 if (replacing) { | |
5881 // We are replacing an existing descriptor. We keep the enumeration index | |
5882 // of a visible property. | |
5883 keep_enumeration_index = true; | |
5884 } else { | |
5885 ++new_size; | |
5886 } | 5918 } |
5887 | 5919 |
| 5920 String* key = descriptor->GetKey(); |
| 5921 ASSERT(Search(key) == kNotFound); |
| 5922 |
| 5923 int new_size = number_of_descriptors() + 1; |
| 5924 |
5888 DescriptorArray* new_descriptors; | 5925 DescriptorArray* new_descriptors; |
5889 { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); | 5926 { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); |
5890 if (!maybe_result->To(&new_descriptors)) return maybe_result; | 5927 if (!maybe_result->To(&new_descriptors)) return maybe_result; |
5891 } | 5928 } |
5892 | 5929 |
5893 FixedArray::WhitenessWitness witness(new_descriptors); | 5930 FixedArray::WhitenessWitness witness(new_descriptors); |
5894 | 5931 |
5895 // Set the enumeration index in the descriptors and set the enumeration index | 5932 // Copy the descriptors, inserting a descriptor. |
5896 // in the result. | 5933 int insertion_index = -1; |
5897 if (keep_enumeration_index) { | 5934 int to = 0; |
5898 descriptor->SetEnumerationIndex(GetDetails(index).index()); | 5935 for (int from = 0; from < number_of_descriptors(); ++from) { |
5899 } else { | 5936 if (insertion_index < 0 && InsertionPointFound(GetKey(from), key)) { |
5900 descriptor->SetEnumerationIndex(NextEnumerationIndex()); | 5937 insertion_index = to++; |
| 5938 } |
| 5939 MaybeObject* copy_result = |
| 5940 new_descriptors->CopyFrom(to++, this, from, witness); |
| 5941 if (copy_result->IsFailure()) return copy_result; |
5901 } | 5942 } |
| 5943 if (insertion_index < 0) insertion_index = to++; |
5902 | 5944 |
5903 // Copy the descriptors, inserting or replacing a descriptor. | 5945 ASSERT(to == new_descriptors->number_of_descriptors()); |
5904 int to_index = 0; | |
5905 int insertion_index = -1; | |
5906 int from_index = 0; | |
5907 while (from_index < number_of_descriptors()) { | |
5908 if (insertion_index < 0 && | |
5909 InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { | |
5910 insertion_index = to_index++; | |
5911 if (replacing) from_index++; | |
5912 } else { | |
5913 MaybeObject* copy_result = | |
5914 new_descriptors->CopyFrom(to_index++, this, from_index, witness); | |
5915 if (copy_result->IsFailure()) return copy_result; | |
5916 from_index++; | |
5917 } | |
5918 } | |
5919 if (insertion_index < 0) insertion_index = to_index++; | |
5920 | 5946 |
5921 ASSERT(insertion_index < new_descriptors->number_of_descriptors()); | 5947 descriptor->SetEnumerationIndex(NextEnumerationIndex()); |
5922 new_descriptors->Set(insertion_index, descriptor, witness); | 5948 new_descriptors->Set(insertion_index, descriptor, witness); |
| 5949 new_descriptors->SetLastAdded(insertion_index); |
5923 | 5950 |
5924 if (!replacing) { | |
5925 new_descriptors->SetLastAdded(insertion_index); | |
5926 } else { | |
5927 new_descriptors->SetLastAdded(LastAdded()); | |
5928 } | |
5929 | |
5930 ASSERT(to_index == new_descriptors->number_of_descriptors()); | |
5931 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | 5951 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
5932 | 5952 |
5933 return new_descriptors; | 5953 return new_descriptors; |
5934 } | 5954 } |
5935 | 5955 |
5936 | 5956 |
5937 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { | 5957 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { |
5938 // Allocate the new descriptor array. | 5958 // Allocate the new descriptor array. |
5939 int number_of_descriptors = this->number_of_descriptors(); | 5959 int number_of_descriptors = this->number_of_descriptors(); |
5940 DescriptorArray* new_descriptors; | 5960 DescriptorArray* new_descriptors; |
(...skipping 7336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13277 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13297 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13278 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13298 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13279 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13299 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13280 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13300 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13281 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13301 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13282 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13302 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13283 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13303 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13284 } | 13304 } |
13285 | 13305 |
13286 } } // namespace v8::internal | 13306 } } // namespace v8::internal |
OLD | NEW |