OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/counters.h" | 9 #include "src/counters.h" |
10 #include "src/ic/handler-configuration.h" | 10 #include "src/ic/handler-configuration.h" |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 transition_to_field, miss); | 977 transition_to_field, miss); |
978 if (transition_to_field) { | 978 if (transition_to_field) { |
979 StoreMap(holder, transition); | 979 StoreMap(holder, transition); |
980 } | 980 } |
981 Return(value); | 981 Return(value); |
982 } | 982 } |
983 | 983 |
984 BIND(&if_out_of_object); | 984 BIND(&if_out_of_object); |
985 { | 985 { |
986 if (transition_to_field) { | 986 if (transition_to_field) { |
987 Label storage_extended(this); | 987 ExtendPropertiesBackingStore(holder, handler_word); |
988 GotoIfNot(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word), | |
989 &storage_extended); | |
990 Comment("[ Extend storage"); | |
991 ExtendPropertiesBackingStore(holder); | |
992 Comment("] Extend storage"); | |
993 Goto(&storage_extended); | |
994 | |
995 BIND(&storage_extended); | |
996 } | 988 } |
997 | 989 |
998 StoreNamedField(handler_word, holder, false, representation, prepared_value, | 990 StoreNamedField(handler_word, holder, false, representation, prepared_value, |
999 transition_to_field, miss); | 991 transition_to_field, miss); |
1000 if (transition_to_field) { | 992 if (transition_to_field) { |
1001 StoreMap(holder, transition); | 993 StoreMap(holder, transition); |
1002 } | 994 } |
1003 Return(value); | 995 Return(value); |
1004 } | 996 } |
1005 } | 997 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 | 1038 |
1047 } else if (representation.IsSmi()) { | 1039 } else if (representation.IsSmi()) { |
1048 GotoIfNot(TaggedIsSmi(value), bailout); | 1040 GotoIfNot(TaggedIsSmi(value), bailout); |
1049 | 1041 |
1050 } else { | 1042 } else { |
1051 DCHECK(representation.IsTagged()); | 1043 DCHECK(representation.IsTagged()); |
1052 } | 1044 } |
1053 return value; | 1045 return value; |
1054 } | 1046 } |
1055 | 1047 |
1056 void AccessorAssembler::ExtendPropertiesBackingStore(Node* object) { | 1048 void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, |
| 1049 Node* handler_word) { |
| 1050 Label done(this); |
| 1051 GotoIfNot(IsSetWord<StoreHandler::ExtendStorageBits>(handler_word), &done); |
| 1052 Comment("[ Extend storage"); |
| 1053 |
1057 ParameterMode mode = OptimalParameterMode(); | 1054 ParameterMode mode = OptimalParameterMode(); |
1058 | 1055 |
1059 Node* properties = LoadProperties(object); | 1056 Node* properties = LoadProperties(object); |
1060 Node* length = (mode == INTPTR_PARAMETERS) | 1057 Node* length = (mode == INTPTR_PARAMETERS) |
1061 ? LoadAndUntagFixedArrayBaseLength(properties) | 1058 ? LoadAndUntagFixedArrayBaseLength(properties) |
1062 : LoadFixedArrayBaseLength(properties); | 1059 : LoadFixedArrayBaseLength(properties); |
1063 | 1060 |
| 1061 // Previous property deletion could have left behind unused backing store |
| 1062 // capacity even for a map that think it doesn't have any unused fields. |
| 1063 // Perform a bounds check to see if we actually have to grow the array. |
| 1064 Node* offset = DecodeWord<StoreHandler::FieldOffsetBits>(handler_word); |
| 1065 Node* size = ElementOffsetFromIndex(length, FAST_ELEMENTS, mode, |
| 1066 FixedArray::kHeaderSize); |
| 1067 GotoIf(UintPtrLessThan(offset, size), &done); |
| 1068 |
1064 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 1069 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
1065 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); | 1070 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
1066 | 1071 |
1067 // Grow properties array. | 1072 // Grow properties array. |
1068 ElementsKind kind = FAST_ELEMENTS; | 1073 ElementsKind kind = FAST_ELEMENTS; |
1069 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | 1074 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < |
1070 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | 1075 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); |
1071 // The size of a new properties backing store is guaranteed to be small | 1076 // The size of a new properties backing store is guaranteed to be small |
1072 // enough that the new backing store will be allocated in new space. | 1077 // enough that the new backing store will be allocated in new space. |
1073 CSA_ASSERT(this, | 1078 CSA_ASSERT(this, |
1074 UintPtrOrSmiLessThan( | 1079 UintPtrOrSmiLessThan( |
1075 new_capacity, | 1080 new_capacity, |
1076 IntPtrOrSmiConstant( | 1081 IntPtrOrSmiConstant( |
1077 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), | 1082 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), |
1078 mode)); | 1083 mode)); |
1079 | 1084 |
1080 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); | 1085 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); |
1081 | 1086 |
1082 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, | 1087 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, |
1083 Heap::kUndefinedValueRootIndex, mode); | 1088 Heap::kUndefinedValueRootIndex, mode); |
1084 | 1089 |
1085 // |new_properties| is guaranteed to be in new space, so we can skip | 1090 // |new_properties| is guaranteed to be in new space, so we can skip |
1086 // the write barrier. | 1091 // the write barrier. |
1087 CopyFixedArrayElements(kind, properties, new_properties, length, | 1092 CopyFixedArrayElements(kind, properties, new_properties, length, |
1088 SKIP_WRITE_BARRIER, mode); | 1093 SKIP_WRITE_BARRIER, mode); |
1089 | 1094 |
1090 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | 1095 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
| 1096 Comment("] Extend storage"); |
| 1097 Goto(&done); |
| 1098 |
| 1099 BIND(&done); |
1091 } | 1100 } |
1092 | 1101 |
1093 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, | 1102 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, |
1094 bool is_inobject, | 1103 bool is_inobject, |
1095 Representation representation, | 1104 Representation representation, |
1096 Node* value, bool transition_to_field, | 1105 Node* value, bool transition_to_field, |
1097 Label* bailout) { | 1106 Label* bailout) { |
1098 bool store_value_as_double = representation.IsDouble(); | 1107 bool store_value_as_double = representation.IsDouble(); |
1099 Node* property_storage = object; | 1108 Node* property_storage = object; |
1100 if (!is_inobject) { | 1109 if (!is_inobject) { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2489 Node* context = Parameter(Descriptor::kContext); | 2498 Node* context = Parameter(Descriptor::kContext); |
2490 Node* vector = LoadFeedbackVectorForStub(); | 2499 Node* vector = LoadFeedbackVectorForStub(); |
2491 | 2500 |
2492 Callable callable = | 2501 Callable callable = |
2493 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); | 2502 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); |
2494 TailCallStub(callable, context, receiver, name, value, slot, vector); | 2503 TailCallStub(callable, context, receiver, name, value, slot, vector); |
2495 } | 2504 } |
2496 | 2505 |
2497 } // namespace internal | 2506 } // namespace internal |
2498 } // namespace v8 | 2507 } // namespace v8 |
OLD | NEW |