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 4732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4743 | 4743 |
4744 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); | 4744 result->set_pre_allocated_property_fields(pre_allocated_property_fields()); |
4745 result->set_is_shared(false); | 4745 result->set_is_shared(false); |
4746 result->ClearCodeCache(GetHeap()); | 4746 result->ClearCodeCache(GetHeap()); |
4747 return result; | 4747 return result; |
4748 } | 4748 } |
4749 | 4749 |
4750 | 4750 |
4751 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, | 4751 MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, |
4752 String* name, | 4752 String* name, |
| 4753 int last_added, |
4753 TransitionFlag flag) { | 4754 TransitionFlag flag) { |
4754 Map* result; | 4755 Map* result; |
4755 MaybeObject* maybe_result = CopyDropDescriptors(); | 4756 MaybeObject* maybe_result = CopyDropDescriptors(); |
4756 if (!maybe_result->To(&result)) return maybe_result; | 4757 if (!maybe_result->To(&result)) return maybe_result; |
4757 | 4758 |
| 4759 if (last_added == DescriptorArray::kNoneAdded) { |
| 4760 ASSERT(descriptors->IsEmpty()); |
| 4761 ASSERT(flag == OMIT_TRANSITION); |
| 4762 return result; |
| 4763 } |
| 4764 |
| 4765 descriptors->SetLastAdded(last_added); |
4758 result->set_instance_descriptors(descriptors); | 4766 result->set_instance_descriptors(descriptors); |
4759 | 4767 |
4760 if (flag == INSERT_TRANSITION) { | 4768 if (flag == INSERT_TRANSITION) { |
4761 TransitionArray* transitions; | 4769 TransitionArray* transitions; |
4762 MaybeObject* maybe_transitions = AddTransition(name, result); | 4770 MaybeObject* maybe_transitions = AddTransition(name, result); |
4763 if (!maybe_transitions->To(&transitions)) return maybe_transitions; | 4771 if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
4764 | 4772 |
4765 MaybeObject* maybe_set = set_transitions(transitions); | 4773 MaybeObject* maybe_set = set_transitions(transitions); |
4766 if (maybe_set->IsFailure()) return maybe_set; | 4774 if (maybe_set->IsFailure()) return maybe_set; |
4767 | 4775 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4800 } | 4808 } |
4801 | 4809 |
4802 | 4810 |
4803 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { | 4811 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { |
4804 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); | 4812 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); |
4805 | 4813 |
4806 // If the map has pre-allocated properties always start out with a descriptor | 4814 // If the map has pre-allocated properties always start out with a descriptor |
4807 // array describing these properties. | 4815 // array describing these properties. |
4808 ASSERT(constructor()->IsJSFunction()); | 4816 ASSERT(constructor()->IsJSFunction()); |
4809 JSFunction* ctor = JSFunction::cast(constructor()); | 4817 JSFunction* ctor = JSFunction::cast(constructor()); |
| 4818 Map* initial_map = ctor->initial_map(); |
| 4819 DescriptorArray* initial_descriptors = initial_map->instance_descriptors(); |
4810 DescriptorArray* descriptors; | 4820 DescriptorArray* descriptors; |
4811 MaybeObject* maybe_descriptors = | 4821 MaybeObject* maybe_descriptors = |
4812 ctor->initial_map()->instance_descriptors()->Copy( | 4822 initial_descriptors->Copy(DescriptorArray::MAY_BE_SHARED); |
4813 DescriptorArray::MAY_BE_SHARED); | |
4814 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 4823 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
4815 | 4824 |
4816 return CopyReplaceDescriptors(descriptors, NULL, OMIT_TRANSITION); | 4825 int last_added = initial_descriptors->IsEmpty() |
| 4826 ? DescriptorArray::kNoneAdded |
| 4827 : initial_descriptors->LastAdded(); |
| 4828 |
| 4829 return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION); |
4817 } | 4830 } |
4818 | 4831 |
4819 | 4832 |
4820 MaybeObject* Map::Copy(DescriptorArray::SharedMode shared_mode) { | 4833 MaybeObject* Map::Copy(DescriptorArray::SharedMode shared_mode) { |
| 4834 DescriptorArray* source_descriptors = instance_descriptors(); |
4821 DescriptorArray* descriptors; | 4835 DescriptorArray* descriptors; |
4822 MaybeObject* maybe_descriptors = instance_descriptors()->Copy(shared_mode); | 4836 MaybeObject* maybe_descriptors = source_descriptors->Copy(shared_mode); |
4823 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 4837 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
4824 | 4838 |
4825 return CopyReplaceDescriptors(descriptors, NULL, OMIT_TRANSITION); | 4839 int last_added = source_descriptors->IsEmpty() |
| 4840 ? DescriptorArray::kNoneAdded |
| 4841 : source_descriptors->LastAdded(); |
| 4842 |
| 4843 return CopyReplaceDescriptors(descriptors, NULL, last_added, OMIT_TRANSITION); |
| 4844 } |
| 4845 |
| 4846 |
| 4847 static bool InsertionPointFound(String* key1, String* key2) { |
| 4848 return key1->Hash() > key2->Hash() || key1 == key2; |
4826 } | 4849 } |
4827 | 4850 |
4828 | 4851 |
4829 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, | 4852 MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, |
4830 TransitionFlag flag) { | 4853 TransitionFlag flag) { |
4831 DescriptorArray* descriptors; | 4854 DescriptorArray* descriptors = instance_descriptors(); |
4832 MaybeObject* maybe_descriptors = instance_descriptors()->CopyAdd(descriptor); | |
4833 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | |
4834 | 4855 |
4835 return CopyReplaceDescriptors(descriptors, descriptor->GetKey(), flag); | 4856 // Ensure the key is a symbol. |
| 4857 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
| 4858 if (maybe_failure->IsFailure()) return maybe_failure; |
| 4859 |
| 4860 String* key = descriptor->GetKey(); |
| 4861 ASSERT(descriptors->Search(key) == DescriptorArray::kNotFound); |
| 4862 |
| 4863 int old_size = descriptors->number_of_descriptors(); |
| 4864 int new_size = old_size + 1; |
| 4865 |
| 4866 DescriptorArray* new_descriptors; |
| 4867 MaybeObject* maybe_descriptors = |
| 4868 DescriptorArray::Allocate(new_size, DescriptorArray::MAY_BE_SHARED); |
| 4869 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
| 4870 |
| 4871 FixedArray::WhitenessWitness witness(new_descriptors); |
| 4872 |
| 4873 // Copy the descriptors, inserting a descriptor. |
| 4874 int insertion_index = -1; |
| 4875 int to = 0; |
| 4876 for (int from = 0; from < old_size; ++from) { |
| 4877 if (insertion_index < 0 && |
| 4878 InsertionPointFound(descriptors->GetKey(from), key)) { |
| 4879 insertion_index = to++; |
| 4880 } |
| 4881 new_descriptors->CopyFrom(to++, descriptors, from, witness); |
| 4882 } |
| 4883 if (insertion_index < 0) insertion_index = to++; |
| 4884 |
| 4885 ASSERT(to == new_size); |
| 4886 ASSERT(new_size == descriptors->NextEnumerationIndex()); |
| 4887 |
| 4888 descriptor->SetEnumerationIndex(new_size); |
| 4889 new_descriptors->Set(insertion_index, descriptor, witness); |
| 4890 |
| 4891 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
| 4892 |
| 4893 return CopyReplaceDescriptors(new_descriptors, key, insertion_index, flag); |
4836 } | 4894 } |
4837 | 4895 |
4838 | 4896 |
4839 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, | 4897 MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, |
4840 TransitionFlag flag) { | 4898 TransitionFlag flag) { |
4841 DescriptorArray* old_descriptors = instance_descriptors(); | 4899 DescriptorArray* old_descriptors = instance_descriptors(); |
4842 | 4900 |
4843 // Ensure the key is a symbol. | 4901 // Ensure the key is a symbol. |
4844 MaybeObject* maybe_result = descriptor->KeyToSymbol(); | 4902 MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
4845 if (maybe_result->IsFailure()) return maybe_result; | 4903 if (maybe_result->IsFailure()) return maybe_result; |
4846 | 4904 |
4847 DescriptorArray* descriptors; | |
4848 MaybeObject* maybe_descriptors; | |
4849 | |
4850 // We replace the key if it is already present. | 4905 // We replace the key if it is already present. |
4851 int index = old_descriptors->SearchWithCache(descriptor->GetKey()); | 4906 int index = old_descriptors->SearchWithCache(descriptor->GetKey()); |
4852 if (index == DescriptorArray::kNotFound) { | 4907 if (index != DescriptorArray::kNotFound) { |
4853 maybe_descriptors = old_descriptors->CopyAdd(descriptor); | 4908 return CopyReplaceDescriptor(descriptor, index, flag); |
4854 } else { | |
4855 maybe_descriptors = old_descriptors->CopyReplace(descriptor, index); | |
4856 } | 4909 } |
4857 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 4910 return CopyAddDescriptor(descriptor, flag); |
4858 | |
4859 return CopyReplaceDescriptors(descriptors, descriptor->GetKey(), flag); | |
4860 } | 4911 } |
4861 | 4912 |
4862 | 4913 |
4863 MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor, | 4914 MaybeObject* Map::CopyReplaceDescriptor(Descriptor* descriptor, |
4864 int index, | 4915 int insertion_index, |
4865 TransitionFlag flag) { | 4916 TransitionFlag flag) { |
4866 DescriptorArray* descriptors; | 4917 DescriptorArray* descriptors = instance_descriptors(); |
| 4918 int size = descriptors->number_of_descriptors(); |
| 4919 ASSERT(0 <= insertion_index && insertion_index < size); |
| 4920 |
| 4921 // Ensure the key is a symbol. |
| 4922 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); |
| 4923 if (maybe_failure->IsFailure()) return maybe_failure; |
| 4924 |
| 4925 String* key = descriptor->GetKey(); |
| 4926 ASSERT(key == descriptors->GetKey(insertion_index)); |
| 4927 |
| 4928 DescriptorArray* new_descriptors; |
4867 MaybeObject* maybe_descriptors = | 4929 MaybeObject* maybe_descriptors = |
4868 instance_descriptors()->CopyReplace(descriptor, index); | 4930 DescriptorArray::Allocate(size, DescriptorArray::MAY_BE_SHARED); |
4869 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; | 4931 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
4870 | 4932 |
4871 return CopyReplaceDescriptors(descriptors, descriptor->GetKey(), flag); | 4933 FixedArray::WhitenessWitness witness(new_descriptors); |
| 4934 |
| 4935 // Copy the descriptors, replacing a descriptor. |
| 4936 for (int index = 0; index < size; ++index) { |
| 4937 if (index == insertion_index) continue; |
| 4938 new_descriptors->CopyFrom(index, descriptors, index, witness); |
| 4939 } |
| 4940 |
| 4941 descriptor->SetEnumerationIndex( |
| 4942 descriptors->GetDetails(insertion_index).index()); |
| 4943 new_descriptors->Set(insertion_index, descriptor, witness); |
| 4944 |
| 4945 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); |
| 4946 |
| 4947 return CopyReplaceDescriptors( |
| 4948 new_descriptors, key, descriptors->LastAdded(), flag); |
4872 } | 4949 } |
4873 | 4950 |
4874 | 4951 |
4875 void Map::UpdateCodeCache(Handle<Map> map, | 4952 void Map::UpdateCodeCache(Handle<Map> map, |
4876 Handle<String> name, | 4953 Handle<String> name, |
4877 Handle<Code> code) { | 4954 Handle<Code> code) { |
4878 Isolate* isolate = map->GetIsolate(); | 4955 Isolate* isolate = map->GetIsolate(); |
4879 CALL_HEAP_FUNCTION_VOID(isolate, | 4956 CALL_HEAP_FUNCTION_VOID(isolate, |
4880 map->UpdateCodeCache(*name, *code)); | 4957 map->UpdateCodeCache(*name, *code)); |
4881 } | 4958 } |
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5678 FixedArray::cast(bridge_storage)-> | 5755 FixedArray::cast(bridge_storage)-> |
5679 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 5756 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
5680 NoWriteBarrierSet(FixedArray::cast(bridge_storage), | 5757 NoWriteBarrierSet(FixedArray::cast(bridge_storage), |
5681 kEnumCacheBridgeLastAdded, | 5758 kEnumCacheBridgeLastAdded, |
5682 get(kLastAddedIndex)); | 5759 get(kLastAddedIndex)); |
5683 set(kLastAddedIndex, bridge_storage); | 5760 set(kLastAddedIndex, bridge_storage); |
5684 } | 5761 } |
5685 } | 5762 } |
5686 | 5763 |
5687 | 5764 |
5688 static bool InsertionPointFound(String* key1, String* key2) { | |
5689 return key1->Hash() > key2->Hash() || key1 == key2; | |
5690 } | |
5691 | |
5692 | |
5693 void DescriptorArray::CopyFrom(int dst_index, | 5765 void DescriptorArray::CopyFrom(int dst_index, |
5694 DescriptorArray* src, | 5766 DescriptorArray* src, |
5695 int src_index, | 5767 int src_index, |
5696 const WhitenessWitness& witness) { | 5768 const WhitenessWitness& witness) { |
5697 Object* value = src->GetValue(src_index); | 5769 Object* value = src->GetValue(src_index); |
5698 PropertyDetails details = src->GetDetails(src_index); | 5770 PropertyDetails details = src->GetDetails(src_index); |
5699 Descriptor desc(src->GetKey(src_index), value, details); | 5771 Descriptor desc(src->GetKey(src_index), value, details); |
5700 Set(dst_index, &desc, witness); | 5772 Set(dst_index, &desc, witness); |
5701 } | 5773 } |
5702 | 5774 |
5703 | 5775 |
5704 MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, | |
5705 int insertion_index) { | |
5706 ASSERT(0 <= insertion_index && insertion_index < number_of_descriptors()); | |
5707 | |
5708 // Ensure the key is a symbol. | |
5709 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | |
5710 if (maybe_failure->IsFailure()) return maybe_failure; | |
5711 | |
5712 int size = number_of_descriptors(); | |
5713 | |
5714 DescriptorArray* new_descriptors; | |
5715 MaybeObject* maybe_descriptors = Allocate(size, MAY_BE_SHARED); | |
5716 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
5717 | |
5718 FixedArray::WhitenessWitness witness(new_descriptors); | |
5719 | |
5720 // Copy the descriptors, replacing a descriptor. | |
5721 for (int index = 0; index < size; ++index) { | |
5722 if (index == insertion_index) continue; | |
5723 new_descriptors->CopyFrom(index, this, index, witness); | |
5724 } | |
5725 | |
5726 descriptor->SetEnumerationIndex(GetDetails(insertion_index).index()); | |
5727 new_descriptors->Set(insertion_index, descriptor, witness); | |
5728 new_descriptors->SetLastAdded(LastAdded()); | |
5729 | |
5730 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | |
5731 | |
5732 return new_descriptors; | |
5733 } | |
5734 | |
5735 | |
5736 MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { | |
5737 // Ensure the key is a symbol. | |
5738 MaybeObject* maybe_failure = descriptor->KeyToSymbol(); | |
5739 if (maybe_failure->IsFailure()) return maybe_failure; | |
5740 | |
5741 String* key = descriptor->GetKey(); | |
5742 ASSERT(Search(key) == kNotFound); | |
5743 | |
5744 int new_size = number_of_descriptors() + 1; | |
5745 | |
5746 DescriptorArray* new_descriptors; | |
5747 MaybeObject* maybe_descriptors = Allocate(new_size, MAY_BE_SHARED); | |
5748 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | |
5749 | |
5750 FixedArray::WhitenessWitness witness(new_descriptors); | |
5751 | |
5752 // Copy the descriptors, inserting a descriptor. | |
5753 int insertion_index = -1; | |
5754 int to = 0; | |
5755 for (int from = 0; from < number_of_descriptors(); ++from) { | |
5756 if (insertion_index < 0 && InsertionPointFound(GetKey(from), key)) { | |
5757 insertion_index = to++; | |
5758 } | |
5759 new_descriptors->CopyFrom(to++, this, from, witness); | |
5760 } | |
5761 if (insertion_index < 0) insertion_index = to++; | |
5762 | |
5763 ASSERT(to == new_descriptors->number_of_descriptors()); | |
5764 | |
5765 ASSERT(new_size == NextEnumerationIndex()); | |
5766 descriptor->SetEnumerationIndex(new_size); | |
5767 new_descriptors->Set(insertion_index, descriptor, witness); | |
5768 new_descriptors->SetLastAdded(insertion_index); | |
5769 | |
5770 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); | |
5771 | |
5772 return new_descriptors; | |
5773 } | |
5774 | |
5775 | |
5776 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { | 5776 MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { |
5777 // Allocate the new descriptor array. | 5777 // Allocate the new descriptor array. |
5778 int number_of_descriptors = this->number_of_descriptors(); | 5778 int number_of_descriptors = this->number_of_descriptors(); |
5779 DescriptorArray* new_descriptors; | 5779 DescriptorArray* new_descriptors; |
5780 MaybeObject* maybe_result = Allocate(number_of_descriptors, shared_mode); | 5780 MaybeObject* maybe_result = Allocate(number_of_descriptors, shared_mode); |
5781 if (!maybe_result->To(&new_descriptors)) return maybe_result; | 5781 if (!maybe_result->To(&new_descriptors)) return maybe_result; |
5782 | 5782 |
5783 // Copy the content. | 5783 // Copy the content. |
5784 if (number_of_descriptors > 0) { | 5784 if (number_of_descriptors > 0) { |
5785 FixedArray::WhitenessWitness witness(new_descriptors); | 5785 FixedArray::WhitenessWitness witness(new_descriptors); |
5786 for (int i = 0; i < number_of_descriptors; i++) { | 5786 for (int i = 0; i < number_of_descriptors; i++) { |
5787 new_descriptors->CopyFrom(i, this, i, witness); | 5787 new_descriptors->CopyFrom(i, this, i, witness); |
5788 } | 5788 } |
5789 new_descriptors->SetLastAdded(LastAdded()); | |
5790 } | 5789 } |
5791 | 5790 |
5792 return new_descriptors; | 5791 return new_descriptors; |
5793 } | 5792 } |
5794 | 5793 |
5795 | 5794 |
5796 // We need the whiteness witness since sort will reshuffle the entries in the | 5795 // We need the whiteness witness since sort will reshuffle the entries in the |
5797 // descriptor array. If the descriptor array were to be black, the shuffling | 5796 // descriptor array. If the descriptor array were to be black, the shuffling |
5798 // would move a slot that was already recorded as pointing into an evacuation | 5797 // would move a slot that was already recorded as pointing into an evacuation |
5799 // candidate. This would result in missing updates upon evacuation. | 5798 // candidate. This would result in missing updates upon evacuation. |
(...skipping 7235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13035 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13034 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13036 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13035 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13037 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13036 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13038 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13037 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13039 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13038 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13040 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13039 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13041 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13040 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13042 } | 13041 } |
13043 | 13042 |
13044 } } // namespace v8::internal | 13043 } } // namespace v8::internal |
OLD | NEW |