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