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 ExtendPropertiesBackingStore(holder, handler_word); | 987 Label storage_extended(this); |
| 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); |
988 } | 996 } |
989 | 997 |
990 StoreNamedField(handler_word, holder, false, representation, prepared_value, | 998 StoreNamedField(handler_word, holder, false, representation, prepared_value, |
991 transition_to_field, miss); | 999 transition_to_field, miss); |
992 if (transition_to_field) { | 1000 if (transition_to_field) { |
993 StoreMap(holder, transition); | 1001 StoreMap(holder, transition); |
994 } | 1002 } |
995 Return(value); | 1003 Return(value); |
996 } | 1004 } |
997 } | 1005 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 | 1046 |
1039 } else if (representation.IsSmi()) { | 1047 } else if (representation.IsSmi()) { |
1040 GotoIfNot(TaggedIsSmi(value), bailout); | 1048 GotoIfNot(TaggedIsSmi(value), bailout); |
1041 | 1049 |
1042 } else { | 1050 } else { |
1043 DCHECK(representation.IsTagged()); | 1051 DCHECK(representation.IsTagged()); |
1044 } | 1052 } |
1045 return value; | 1053 return value; |
1046 } | 1054 } |
1047 | 1055 |
1048 void AccessorAssembler::ExtendPropertiesBackingStore(Node* object, | 1056 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 | |
1054 ParameterMode mode = OptimalParameterMode(); | 1057 ParameterMode mode = OptimalParameterMode(); |
1055 | 1058 |
1056 Node* properties = LoadProperties(object); | 1059 Node* properties = LoadProperties(object); |
1057 Node* length = (mode == INTPTR_PARAMETERS) | 1060 Node* length = (mode == INTPTR_PARAMETERS) |
1058 ? LoadAndUntagFixedArrayBaseLength(properties) | 1061 ? LoadAndUntagFixedArrayBaseLength(properties) |
1059 : LoadFixedArrayBaseLength(properties); | 1062 : LoadFixedArrayBaseLength(properties); |
1060 | 1063 |
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 | |
1069 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 1064 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
1070 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); | 1065 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
1071 | 1066 |
1072 // Grow properties array. | 1067 // Grow properties array. |
1073 ElementsKind kind = FAST_ELEMENTS; | 1068 ElementsKind kind = FAST_ELEMENTS; |
1074 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | 1069 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < |
1075 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | 1070 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); |
1076 // The size of a new properties backing store is guaranteed to be small | 1071 // The size of a new properties backing store is guaranteed to be small |
1077 // enough that the new backing store will be allocated in new space. | 1072 // enough that the new backing store will be allocated in new space. |
1078 CSA_ASSERT(this, | 1073 CSA_ASSERT(this, |
1079 UintPtrOrSmiLessThan( | 1074 UintPtrOrSmiLessThan( |
1080 new_capacity, | 1075 new_capacity, |
1081 IntPtrOrSmiConstant( | 1076 IntPtrOrSmiConstant( |
1082 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), | 1077 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), |
1083 mode)); | 1078 mode)); |
1084 | 1079 |
1085 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); | 1080 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); |
1086 | 1081 |
1087 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, | 1082 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, |
1088 Heap::kUndefinedValueRootIndex, mode); | 1083 Heap::kUndefinedValueRootIndex, mode); |
1089 | 1084 |
1090 // |new_properties| is guaranteed to be in new space, so we can skip | 1085 // |new_properties| is guaranteed to be in new space, so we can skip |
1091 // the write barrier. | 1086 // the write barrier. |
1092 CopyFixedArrayElements(kind, properties, new_properties, length, | 1087 CopyFixedArrayElements(kind, properties, new_properties, length, |
1093 SKIP_WRITE_BARRIER, mode); | 1088 SKIP_WRITE_BARRIER, mode); |
1094 | 1089 |
1095 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | 1090 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
1096 Comment("] Extend storage"); | |
1097 Goto(&done); | |
1098 | |
1099 BIND(&done); | |
1100 } | 1091 } |
1101 | 1092 |
1102 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, | 1093 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, |
1103 bool is_inobject, | 1094 bool is_inobject, |
1104 Representation representation, | 1095 Representation representation, |
1105 Node* value, bool transition_to_field, | 1096 Node* value, bool transition_to_field, |
1106 Label* bailout) { | 1097 Label* bailout) { |
1107 bool store_value_as_double = representation.IsDouble(); | 1098 bool store_value_as_double = representation.IsDouble(); |
1108 Node* property_storage = object; | 1099 Node* property_storage = object; |
1109 if (!is_inobject) { | 1100 if (!is_inobject) { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 Node* context = Parameter(Descriptor::kContext); | 2489 Node* context = Parameter(Descriptor::kContext); |
2499 Node* vector = LoadFeedbackVectorForStub(); | 2490 Node* vector = LoadFeedbackVectorForStub(); |
2500 | 2491 |
2501 Callable callable = | 2492 Callable callable = |
2502 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); | 2493 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); |
2503 TailCallStub(callable, context, receiver, name, value, slot, vector); | 2494 TailCallStub(callable, context, receiver, name, value, slot, vector); |
2504 } | 2495 } |
2505 | 2496 |
2506 } // namespace internal | 2497 } // namespace internal |
2507 } // namespace v8 | 2498 } // namespace v8 |
OLD | NEW |