OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2628 old_map->PrintGeneralization( | 2628 old_map->PrintGeneralization( |
2629 stdout, "", modify_index, descriptor, descriptors, | 2629 stdout, "", modify_index, descriptor, descriptors, |
2630 old_descriptors->GetDetails(modify_index).type() == CONSTANT && | 2630 old_descriptors->GetDetails(modify_index).type() == CONSTANT && |
2631 store_mode == FORCE_FIELD, | 2631 store_mode == FORCE_FIELD, |
2632 old_representation, updated_representation); | 2632 old_representation, updated_representation); |
2633 } | 2633 } |
2634 | 2634 |
2635 // Add missing transitions. | 2635 // Add missing transitions. |
2636 Handle<Map> new_map = split_map; | 2636 Handle<Map> new_map = split_map; |
2637 for (; descriptor < descriptors; descriptor++) { | 2637 for (; descriptor < descriptors; descriptor++) { |
2638 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2638 new_map = CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
2639 } | 2639 } |
2640 | 2640 |
2641 new_map->set_owns_descriptors(true); | 2641 new_map->set_owns_descriptors(true); |
2642 return new_map; | 2642 return new_map; |
2643 } | 2643 } |
2644 | 2644 |
2645 | 2645 |
2646 // Generalize the representation of all FIELD descriptors. | 2646 // Generalize the representation of all FIELD descriptors. |
2647 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2647 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
2648 Handle<Map> map, | 2648 Handle<Map> map, |
(...skipping 4138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6787 | 6787 |
6788 | 6788 |
6789 Handle<Map> Map::CopyNormalized(Handle<Map> map, | 6789 Handle<Map> Map::CopyNormalized(Handle<Map> map, |
6790 PropertyNormalizationMode mode, | 6790 PropertyNormalizationMode mode, |
6791 NormalizedMapSharingMode sharing) { | 6791 NormalizedMapSharingMode sharing) { |
6792 int new_instance_size = map->instance_size(); | 6792 int new_instance_size = map->instance_size(); |
6793 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 6793 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
6794 new_instance_size -= map->inobject_properties() * kPointerSize; | 6794 new_instance_size -= map->inobject_properties() * kPointerSize; |
6795 } | 6795 } |
6796 | 6796 |
6797 Handle<Map> result = Map::RawCopy(map, new_instance_size); | 6797 Handle<Map> result = RawCopy(map, new_instance_size); |
6798 | 6798 |
6799 if (mode != CLEAR_INOBJECT_PROPERTIES) { | 6799 if (mode != CLEAR_INOBJECT_PROPERTIES) { |
6800 result->set_inobject_properties(map->inobject_properties()); | 6800 result->set_inobject_properties(map->inobject_properties()); |
6801 } | 6801 } |
6802 | 6802 |
6803 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP); | 6803 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP); |
6804 result->set_dictionary_map(true); | 6804 result->set_dictionary_map(true); |
6805 result->set_migration_target(false); | 6805 result->set_migration_target(false); |
6806 | 6806 |
6807 #ifdef VERIFY_HEAP | 6807 #ifdef VERIFY_HEAP |
(...skipping 24 matching lines...) Expand all Loading... |
6832 | 6832 |
6833 Handle<Map> Map::ShareDescriptor(Handle<Map> map, | 6833 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
6834 Handle<DescriptorArray> descriptors, | 6834 Handle<DescriptorArray> descriptors, |
6835 Descriptor* descriptor) { | 6835 Descriptor* descriptor) { |
6836 // Sanity check. This path is only to be taken if the map owns its descriptor | 6836 // Sanity check. This path is only to be taken if the map owns its descriptor |
6837 // array, implying that its NumberOfOwnDescriptors equals the number of | 6837 // array, implying that its NumberOfOwnDescriptors equals the number of |
6838 // descriptors in the descriptor array. | 6838 // descriptors in the descriptor array. |
6839 ASSERT(map->NumberOfOwnDescriptors() == | 6839 ASSERT(map->NumberOfOwnDescriptors() == |
6840 map->instance_descriptors()->number_of_descriptors()); | 6840 map->instance_descriptors()->number_of_descriptors()); |
6841 | 6841 |
6842 Handle<Map> result = Map::CopyDropDescriptors(map); | 6842 Handle<Map> result = CopyDropDescriptors(map); |
6843 Handle<Name> name = descriptor->GetKey(); | 6843 Handle<Name> name = descriptor->GetKey(); |
6844 Handle<TransitionArray> transitions = | 6844 Handle<TransitionArray> transitions = |
6845 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); | 6845 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); |
6846 | 6846 |
6847 // Ensure there's space for the new descriptor in the shared descriptor array. | 6847 // Ensure there's space for the new descriptor in the shared descriptor array. |
6848 if (descriptors->NumberOfSlackDescriptors() == 0) { | 6848 if (descriptors->NumberOfSlackDescriptors() == 0) { |
6849 int old_size = descriptors->number_of_descriptors(); | 6849 int old_size = descriptors->number_of_descriptors(); |
6850 if (old_size == 0) { | 6850 if (old_size == 0) { |
6851 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); | 6851 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); |
6852 } else { | 6852 } else { |
6853 Map::EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); | 6853 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); |
6854 descriptors = handle(map->instance_descriptors()); | 6854 descriptors = handle(map->instance_descriptors()); |
6855 } | 6855 } |
6856 } | 6856 } |
6857 | 6857 |
6858 // Commit the state atomically. | 6858 // Commit the state atomically. |
6859 DisallowHeapAllocation no_gc; | 6859 DisallowHeapAllocation no_gc; |
6860 | 6860 |
6861 descriptors->Append(descriptor); | 6861 descriptors->Append(descriptor); |
6862 result->SetBackPointer(*map); | 6862 result->SetBackPointer(*map); |
6863 result->InitializeDescriptors(*descriptors); | 6863 result->InitializeDescriptors(*descriptors); |
6864 | 6864 |
6865 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 6865 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
6866 | 6866 |
6867 map->set_transitions(*transitions); | 6867 map->set_transitions(*transitions); |
6868 map->set_owns_descriptors(false); | 6868 map->set_owns_descriptors(false); |
6869 | 6869 |
6870 return result; | 6870 return result; |
6871 } | 6871 } |
6872 | 6872 |
6873 | 6873 |
6874 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6874 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6875 Handle<DescriptorArray> descriptors, | 6875 Handle<DescriptorArray> descriptors, |
6876 TransitionFlag flag, | 6876 TransitionFlag flag, |
6877 SimpleTransitionFlag simple_flag) { | 6877 SimpleTransitionFlag simple_flag) { |
6878 return Map::CopyReplaceDescriptors( | 6878 return CopyReplaceDescriptors( |
6879 map, descriptors, flag, Handle<Name>::null(), simple_flag); | 6879 map, descriptors, flag, Handle<Name>::null(), simple_flag); |
6880 } | 6880 } |
6881 | 6881 |
6882 | 6882 |
6883 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 6883 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
6884 Handle<DescriptorArray> descriptors, | 6884 Handle<DescriptorArray> descriptors, |
6885 TransitionFlag flag, | 6885 TransitionFlag flag, |
6886 Handle<Name> name, | 6886 Handle<Name> name, |
6887 SimpleTransitionFlag simple_flag) { | 6887 SimpleTransitionFlag simple_flag) { |
6888 ASSERT(descriptors->IsSortedNoDuplicates()); | 6888 ASSERT(descriptors->IsSortedNoDuplicates()); |
(...skipping 14 matching lines...) Expand all Loading... |
6903 } | 6903 } |
6904 | 6904 |
6905 | 6905 |
6906 // Since this method is used to rewrite an existing transition tree, it can | 6906 // Since this method is used to rewrite an existing transition tree, it can |
6907 // always insert transitions without checking. | 6907 // always insert transitions without checking. |
6908 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 6908 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
6909 int new_descriptor, | 6909 int new_descriptor, |
6910 Handle<DescriptorArray> descriptors) { | 6910 Handle<DescriptorArray> descriptors) { |
6911 ASSERT(descriptors->IsSortedNoDuplicates()); | 6911 ASSERT(descriptors->IsSortedNoDuplicates()); |
6912 | 6912 |
6913 Handle<Map> result = Map::CopyDropDescriptors(map); | 6913 Handle<Map> result = CopyDropDescriptors(map); |
6914 | 6914 |
6915 result->InitializeDescriptors(*descriptors); | 6915 result->InitializeDescriptors(*descriptors); |
6916 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 6916 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
6917 | 6917 |
6918 int unused_property_fields = map->unused_property_fields(); | 6918 int unused_property_fields = map->unused_property_fields(); |
6919 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { | 6919 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { |
6920 unused_property_fields = map->unused_property_fields() - 1; | 6920 unused_property_fields = map->unused_property_fields() - 1; |
6921 if (unused_property_fields < 0) { | 6921 if (unused_property_fields < 0) { |
6922 unused_property_fields += JSObject::kFieldsAdded; | 6922 unused_property_fields += JSObject::kFieldsAdded; |
6923 } | 6923 } |
(...skipping 27 matching lines...) Expand all Loading... |
6951 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 6951 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
6952 ASSERT(kind != map->elements_kind()); | 6952 ASSERT(kind != map->elements_kind()); |
6953 } | 6953 } |
6954 | 6954 |
6955 bool insert_transition = | 6955 bool insert_transition = |
6956 flag == INSERT_TRANSITION && !map->HasElementsTransition(); | 6956 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
6957 | 6957 |
6958 if (insert_transition && map->owns_descriptors()) { | 6958 if (insert_transition && map->owns_descriptors()) { |
6959 // In case the map owned its own descriptors, share the descriptors and | 6959 // In case the map owned its own descriptors, share the descriptors and |
6960 // transfer ownership to the new map. | 6960 // transfer ownership to the new map. |
6961 Handle<Map> new_map = Map::CopyDropDescriptors(map); | 6961 Handle<Map> new_map = CopyDropDescriptors(map); |
6962 | 6962 |
6963 SetElementsTransitionMap(map, new_map); | 6963 SetElementsTransitionMap(map, new_map); |
6964 | 6964 |
6965 new_map->set_elements_kind(kind); | 6965 new_map->set_elements_kind(kind); |
6966 new_map->InitializeDescriptors(map->instance_descriptors()); | 6966 new_map->InitializeDescriptors(map->instance_descriptors()); |
6967 new_map->SetBackPointer(*map); | 6967 new_map->SetBackPointer(*map); |
6968 map->set_owns_descriptors(false); | 6968 map->set_owns_descriptors(false); |
6969 return new_map; | 6969 return new_map; |
6970 } | 6970 } |
6971 | 6971 |
6972 // In case the map did not own its own descriptors, a split is forced by | 6972 // In case the map did not own its own descriptors, a split is forced by |
6973 // copying the map; creating a new descriptor array cell. | 6973 // copying the map; creating a new descriptor array cell. |
6974 // Create a new free-floating map only if we are not allowed to store it. | 6974 // Create a new free-floating map only if we are not allowed to store it. |
6975 Handle<Map> new_map = Map::Copy(map); | 6975 Handle<Map> new_map = Copy(map); |
6976 | 6976 |
6977 new_map->set_elements_kind(kind); | 6977 new_map->set_elements_kind(kind); |
6978 | 6978 |
6979 if (insert_transition) { | 6979 if (insert_transition) { |
6980 SetElementsTransitionMap(map, new_map); | 6980 SetElementsTransitionMap(map, new_map); |
6981 new_map->SetBackPointer(*map); | 6981 new_map->SetBackPointer(*map); |
6982 } | 6982 } |
6983 | 6983 |
6984 return new_map; | 6984 return new_map; |
6985 } | 6985 } |
6986 | 6986 |
6987 | 6987 |
6988 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 6988 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
6989 ASSERT(!map->is_observed()); | 6989 ASSERT(!map->is_observed()); |
6990 | 6990 |
6991 Isolate* isolate = map->GetIsolate(); | 6991 Isolate* isolate = map->GetIsolate(); |
6992 | 6992 |
6993 // In case the map owned its own descriptors, share the descriptors and | 6993 // In case the map owned its own descriptors, share the descriptors and |
6994 // transfer ownership to the new map. | 6994 // transfer ownership to the new map. |
6995 Handle<Map> new_map; | 6995 Handle<Map> new_map; |
6996 if (map->owns_descriptors()) { | 6996 if (map->owns_descriptors()) { |
6997 new_map = Map::CopyDropDescriptors(map); | 6997 new_map = CopyDropDescriptors(map); |
6998 } else { | 6998 } else { |
6999 new_map = Map::Copy(map); | 6999 new_map = Copy(map); |
7000 } | 7000 } |
7001 | 7001 |
7002 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7002 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
7003 map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION); | 7003 map, isolate->factory()->observed_symbol(), new_map, FULL_TRANSITION); |
7004 | 7004 |
7005 map->set_transitions(*transitions); | 7005 map->set_transitions(*transitions); |
7006 | 7006 |
7007 new_map->set_is_observed(); | 7007 new_map->set_is_observed(); |
7008 | 7008 |
7009 if (map->owns_descriptors()) { | 7009 if (map->owns_descriptors()) { |
7010 new_map->InitializeDescriptors(map->instance_descriptors()); | 7010 new_map->InitializeDescriptors(map->instance_descriptors()); |
7011 map->set_owns_descriptors(false); | 7011 map->set_owns_descriptors(false); |
7012 } | 7012 } |
7013 | 7013 |
7014 new_map->SetBackPointer(*map); | 7014 new_map->SetBackPointer(*map); |
7015 return new_map; | 7015 return new_map; |
7016 } | 7016 } |
7017 | 7017 |
7018 | 7018 |
7019 Handle<Map> Map::Copy(Handle<Map> map) { | 7019 Handle<Map> Map::Copy(Handle<Map> map) { |
7020 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7020 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
7021 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 7021 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
7022 Handle<DescriptorArray> new_descriptors = | 7022 Handle<DescriptorArray> new_descriptors = |
7023 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); | 7023 DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
7024 return Map::CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); | 7024 return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); |
7025 } | 7025 } |
7026 | 7026 |
7027 | 7027 |
7028 Handle<Map> Map::Create(Handle<JSFunction> constructor, | 7028 Handle<Map> Map::Create(Handle<JSFunction> constructor, |
7029 int extra_inobject_properties) { | 7029 int extra_inobject_properties) { |
7030 Handle<Map> copy = Copy(handle(constructor->initial_map())); | 7030 Handle<Map> copy = Copy(handle(constructor->initial_map())); |
7031 | 7031 |
7032 // Check that we do not overflow the instance size when adding the | 7032 // Check that we do not overflow the instance size when adding the |
7033 // extra inobject properties. | 7033 // extra inobject properties. |
7034 int instance_size_delta = extra_inobject_properties * kPointerSize; | 7034 int instance_size_delta = extra_inobject_properties * kPointerSize; |
(...skipping 23 matching lines...) Expand all Loading... |
7058 Descriptor* descriptor, | 7058 Descriptor* descriptor, |
7059 TransitionFlag flag) { | 7059 TransitionFlag flag) { |
7060 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 7060 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
7061 | 7061 |
7062 // Ensure the key is unique. | 7062 // Ensure the key is unique. |
7063 descriptor->KeyToUniqueName(); | 7063 descriptor->KeyToUniqueName(); |
7064 | 7064 |
7065 if (flag == INSERT_TRANSITION && | 7065 if (flag == INSERT_TRANSITION && |
7066 map->owns_descriptors() && | 7066 map->owns_descriptors() && |
7067 map->CanHaveMoreTransitions()) { | 7067 map->CanHaveMoreTransitions()) { |
7068 return Map::ShareDescriptor(map, descriptors, descriptor); | 7068 return ShareDescriptor(map, descriptors, descriptor); |
7069 } | 7069 } |
7070 | 7070 |
7071 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7071 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
7072 descriptors, map->NumberOfOwnDescriptors(), 1); | 7072 descriptors, map->NumberOfOwnDescriptors(), 1); |
7073 new_descriptors->Append(descriptor); | 7073 new_descriptors->Append(descriptor); |
7074 | 7074 |
7075 return Map::CopyReplaceDescriptors( | 7075 return CopyReplaceDescriptors( |
7076 map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION); | 7076 map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION); |
7077 } | 7077 } |
7078 | 7078 |
7079 | 7079 |
7080 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, | 7080 Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
7081 Descriptor* descriptor, | 7081 Descriptor* descriptor, |
7082 TransitionFlag flag) { | 7082 TransitionFlag flag) { |
7083 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); | 7083 Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
7084 | 7084 |
7085 // Ensure the key is unique. | 7085 // Ensure the key is unique. |
7086 descriptor->KeyToUniqueName(); | 7086 descriptor->KeyToUniqueName(); |
7087 | 7087 |
7088 // We replace the key if it is already present. | 7088 // We replace the key if it is already present. |
7089 int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map); | 7089 int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map); |
7090 if (index != DescriptorArray::kNotFound) { | 7090 if (index != DescriptorArray::kNotFound) { |
7091 return Map::CopyReplaceDescriptor( | 7091 return CopyReplaceDescriptor(map, old_descriptors, descriptor, index, flag); |
7092 map, old_descriptors, descriptor, index, flag); | |
7093 } | 7092 } |
7094 return Map::CopyAddDescriptor(map, descriptor, flag); | 7093 return CopyAddDescriptor(map, descriptor, flag); |
7095 } | 7094 } |
7096 | 7095 |
7097 | 7096 |
7098 Handle<DescriptorArray> DescriptorArray::CopyUpTo( | 7097 Handle<DescriptorArray> DescriptorArray::CopyUpTo( |
7099 Handle<DescriptorArray> desc, | 7098 Handle<DescriptorArray> desc, |
7100 int enumeration_index, | 7099 int enumeration_index, |
7101 int slack) { | 7100 int slack) { |
7102 return DescriptorArray::CopyUpToAddAttributes( | 7101 return DescriptorArray::CopyUpToAddAttributes( |
7103 desc, enumeration_index, NONE, slack); | 7102 desc, enumeration_index, NONE, slack); |
7104 } | 7103 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7160 | 7159 |
7161 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7160 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
7162 descriptors, map->NumberOfOwnDescriptors()); | 7161 descriptors, map->NumberOfOwnDescriptors()); |
7163 | 7162 |
7164 new_descriptors->Replace(insertion_index, descriptor); | 7163 new_descriptors->Replace(insertion_index, descriptor); |
7165 | 7164 |
7166 SimpleTransitionFlag simple_flag = | 7165 SimpleTransitionFlag simple_flag = |
7167 (insertion_index == descriptors->number_of_descriptors() - 1) | 7166 (insertion_index == descriptors->number_of_descriptors() - 1) |
7168 ? SIMPLE_TRANSITION | 7167 ? SIMPLE_TRANSITION |
7169 : FULL_TRANSITION; | 7168 : FULL_TRANSITION; |
7170 return Map::CopyReplaceDescriptors( | 7169 return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag); |
7171 map, new_descriptors, flag, key, simple_flag); | |
7172 } | 7170 } |
7173 | 7171 |
7174 | 7172 |
7175 void Map::UpdateCodeCache(Handle<Map> map, | 7173 void Map::UpdateCodeCache(Handle<Map> map, |
7176 Handle<Name> name, | 7174 Handle<Name> name, |
7177 Handle<Code> code) { | 7175 Handle<Code> code) { |
7178 Isolate* isolate = map->GetIsolate(); | 7176 Isolate* isolate = map->GetIsolate(); |
7179 CALL_HEAP_FUNCTION_VOID(isolate, | 7177 CALL_HEAP_FUNCTION_VOID(isolate, |
7180 map->UpdateCodeCache(*name, *code)); | 7178 map->UpdateCodeCache(*name, *code)); |
7181 } | 7179 } |
(...skipping 4344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11526 int capacity = (cache->length() - header) / step; | 11524 int capacity = (cache->length() - header) / step; |
11527 int transitions = map->NumberOfProtoTransitions() + 1; | 11525 int transitions = map->NumberOfProtoTransitions() + 1; |
11528 | 11526 |
11529 if (transitions > capacity) { | 11527 if (transitions > capacity) { |
11530 if (capacity > kMaxCachedPrototypeTransitions) return map; | 11528 if (capacity > kMaxCachedPrototypeTransitions) return map; |
11531 | 11529 |
11532 // Grow array by factor 2 over and above what we need. | 11530 // Grow array by factor 2 over and above what we need. |
11533 Factory* factory = map->GetIsolate()->factory(); | 11531 Factory* factory = map->GetIsolate()->factory(); |
11534 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header); | 11532 cache = factory->CopySizeFixedArray(cache, transitions * 2 * step + header); |
11535 | 11533 |
11536 Map::SetPrototypeTransitions(map, cache); | 11534 SetPrototypeTransitions(map, cache); |
11537 } | 11535 } |
11538 | 11536 |
11539 // Reload number of transitions as GC might shrink them. | 11537 // Reload number of transitions as GC might shrink them. |
11540 int last = map->NumberOfProtoTransitions(); | 11538 int last = map->NumberOfProtoTransitions(); |
11541 int entry = header + last * step; | 11539 int entry = header + last * step; |
11542 | 11540 |
11543 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); | 11541 cache->set(entry + kProtoTransitionPrototypeOffset, *prototype); |
11544 cache->set(entry + kProtoTransitionMapOffset, *target_map); | 11542 cache->set(entry + kProtoTransitionMapOffset, *target_map); |
11545 map->SetNumberOfProtoTransitions(last + 1); | 11543 map->SetNumberOfProtoTransitions(last + 1); |
11546 | 11544 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11806 | 11804 |
11807 void DependentCode::AddToDependentICList(Handle<Code> stub) { | 11805 void DependentCode::AddToDependentICList(Handle<Code> stub) { |
11808 DisallowHeapAllocation no_heap_allocation; | 11806 DisallowHeapAllocation no_heap_allocation; |
11809 GroupStartIndexes starts(this); | 11807 GroupStartIndexes starts(this); |
11810 int i = starts.at(kWeakICGroup); | 11808 int i = starts.at(kWeakICGroup); |
11811 stub->set_next_code_link(object_at(i)); | 11809 stub->set_next_code_link(object_at(i)); |
11812 set_object_at(i, *stub); | 11810 set_object_at(i, *stub); |
11813 } | 11811 } |
11814 | 11812 |
11815 | 11813 |
| 11814 Handle<Map> Map::TransitionToPrototype(Handle<Map> map, |
| 11815 Handle<Object> prototype) { |
| 11816 Handle<Map> new_map = GetPrototypeTransition(map, prototype); |
| 11817 if (new_map.is_null()) { |
| 11818 new_map = Copy(map); |
| 11819 PutPrototypeTransition(map, prototype, new_map); |
| 11820 new_map->set_prototype(*prototype); |
| 11821 } |
| 11822 return new_map; |
| 11823 } |
| 11824 |
| 11825 |
11816 Handle<Object> JSObject::SetPrototype(Handle<JSObject> object, | 11826 Handle<Object> JSObject::SetPrototype(Handle<JSObject> object, |
11817 Handle<Object> value, | 11827 Handle<Object> value, |
11818 bool skip_hidden_prototypes) { | 11828 bool skip_hidden_prototypes) { |
11819 #ifdef DEBUG | 11829 #ifdef DEBUG |
11820 int size = object->Size(); | 11830 int size = object->Size(); |
11821 #endif | 11831 #endif |
11822 | 11832 |
11823 Isolate* isolate = object->GetIsolate(); | 11833 Isolate* isolate = object->GetIsolate(); |
11824 Heap* heap = isolate->heap(); | 11834 Heap* heap = isolate->heap(); |
11825 // Silently ignore the change if value is not a JSObject or null. | 11835 // Silently ignore the change if value is not a JSObject or null. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11876 // Set the new prototype of the object. | 11886 // Set the new prototype of the object. |
11877 Handle<Map> map(real_receiver->map()); | 11887 Handle<Map> map(real_receiver->map()); |
11878 | 11888 |
11879 // Nothing to do if prototype is already set. | 11889 // Nothing to do if prototype is already set. |
11880 if (map->prototype() == *value) return value; | 11890 if (map->prototype() == *value) return value; |
11881 | 11891 |
11882 if (value->IsJSObject()) { | 11892 if (value->IsJSObject()) { |
11883 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 11893 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
11884 } | 11894 } |
11885 | 11895 |
11886 Handle<Map> new_map = Map::GetPrototypeTransition(map, value); | 11896 Handle<Map> new_map = Map::TransitionToPrototype(map, value); |
11887 if (new_map.is_null()) { | |
11888 new_map = Map::Copy(map); | |
11889 Map::PutPrototypeTransition(map, value, new_map); | |
11890 new_map->set_prototype(*value); | |
11891 } | |
11892 ASSERT(new_map->prototype() == *value); | 11897 ASSERT(new_map->prototype() == *value); |
11893 JSObject::MigrateToMap(real_receiver, new_map); | 11898 JSObject::MigrateToMap(real_receiver, new_map); |
11894 | 11899 |
11895 if (!dictionary_elements_in_chain && | 11900 if (!dictionary_elements_in_chain && |
11896 new_map->DictionaryElementsInPrototypeChainOnly()) { | 11901 new_map->DictionaryElementsInPrototypeChainOnly()) { |
11897 // If the prototype chain didn't previously have element callbacks, then | 11902 // If the prototype chain didn't previously have element callbacks, then |
11898 // KeyedStoreICs need to be cleared to ensure any that involve this | 11903 // KeyedStoreICs need to be cleared to ensure any that involve this |
11899 // map go generic. | 11904 // map go generic. |
11900 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); | 11905 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
11901 } | 11906 } |
(...skipping 4615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16517 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16522 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16518 static const char* error_messages_[] = { | 16523 static const char* error_messages_[] = { |
16519 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16524 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16520 }; | 16525 }; |
16521 #undef ERROR_MESSAGES_TEXTS | 16526 #undef ERROR_MESSAGES_TEXTS |
16522 return error_messages_[reason]; | 16527 return error_messages_[reason]; |
16523 } | 16528 } |
16524 | 16529 |
16525 | 16530 |
16526 } } // namespace v8::internal | 16531 } } // namespace v8::internal |
OLD | NEW |