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

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

Issue 2665653004: ValueSerializer: Share string encoding code with String and RegExp objects. (Closed)
Patch Set: Created 3 years, 10 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') | test/unittests/value-serializer-unittest.cc » ('j') | 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/flags.h" 12 #include "src/flags.h"
13 #include "src/handles-inl.h" 13 #include "src/handles-inl.h"
14 #include "src/isolate.h" 14 #include "src/isolate.h"
15 #include "src/objects-inl.h" 15 #include "src/objects-inl.h"
16 #include "src/objects.h" 16 #include "src/objects.h"
17 #include "src/snapshot/code-serializer.h" 17 #include "src/snapshot/code-serializer.h"
18 #include "src/transitions.h" 18 #include "src/transitions.h"
19 #include "src/wasm/wasm-module.h" 19 #include "src/wasm/wasm-module.h"
20 #include "src/wasm/wasm-objects.h" 20 #include "src/wasm/wasm-objects.h"
21 #include "src/wasm/wasm-result.h" 21 #include "src/wasm/wasm-result.h"
22 22
23 namespace v8 { 23 namespace v8 {
24 namespace internal { 24 namespace internal {
25 25
26 // Version 9: (imported from Blink) 26 // Version 9: (imported from Blink)
27 // Version 10: one-byte (Latin-1) strings 27 // Version 10: one-byte (Latin-1) strings
28 // Version 11: properly separate undefined from the hole in arrays 28 // Version 11: properly separate undefined from the hole in arrays
29 static const uint32_t kLatestVersion = 11; 29 // Version 12: regexp and string objects share normal string encoding
30 static const uint32_t kLatestVersion = 12;
30 31
31 static const int kPretenureThreshold = 100 * KB; 32 static const int kPretenureThreshold = 100 * KB;
32 33
33 template <typename T> 34 template <typename T>
34 static size_t BytesNeededForVarint(T value) { 35 static size_t BytesNeededForVarint(T value) {
35 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, 36 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
36 "Only unsigned integer types can be written as varints."); 37 "Only unsigned integer types can be written as varints.");
37 size_t result = 0; 38 size_t result = 0;
38 do { 39 do {
39 result++; 40 result++;
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) { 641 Maybe<bool> ValueSerializer::WriteJSValue(Handle<JSValue> value) {
641 Object* inner_value = value->value(); 642 Object* inner_value = value->value();
642 if (inner_value->IsTrue(isolate_)) { 643 if (inner_value->IsTrue(isolate_)) {
643 WriteTag(SerializationTag::kTrueObject); 644 WriteTag(SerializationTag::kTrueObject);
644 } else if (inner_value->IsFalse(isolate_)) { 645 } else if (inner_value->IsFalse(isolate_)) {
645 WriteTag(SerializationTag::kFalseObject); 646 WriteTag(SerializationTag::kFalseObject);
646 } else if (inner_value->IsNumber()) { 647 } else if (inner_value->IsNumber()) {
647 WriteTag(SerializationTag::kNumberObject); 648 WriteTag(SerializationTag::kNumberObject);
648 WriteDouble(inner_value->Number()); 649 WriteDouble(inner_value->Number());
649 } else if (inner_value->IsString()) { 650 } else if (inner_value->IsString()) {
650 // TODO(jbroman): Replace UTF-8 encoding with the same options available for
651 // ordinary strings.
652 WriteTag(SerializationTag::kStringObject); 651 WriteTag(SerializationTag::kStringObject);
653 v8::Local<v8::String> api_string = 652 WriteString(handle(String::cast(inner_value), isolate_));
654 Utils::ToLocal(handle(String::cast(inner_value), isolate_));
655 uint32_t utf8_length = api_string->Utf8Length();
656 WriteVarint(utf8_length);
657 uint8_t* dest;
658 if (ReserveRawBytes(utf8_length).To(&dest)) {
659 api_string->WriteUtf8(reinterpret_cast<char*>(dest), utf8_length, nullptr,
660 v8::String::NO_NULL_TERMINATION);
661 }
662 } else { 653 } else {
663 DCHECK(inner_value->IsSymbol()); 654 DCHECK(inner_value->IsSymbol());
664 ThrowDataCloneError(MessageTemplate::kDataCloneError, value); 655 ThrowDataCloneError(MessageTemplate::kDataCloneError, value);
665 return Nothing<bool>(); 656 return Nothing<bool>();
666 } 657 }
667 return ThrowIfOutOfMemory(); 658 return ThrowIfOutOfMemory();
668 } 659 }
669 660
670 void ValueSerializer::WriteJSRegExp(JSRegExp* regexp) { 661 void ValueSerializer::WriteJSRegExp(JSRegExp* regexp) {
671 WriteTag(SerializationTag::kRegExp); 662 WriteTag(SerializationTag::kRegExp);
672 v8::Local<v8::String> api_string = 663 WriteString(handle(regexp->Pattern(), isolate_));
673 Utils::ToLocal(handle(regexp->Pattern(), isolate_));
674 uint32_t utf8_length = api_string->Utf8Length();
675 WriteVarint(utf8_length);
676 uint8_t* dest;
677 if (ReserveRawBytes(utf8_length).To(&dest)) {
678 api_string->WriteUtf8(reinterpret_cast<char*>(dest), utf8_length, nullptr,
679 v8::String::NO_NULL_TERMINATION);
680 }
681 WriteVarint(static_cast<uint32_t>(regexp->GetFlags())); 664 WriteVarint(static_cast<uint32_t>(regexp->GetFlags()));
682 } 665 }
683 666
684 Maybe<bool> ValueSerializer::WriteJSMap(Handle<JSMap> map) { 667 Maybe<bool> ValueSerializer::WriteJSMap(Handle<JSMap> map) {
685 // First copy the key-value pairs, since getters could mutate them. 668 // First copy the key-value pairs, since getters could mutate them.
686 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); 669 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
687 int length = table->NumberOfElements() * 2; 670 int length = table->NumberOfElements() * 2;
688 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length); 671 Handle<FixedArray> entries = isolate_->factory()->NewFixedArray(length);
689 { 672 {
690 DisallowHeapAllocation no_gc; 673 DisallowHeapAllocation no_gc;
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 case SerializationTag::kWasmModule: 1134 case SerializationTag::kWasmModule:
1152 return ReadWasmModule(); 1135 return ReadWasmModule();
1153 default: 1136 default:
1154 // TODO(jbroman): Introduce an explicit tag for host objects to avoid 1137 // TODO(jbroman): Introduce an explicit tag for host objects to avoid
1155 // having to treat every unknown tag as a potential host object. 1138 // having to treat every unknown tag as a potential host object.
1156 position_--; 1139 position_--;
1157 return ReadHostObject(); 1140 return ReadHostObject();
1158 } 1141 }
1159 } 1142 }
1160 1143
1144 MaybeHandle<String> ValueDeserializer::ReadString() {
1145 if (version_ < 12) return ReadUtf8String();
1146 Handle<Object> object;
1147 if (!ReadObject().ToHandle(&object) || !object->IsString()) {
1148 return MaybeHandle<String>();
1149 }
1150 return Handle<String>::cast(object);
1151 }
1152
1161 MaybeHandle<String> ValueDeserializer::ReadUtf8String() { 1153 MaybeHandle<String> ValueDeserializer::ReadUtf8String() {
1162 uint32_t utf8_length; 1154 uint32_t utf8_length;
1163 Vector<const uint8_t> utf8_bytes; 1155 Vector<const uint8_t> utf8_bytes;
1164 if (!ReadVarint<uint32_t>().To(&utf8_length) || 1156 if (!ReadVarint<uint32_t>().To(&utf8_length) ||
1165 utf8_length > 1157 utf8_length >
1166 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) || 1158 static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) ||
1167 !ReadRawBytes(utf8_length).To(&utf8_bytes)) { 1159 !ReadRawBytes(utf8_length).To(&utf8_bytes)) {
1168 return MaybeHandle<String>(); 1160 return MaybeHandle<String>();
1169 } 1161 }
1170 return isolate_->factory()->NewStringFromUtf8( 1162 return isolate_->factory()->NewStringFromUtf8(
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>(); 1381 if (!ReadDouble().To(&number)) return MaybeHandle<JSValue>();
1390 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( 1382 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
1391 isolate_->number_function(), pretenure_)); 1383 isolate_->number_function(), pretenure_));
1392 Handle<Object> number_object = 1384 Handle<Object> number_object =
1393 isolate_->factory()->NewNumber(number, pretenure_); 1385 isolate_->factory()->NewNumber(number, pretenure_);
1394 value->set_value(*number_object); 1386 value->set_value(*number_object);
1395 break; 1387 break;
1396 } 1388 }
1397 case SerializationTag::kStringObject: { 1389 case SerializationTag::kStringObject: {
1398 Handle<String> string; 1390 Handle<String> string;
1399 if (!ReadUtf8String().ToHandle(&string)) return MaybeHandle<JSValue>(); 1391 if (!ReadString().ToHandle(&string)) return MaybeHandle<JSValue>();
1400 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject( 1392 value = Handle<JSValue>::cast(isolate_->factory()->NewJSObject(
1401 isolate_->string_function(), pretenure_)); 1393 isolate_->string_function(), pretenure_));
1402 value->set_value(*string); 1394 value->set_value(*string);
1403 break; 1395 break;
1404 } 1396 }
1405 default: 1397 default:
1406 UNREACHABLE(); 1398 UNREACHABLE();
1407 return MaybeHandle<JSValue>(); 1399 return MaybeHandle<JSValue>();
1408 } 1400 }
1409 AddObjectWithID(id, value); 1401 AddObjectWithID(id, value);
1410 return value; 1402 return value;
1411 } 1403 }
1412 1404
1413 MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() { 1405 MaybeHandle<JSRegExp> ValueDeserializer::ReadJSRegExp() {
1414 uint32_t id = next_id_++; 1406 uint32_t id = next_id_++;
1415 Handle<String> pattern; 1407 Handle<String> pattern;
1416 uint32_t raw_flags; 1408 uint32_t raw_flags;
1417 Handle<JSRegExp> regexp; 1409 Handle<JSRegExp> regexp;
1418 if (!ReadUtf8String().ToHandle(&pattern) || 1410 if (!ReadString().ToHandle(&pattern) ||
1419 !ReadVarint<uint32_t>().To(&raw_flags) || 1411 !ReadVarint<uint32_t>().To(&raw_flags) ||
1420 !JSRegExp::New(pattern, static_cast<JSRegExp::Flags>(raw_flags)) 1412 !JSRegExp::New(pattern, static_cast<JSRegExp::Flags>(raw_flags))
1421 .ToHandle(&regexp)) { 1413 .ToHandle(&regexp)) {
1422 return MaybeHandle<JSRegExp>(); 1414 return MaybeHandle<JSRegExp>();
1423 } 1415 }
1424 AddObjectWithID(id, regexp); 1416 AddObjectWithID(id, regexp);
1425 return regexp; 1417 return regexp;
1426 } 1418 }
1427 1419
1428 MaybeHandle<JSMap> ValueDeserializer::ReadJSMap() { 1420 MaybeHandle<JSMap> ValueDeserializer::ReadJSMap() {
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 if (stack.size() != 1) { 1926 if (stack.size() != 1) {
1935 isolate_->Throw(*isolate_->factory()->NewError( 1927 isolate_->Throw(*isolate_->factory()->NewError(
1936 MessageTemplate::kDataCloneDeserializationError)); 1928 MessageTemplate::kDataCloneDeserializationError));
1937 return MaybeHandle<Object>(); 1929 return MaybeHandle<Object>();
1938 } 1930 }
1939 return scope.CloseAndEscape(stack[0]); 1931 return scope.CloseAndEscape(stack[0]);
1940 } 1932 }
1941 1933
1942 } // namespace internal 1934 } // namespace internal
1943 } // namespace v8 1935 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698