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* new_offset = | |
1065 IntPtrSub(DecodeWord<StoreHandler::FieldOffsetBits>(handler_word), | |
1066 IntPtrConstant(FixedArray::OffsetOfElementAt(0))); | |
1067 constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize; | |
1068 int shift = kPointerSizeLog2 - (mode == SMI_PARAMETERS ? kSmiShift : 0); | |
1069 Node* new_index = WordShr(new_offset, shift); | |
1070 GotoIf(IntPtrOrSmiLessThan(new_index, length, mode), &done); | |
Igor Sheludko
2017/04/21 14:17:50
Probably the following code would be a bit more re
Jakob Kummerow
2017/04/21 17:49:31
Thanks, that's much better. Done.
| |
1071 | |
1064 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); | 1072 Node* delta = IntPtrOrSmiConstant(JSObject::kFieldsAdded, mode); |
1065 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); | 1073 Node* new_capacity = IntPtrOrSmiAdd(length, delta, mode); |
1066 | 1074 |
1067 // Grow properties array. | 1075 // Grow properties array. |
1068 ElementsKind kind = FAST_ELEMENTS; | 1076 ElementsKind kind = FAST_ELEMENTS; |
1069 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < | 1077 DCHECK(kMaxNumberOfDescriptors + JSObject::kFieldsAdded < |
1070 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); | 1078 FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind)); |
1071 // The size of a new properties backing store is guaranteed to be small | 1079 // 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. | 1080 // enough that the new backing store will be allocated in new space. |
1073 CSA_ASSERT(this, | 1081 CSA_ASSERT(this, |
1074 UintPtrOrSmiLessThan( | 1082 UintPtrOrSmiLessThan( |
1075 new_capacity, | 1083 new_capacity, |
1076 IntPtrOrSmiConstant( | 1084 IntPtrOrSmiConstant( |
1077 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), | 1085 kMaxNumberOfDescriptors + JSObject::kFieldsAdded, mode), |
1078 mode)); | 1086 mode)); |
1079 | 1087 |
1080 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); | 1088 Node* new_properties = AllocateFixedArray(kind, new_capacity, mode); |
1081 | 1089 |
1082 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, | 1090 FillFixedArrayWithValue(kind, new_properties, length, new_capacity, |
1083 Heap::kUndefinedValueRootIndex, mode); | 1091 Heap::kUndefinedValueRootIndex, mode); |
1084 | 1092 |
1085 // |new_properties| is guaranteed to be in new space, so we can skip | 1093 // |new_properties| is guaranteed to be in new space, so we can skip |
1086 // the write barrier. | 1094 // the write barrier. |
1087 CopyFixedArrayElements(kind, properties, new_properties, length, | 1095 CopyFixedArrayElements(kind, properties, new_properties, length, |
1088 SKIP_WRITE_BARRIER, mode); | 1096 SKIP_WRITE_BARRIER, mode); |
1089 | 1097 |
1090 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); | 1098 StoreObjectField(object, JSObject::kPropertiesOffset, new_properties); |
1099 Comment("] Extend storage"); | |
1100 Goto(&done); | |
1101 | |
1102 BIND(&done); | |
1091 } | 1103 } |
1092 | 1104 |
1093 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, | 1105 void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, |
1094 bool is_inobject, | 1106 bool is_inobject, |
1095 Representation representation, | 1107 Representation representation, |
1096 Node* value, bool transition_to_field, | 1108 Node* value, bool transition_to_field, |
1097 Label* bailout) { | 1109 Label* bailout) { |
1098 bool store_value_as_double = representation.IsDouble(); | 1110 bool store_value_as_double = representation.IsDouble(); |
1099 Node* property_storage = object; | 1111 Node* property_storage = object; |
1100 if (!is_inobject) { | 1112 if (!is_inobject) { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2489 Node* context = Parameter(Descriptor::kContext); | 2501 Node* context = Parameter(Descriptor::kContext); |
2490 Node* vector = LoadFeedbackVectorForStub(); | 2502 Node* vector = LoadFeedbackVectorForStub(); |
2491 | 2503 |
2492 Callable callable = | 2504 Callable callable = |
2493 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); | 2505 CodeFactory::KeyedStoreICInOptimizedCode(isolate(), language_mode); |
2494 TailCallStub(callable, context, receiver, name, value, slot, vector); | 2506 TailCallStub(callable, context, receiver, name, value, slot, vector); |
2495 } | 2507 } |
2496 | 2508 |
2497 } // namespace internal | 2509 } // namespace internal |
2498 } // namespace v8 | 2510 } // namespace v8 |
OLD | NEW |