| 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 |