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/value-serializer.h" | 5 #include "src/value-serializer.h" |
6 | 6 |
7 #include <type_traits> | 7 #include <type_traits> |
8 | 8 |
9 #include "src/base/logging.h" | 9 #include "src/base/logging.h" |
10 #include "src/conversions.h" | 10 #include "src/conversions.h" |
11 #include "src/factory.h" | 11 #include "src/factory.h" |
12 #include "src/handles-inl.h" | 12 #include "src/handles-inl.h" |
13 #include "src/isolate.h" | 13 #include "src/isolate.h" |
14 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
15 #include "src/objects.h" | 15 #include "src/objects.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 static const uint32_t kLatestVersion = 9; | 20 static const uint32_t kLatestVersion = 9; |
| 21 static const int kPretenureThreshold = 100 * KB; |
21 | 22 |
22 template <typename T> | 23 template <typename T> |
23 static size_t BytesNeededForVarint(T value) { | 24 static size_t BytesNeededForVarint(T value) { |
24 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, | 25 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, |
25 "Only unsigned integer types can be written as varints."); | 26 "Only unsigned integer types can be written as varints."); |
26 size_t result = 0; | 27 size_t result = 0; |
27 do { | 28 do { |
28 result++; | 29 result++; |
29 value >>= 7; | 30 value >>= 7; |
30 } while (value); | 31 } while (value); |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 isolate_->Throw( | 745 isolate_->Throw( |
745 *isolate_->factory()->NewError(isolate_->error_function(), message)); | 746 *isolate_->factory()->NewError(isolate_->error_function(), message)); |
746 } | 747 } |
747 } | 748 } |
748 | 749 |
749 ValueDeserializer::ValueDeserializer(Isolate* isolate, | 750 ValueDeserializer::ValueDeserializer(Isolate* isolate, |
750 Vector<const uint8_t> data) | 751 Vector<const uint8_t> data) |
751 : isolate_(isolate), | 752 : isolate_(isolate), |
752 position_(data.start()), | 753 position_(data.start()), |
753 end_(data.start() + data.length()), | 754 end_(data.start() + data.length()), |
| 755 pretenure_(data.length() > kPretenureThreshold ? TENURED : NOT_TENURED), |
754 id_map_(Handle<SeededNumberDictionary>::cast( | 756 id_map_(Handle<SeededNumberDictionary>::cast( |
755 isolate->global_handles()->Create( | 757 isolate->global_handles()->Create( |
756 *SeededNumberDictionary::New(isolate, 0)))) {} | 758 *SeededNumberDictionary::New(isolate, 0)))) {} |
757 | 759 |
758 ValueDeserializer::~ValueDeserializer() { | 760 ValueDeserializer::~ValueDeserializer() { |
759 GlobalHandles::Destroy(Handle<Object>::cast(id_map_).location()); | 761 GlobalHandles::Destroy(Handle<Object>::cast(id_map_).location()); |
760 | 762 |
761 Handle<Object> transfer_map_handle; | 763 Handle<Object> transfer_map_handle; |
762 if (array_buffer_transfer_map_.ToHandle(&transfer_map_handle)) { | 764 if (array_buffer_transfer_map_.ToHandle(&transfer_map_handle)) { |
763 GlobalHandles::Destroy(transfer_map_handle.location()); | 765 GlobalHandles::Destroy(transfer_map_handle.location()); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 return isolate_->factory()->undefined_value(); | 915 return isolate_->factory()->undefined_value(); |
914 case SerializationTag::kNull: | 916 case SerializationTag::kNull: |
915 return isolate_->factory()->null_value(); | 917 return isolate_->factory()->null_value(); |
916 case SerializationTag::kTrue: | 918 case SerializationTag::kTrue: |
917 return isolate_->factory()->true_value(); | 919 return isolate_->factory()->true_value(); |
918 case SerializationTag::kFalse: | 920 case SerializationTag::kFalse: |
919 return isolate_->factory()->false_value(); | 921 return isolate_->factory()->false_value(); |
920 case SerializationTag::kInt32: { | 922 case SerializationTag::kInt32: { |
921 Maybe<int32_t> number = ReadZigZag<int32_t>(); | 923 Maybe<int32_t> number = ReadZigZag<int32_t>(); |
922 if (number.IsNothing()) return MaybeHandle<Object>(); | 924 if (number.IsNothing()) return MaybeHandle<Object>(); |
923 return isolate_->factory()->NewNumberFromInt(number.FromJust()); | 925 return isolate_->factory()->NewNumberFromInt(number.FromJust(), |
| 926 pretenure_); |
924 } | 927 } |
925 case SerializationTag::kUint32: { | 928 case SerializationTag::kUint32: { |
926 Maybe<uint32_t> number = ReadVarint<uint32_t>(); | 929 Maybe<uint32_t> number = ReadVarint<uint32_t>(); |
927 if (number.IsNothing()) return MaybeHandle<Object>(); | 930 if (number.IsNothing()) return MaybeHandle<Object>(); |
928 return isolate_->factory()->NewNumberFromUint(number.FromJust()); | 931 return isolate_->factory()->NewNumberFromUint(number.FromJust(), |
| 932 pretenure_); |
929 } | 933 } |
930 case SerializationTag::kDouble: { | 934 case SerializationTag::kDouble: { |
931 Maybe<double> number = ReadDouble(); | 935 Maybe<double> number = ReadDouble(); |
932 if (number.IsNothing()) return MaybeHandle<Object>(); | 936 if (number.IsNothing()) return MaybeHandle<Object>(); |
933 return isolate_->factory()->NewNumber(number.FromJust()); | 937 return isolate_->factory()->NewNumber(number.FromJust(), pretenure_); |
934 } | 938 } |
935 case SerializationTag::kUtf8String: | 939 case SerializationTag::kUtf8String: |
936 return ReadUtf8String(); | 940 return ReadUtf8String(); |
937 case SerializationTag::kTwoByteString: | 941 case SerializationTag::kTwoByteString: |
938 return ReadTwoByteString(); | 942 return ReadTwoByteString(); |
939 case SerializationTag::kObjectReference: { | 943 case SerializationTag::kObjectReference: { |
940 uint32_t id; | 944 uint32_t id; |
941 if (!ReadVarint<uint32_t>().To(&id)) return MaybeHandle<Object>(); | 945 if (!ReadVarint<uint32_t>().To(&id)) return MaybeHandle<Object>(); |
942 return GetObjectWithID(id); | 946 return GetObjectWithID(id); |
943 } | 947 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 | 981 |
978 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { | 982 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { |
979 uint32_t utf8_length; | 983 uint32_t utf8_length; |
980 Vector<const uint8_t> utf8_bytes; | 984 Vector<const uint8_t> utf8_bytes; |
981 if (!ReadVarint<uint32_t>().To(&utf8_length) || | 985 if (!ReadVarint<uint32_t>().To(&utf8_length) || |
982 utf8_length > | 986 utf8_length > |
983 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) || | 987 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) || |
984 !ReadRawBytes(utf8_length).To(&utf8_bytes)) | 988 !ReadRawBytes(utf8_length).To(&utf8_bytes)) |
985 return MaybeHandle<String>(); | 989 return MaybeHandle<String>(); |
986 return isolate_->factory()->NewStringFromUtf8( | 990 return isolate_->factory()->NewStringFromUtf8( |
987 Vector<const char>::cast(utf8_bytes)); | 991 Vector<const char>::cast(utf8_bytes), pretenure_); |
988 } | 992 } |
989 | 993 |
990 MaybeHandle<String> ValueDeserializer::ReadTwoByteString() { | 994 MaybeHandle<String> ValueDeserializer::ReadTwoByteString() { |
991 uint32_t byte_length; | 995 uint32_t byte_length; |
992 Vector<const uint8_t> bytes; | 996 Vector<const uint8_t> bytes; |
993 if (!ReadVarint<uint32_t>().To(&byte_length) || | 997 if (!ReadVarint<uint32_t>().To(&byte_length) || |
994 byte_length > | 998 byte_length > |
995 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) || | 999 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) || |
996 byte_length % sizeof(uc16) != 0 || !ReadRawBytes(byte_length).To(&bytes)) | 1000 byte_length % sizeof(uc16) != 0 || !ReadRawBytes(byte_length).To(&bytes)) |
997 return MaybeHandle<String>(); | 1001 return MaybeHandle<String>(); |
998 | 1002 |
999 // Allocate an uninitialized string so that we can do a raw memcpy into the | 1003 // Allocate an uninitialized string so that we can do a raw memcpy into the |
1000 // string on the heap (regardless of alignment). | 1004 // string on the heap (regardless of alignment). |
1001 Handle<SeqTwoByteString> string; | 1005 Handle<SeqTwoByteString> string; |
1002 if (!isolate_->factory() | 1006 if (!isolate_->factory() |
1003 ->NewRawTwoByteString(byte_length / sizeof(uc16)) | 1007 ->NewRawTwoByteString(byte_length / sizeof(uc16), pretenure_) |
1004 .ToHandle(&string)) | 1008 .ToHandle(&string)) |
1005 return MaybeHandle<String>(); | 1009 return MaybeHandle<String>(); |
1006 | 1010 |
1007 // Copy the bytes directly into the new string. | 1011 // Copy the bytes directly into the new string. |
1008 // Warning: this uses host endianness. | 1012 // Warning: this uses host endianness. |
1009 memcpy(string->GetChars(), bytes.begin(), bytes.length()); | 1013 memcpy(string->GetChars(), bytes.begin(), bytes.length()); |
1010 return string; | 1014 return string; |
1011 } | 1015 } |
1012 | 1016 |
1013 MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() { | 1017 MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() { |
1014 // If we are at the end of the stack, abort. This function may recurse. | 1018 // If we are at the end of the stack, abort. This function may recurse. |
1015 STACK_CHECK(isolate_, MaybeHandle<JSObject>()); | 1019 STACK_CHECK(isolate_, MaybeHandle<JSObject>()); |
1016 | 1020 |
1017 uint32_t id = next_id_++; | 1021 uint32_t id = next_id_++; |
1018 HandleScope scope(isolate_); | 1022 HandleScope scope(isolate_); |
1019 Handle<JSObject> object = | 1023 Handle<JSObject> object = |
1020 isolate_->factory()->NewJSObject(isolate_->object_function()); | 1024 isolate_->factory()->NewJSObject(isolate_->object_function(), pretenure_); |
1021 AddObjectWithID(id, object); | 1025 AddObjectWithID(id, object); |
1022 | 1026 |
1023 uint32_t num_properties; | 1027 uint32_t num_properties; |
1024 uint32_t expected_num_properties; | 1028 uint32_t expected_num_properties; |
1025 if (!ReadJSObjectProperties(object, SerializationTag::kEndJSObject) | 1029 if (!ReadJSObjectProperties(object, SerializationTag::kEndJSObject) |
1026 .To(&num_properties) || | 1030 .To(&num_properties) || |
1027 !ReadVarint<uint32_t>().To(&expected_num_properties) || | 1031 !ReadVarint<uint32_t>().To(&expected_num_properties) || |
1028 num_properties != expected_num_properties) { | 1032 num_properties != expected_num_properties) { |
1029 return MaybeHandle<JSObject>(); | 1033 return MaybeHandle<JSObject>(); |
1030 } | 1034 } |
1031 | 1035 |
1032 DCHECK(HasObjectWithID(id)); | 1036 DCHECK(HasObjectWithID(id)); |
1033 return scope.CloseAndEscape(object); | 1037 return scope.CloseAndEscape(object); |
1034 } | 1038 } |
1035 | 1039 |
1036 MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() { | 1040 MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() { |
1037 // If we are at the end of the stack, abort. This function may recurse. | 1041 // If we are at the end of the stack, abort. This function may recurse. |
1038 STACK_CHECK(isolate_, MaybeHandle<JSArray>()); | 1042 STACK_CHECK(isolate_, MaybeHandle<JSArray>()); |
1039 | 1043 |
1040 uint32_t length; | 1044 uint32_t length; |
1041 if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); | 1045 if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); |
1042 | 1046 |
1043 uint32_t id = next_id_++; | 1047 uint32_t id = next_id_++; |
1044 HandleScope scope(isolate_); | 1048 HandleScope scope(isolate_); |
1045 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 1049 Handle<JSArray> array = isolate_->factory()->NewJSArray( |
| 1050 0, TERMINAL_FAST_ELEMENTS_KIND, pretenure_); |
1046 JSArray::SetLength(array, length); | 1051 JSArray::SetLength(array, length); |
1047 AddObjectWithID(id, array); | 1052 AddObjectWithID(id, array); |
1048 | 1053 |
1049 uint32_t num_properties; | 1054 uint32_t num_properties; |
1050 uint32_t expected_num_properties; | 1055 uint32_t expected_num_properties; |
1051 uint32_t expected_length; | 1056 uint32_t expected_length; |
1052 if (!ReadJSObjectProperties(array, SerializationTag::kEndSparseJSArray) | 1057 if (!ReadJSObjectProperties(array, SerializationTag::kEndSparseJSArray) |
1053 .To(&num_properties) || | 1058 .To(&num_properties) || |
1054 !ReadVarint<uint32_t>().To(&expected_num_properties) || | 1059 !ReadVarint<uint32_t>().To(&expected_num_properties) || |
1055 !ReadVarint<uint32_t>().To(&expected_length) || | 1060 !ReadVarint<uint32_t>().To(&expected_length) || |
1056 num_properties != expected_num_properties || length != expected_length) { | 1061 num_properties != expected_num_properties || length != expected_length) { |
1057 return MaybeHandle<JSArray>(); | 1062 return MaybeHandle<JSArray>(); |
1058 } | 1063 } |
1059 | 1064 |
1060 DCHECK(HasObjectWithID(id)); | 1065 DCHECK(HasObjectWithID(id)); |
1061 return scope.CloseAndEscape(array); | 1066 return scope.CloseAndEscape(array); |
1062 } | 1067 } |
1063 | 1068 |
1064 MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() { | 1069 MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() { |
1065 // If we are at the end of the stack, abort. This function may recurse. | 1070 // If we are at the end of the stack, abort. This function may recurse. |
1066 STACK_CHECK(isolate_, MaybeHandle<JSArray>()); | 1071 STACK_CHECK(isolate_, MaybeHandle<JSArray>()); |
1067 | 1072 |
1068 uint32_t length; | 1073 uint32_t length; |
1069 if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); | 1074 if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); |
1070 | 1075 |
1071 uint32_t id = next_id_++; | 1076 uint32_t id = next_id_++; |
1072 HandleScope scope(isolate_); | 1077 HandleScope scope(isolate_); |
1073 Handle<JSArray> array = isolate_->factory()->NewJSArray( | 1078 Handle<JSArray> array = isolate_->factory()->NewJSArray( |
1074 FAST_HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 1079 FAST_HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, |
| 1080 pretenure_); |
1075 AddObjectWithID(id, array); | 1081 AddObjectWithID(id, array); |
1076 | 1082 |
1077 Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_); | 1083 Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_); |
1078 for (uint32_t i = 0; i < length; i++) { | 1084 for (uint32_t i = 0; i < length; i++) { |
1079 Handle<Object> element; | 1085 Handle<Object> element; |
1080 if (!ReadObject().ToHandle(&element)) return MaybeHandle<JSArray>(); | 1086 if (!ReadObject().ToHandle(&element)) return MaybeHandle<JSArray>(); |
1081 // TODO(jbroman): Distinguish between undefined and a hole. | 1087 // TODO(jbroman): Distinguish between undefined and a hole. |
1082 if (element->IsUndefined(isolate_)) continue; | 1088 if (element->IsUndefined(isolate_)) continue; |
1083 elements->set(i, *element); | 1089 elements->set(i, *element); |
1084 } | 1090 } |
(...skipping 24 matching lines...) Expand all Loading... |
1109 } | 1115 } |
1110 AddObjectWithID(id, date); | 1116 AddObjectWithID(id, date); |
1111 return date; | 1117 return date; |
1112 } | 1118 } |
1113 | 1119 |
1114 MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) { | 1120 MaybeHandle<JSValue> ValueDeserializer::ReadJSValue(SerializationTag tag) { |
1115 uint32_t id = next_id_++; | 1121 uint32_t id = next_id_++; |
1116 Handle<JSValue> value; | 1122 Handle<JSValue> value; |
1117 switch (tag) { | 1123 switch (tag) { |
1118 case SerializationTag::kTrueObject: | 1124 case SerializationTag::kTrueObject: |
1119 value = Handle<JSValue>::cast( | 1125 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( |
1120 isolate_->factory()->NewJSObject(isolate_->boolean_function())); | 1126 isolate_->boolean_function(), pretenure_)); |
1121 value->set_value(isolate_->heap()->true_value()); | 1127 value->set_value(isolate_->heap()->true_value()); |
1122 break; | 1128 break; |
1123 case SerializationTag::kFalseObject: | 1129 case SerializationTag::kFalseObject: |
1124 value = Handle<JSValue>::cast( | 1130 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( |
1125 isolate_->factory()->NewJSObject(isolate_->boolean_function())); | 1131 isolate_->boolean_function(), pretenure_)); |
1126 value->set_value(isolate_->heap()->false_value()); | 1132 value->set_value(isolate_->heap()->false_value()); |
1127 break; | 1133 break; |
1128 case SerializationTag::kNumberObject: { | 1134 case SerializationTag::kNumberObject: { |
1129 double number; | 1135 double number; |
1130 if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>(); | 1136 if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>(); |
1131 value = Handle<JSValue>::cast( | 1137 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( |
1132 isolate_->factory()->NewJSObject(isolate_->number_function())); | 1138 isolate_->number_function(), pretenure_)); |
1133 Handle<Object> number_object = isolate_->factory()->NewNumber(number); | 1139 Handle<Object> number_object = |
| 1140 isolate_->factory()->NewNumber(number, pretenure_); |
1134 value->set_value(*number_object); | 1141 value->set_value(*number_object); |
1135 break; | 1142 break; |
1136 } | 1143 } |
1137 case SerializationTag::kStringObject: { | 1144 case SerializationTag::kStringObject: { |
1138 Handle<String> string; | 1145 Handle<String> string; |
1139 if (!ReadUtf8String().ToHandle(&string)) return MaybeHandle<JSValue>(); | 1146 if (!ReadUtf8String().ToHandle(&string)) return MaybeHandle<JSValue>(); |
1140 value = Handle<JSValue>::cast( | 1147 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( |
1141 isolate_->factory()->NewJSObject(isolate_->string_function())); | 1148 isolate_->string_function(), pretenure_)); |
1142 value->set_value(*string); | 1149 value->set_value(*string); |
1143 break; | 1150 break; |
1144 } | 1151 } |
1145 default: | 1152 default: |
1146 UNREACHABLE(); | 1153 UNREACHABLE(); |
1147 return MaybeHandle<JSValue>(); | 1154 return MaybeHandle<JSValue>(); |
1148 } | 1155 } |
1149 AddObjectWithID(id, value); | 1156 AddObjectWithID(id, value); |
1150 return value; | 1157 return value; |
1151 } | 1158 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 | 1247 |
1241 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer() { | 1248 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer() { |
1242 uint32_t id = next_id_++; | 1249 uint32_t id = next_id_++; |
1243 uint32_t byte_length; | 1250 uint32_t byte_length; |
1244 Vector<const uint8_t> bytes; | 1251 Vector<const uint8_t> bytes; |
1245 if (!ReadVarint<uint32_t>().To(&byte_length) || | 1252 if (!ReadVarint<uint32_t>().To(&byte_length) || |
1246 byte_length > static_cast<size_t>(end_ - position_)) { | 1253 byte_length > static_cast<size_t>(end_ - position_)) { |
1247 return MaybeHandle<JSArrayBuffer>(); | 1254 return MaybeHandle<JSArrayBuffer>(); |
1248 } | 1255 } |
1249 const bool should_initialize = false; | 1256 const bool should_initialize = false; |
1250 Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer(); | 1257 Handle<JSArrayBuffer> array_buffer = |
| 1258 isolate_->factory()->NewJSArrayBuffer(SharedFlag::kNotShared, pretenure_); |
1251 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length, | 1259 JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length, |
1252 should_initialize); | 1260 should_initialize); |
1253 memcpy(array_buffer->backing_store(), position_, byte_length); | 1261 memcpy(array_buffer->backing_store(), position_, byte_length); |
1254 position_ += byte_length; | 1262 position_ += byte_length; |
1255 AddObjectWithID(id, array_buffer); | 1263 AddObjectWithID(id, array_buffer); |
1256 return array_buffer; | 1264 return array_buffer; |
1257 } | 1265 } |
1258 | 1266 |
1259 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer( | 1267 MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadTransferredJSArrayBuffer( |
1260 bool is_shared) { | 1268 bool is_shared) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 external_array_type = kExternal##Type##Array; \ | 1312 external_array_type = kExternal##Type##Array; \ |
1305 element_size = size; \ | 1313 element_size = size; \ |
1306 break; | 1314 break; |
1307 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1315 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1308 #undef TYPED_ARRAY_CASE | 1316 #undef TYPED_ARRAY_CASE |
1309 } | 1317 } |
1310 if (byte_offset % element_size != 0 || byte_length % element_size != 0) { | 1318 if (byte_offset % element_size != 0 || byte_length % element_size != 0) { |
1311 return MaybeHandle<JSArrayBufferView>(); | 1319 return MaybeHandle<JSArrayBufferView>(); |
1312 } | 1320 } |
1313 Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray( | 1321 Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray( |
1314 external_array_type, buffer, byte_offset, byte_length / element_size); | 1322 external_array_type, buffer, byte_offset, byte_length / element_size, |
| 1323 pretenure_); |
1315 AddObjectWithID(id, typed_array); | 1324 AddObjectWithID(id, typed_array); |
1316 return typed_array; | 1325 return typed_array; |
1317 } | 1326 } |
1318 | 1327 |
1319 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( | 1328 Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( |
1320 Handle<JSObject> object, SerializationTag end_tag) { | 1329 Handle<JSObject> object, SerializationTag end_tag) { |
1321 for (uint32_t num_properties = 0;; num_properties++) { | 1330 for (uint32_t num_properties = 0;; num_properties++) { |
1322 SerializationTag tag; | 1331 SerializationTag tag; |
1323 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); | 1332 if (!PeekTag().To(&tag)) return Nothing<uint32_t>(); |
1324 if (tag == end_tag) { | 1333 if (tag == end_tag) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1408 // JS Object: Read the last 2*n values from the stack and use them as | 1417 // JS Object: Read the last 2*n values from the stack and use them as |
1409 // key-value pairs. | 1418 // key-value pairs. |
1410 uint32_t num_properties; | 1419 uint32_t num_properties; |
1411 if (!ReadVarint<uint32_t>().To(&num_properties) || | 1420 if (!ReadVarint<uint32_t>().To(&num_properties) || |
1412 stack.size() / 2 < num_properties) { | 1421 stack.size() / 2 < num_properties) { |
1413 return MaybeHandle<Object>(); | 1422 return MaybeHandle<Object>(); |
1414 } | 1423 } |
1415 | 1424 |
1416 size_t begin_properties = | 1425 size_t begin_properties = |
1417 stack.size() - 2 * static_cast<size_t>(num_properties); | 1426 stack.size() - 2 * static_cast<size_t>(num_properties); |
1418 Handle<JSObject> js_object = | 1427 Handle<JSObject> js_object = isolate_->factory()->NewJSObject( |
1419 isolate_->factory()->NewJSObject(isolate_->object_function()); | 1428 isolate_->object_function(), pretenure_); |
1420 if (num_properties && | 1429 if (num_properties && |
1421 !SetPropertiesFromKeyValuePairs( | 1430 !SetPropertiesFromKeyValuePairs( |
1422 isolate_, js_object, &stack[begin_properties], num_properties) | 1431 isolate_, js_object, &stack[begin_properties], num_properties) |
1423 .FromMaybe(false)) { | 1432 .FromMaybe(false)) { |
1424 return MaybeHandle<Object>(); | 1433 return MaybeHandle<Object>(); |
1425 } | 1434 } |
1426 | 1435 |
1427 stack.resize(begin_properties); | 1436 stack.resize(begin_properties); |
1428 new_object = js_object; | 1437 new_object = js_object; |
1429 break; | 1438 break; |
1430 } | 1439 } |
1431 case SerializationTag::kEndSparseJSArray: { | 1440 case SerializationTag::kEndSparseJSArray: { |
1432 ConsumeTag(SerializationTag::kEndSparseJSArray); | 1441 ConsumeTag(SerializationTag::kEndSparseJSArray); |
1433 | 1442 |
1434 // Sparse JS Array: Read the last 2*|num_properties| from the stack. | 1443 // Sparse JS Array: Read the last 2*|num_properties| from the stack. |
1435 uint32_t num_properties; | 1444 uint32_t num_properties; |
1436 uint32_t length; | 1445 uint32_t length; |
1437 if (!ReadVarint<uint32_t>().To(&num_properties) || | 1446 if (!ReadVarint<uint32_t>().To(&num_properties) || |
1438 !ReadVarint<uint32_t>().To(&length) || | 1447 !ReadVarint<uint32_t>().To(&length) || |
1439 stack.size() / 2 < num_properties) { | 1448 stack.size() / 2 < num_properties) { |
1440 return MaybeHandle<Object>(); | 1449 return MaybeHandle<Object>(); |
1441 } | 1450 } |
1442 | 1451 |
1443 Handle<JSArray> js_array = isolate_->factory()->NewJSArray(0); | 1452 Handle<JSArray> js_array = isolate_->factory()->NewJSArray( |
| 1453 0, TERMINAL_FAST_ELEMENTS_KIND, pretenure_); |
1444 JSArray::SetLength(js_array, length); | 1454 JSArray::SetLength(js_array, length); |
1445 size_t begin_properties = | 1455 size_t begin_properties = |
1446 stack.size() - 2 * static_cast<size_t>(num_properties); | 1456 stack.size() - 2 * static_cast<size_t>(num_properties); |
1447 if (num_properties && | 1457 if (num_properties && |
1448 !SetPropertiesFromKeyValuePairs( | 1458 !SetPropertiesFromKeyValuePairs( |
1449 isolate_, js_array, &stack[begin_properties], num_properties) | 1459 isolate_, js_array, &stack[begin_properties], num_properties) |
1450 .FromMaybe(false)) { | 1460 .FromMaybe(false)) { |
1451 return MaybeHandle<Object>(); | 1461 return MaybeHandle<Object>(); |
1452 } | 1462 } |
1453 | 1463 |
(...skipping 25 matching lines...) Expand all Loading... |
1479 if (stack.size() != 1) { | 1489 if (stack.size() != 1) { |
1480 isolate_->Throw(*isolate_->factory()->NewError( | 1490 isolate_->Throw(*isolate_->factory()->NewError( |
1481 MessageTemplate::kDataCloneDeserializationError)); | 1491 MessageTemplate::kDataCloneDeserializationError)); |
1482 return MaybeHandle<Object>(); | 1492 return MaybeHandle<Object>(); |
1483 } | 1493 } |
1484 return scope.CloseAndEscape(stack[0]); | 1494 return scope.CloseAndEscape(stack[0]); |
1485 } | 1495 } |
1486 | 1496 |
1487 } // namespace internal | 1497 } // namespace internal |
1488 } // namespace v8 | 1498 } // namespace v8 |
OLD | NEW |