Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: src/value-serializer.cc

Issue 2336973004: ValueDeserializer: Pretenure objects while deserializing large objects. (Closed)
Patch Set: remove the anonymous namespace; it is superfluous here Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698