Reviewers: vogelheim,
Description:
Make block writes in the serializer more efficient.
And also fix a OOB read in SerializeExternalString.
[email protected]
Please review this at https://codereview.chromium.org/671633004/
Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+25, -21 lines):
M src/serialize.cc
M src/snapshot-source-sink.cc
M test/cctest/test-serialize.cc
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index
c11f94a5ca0cceb9625611eb0ee45dac855eda50..b862c76f0631ed78fa4914ea4476182c10726ed4
100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -1586,29 +1586,34 @@ void
Serializer::ObjectSerializer::SerializeExternalString() {
ExternalString* string = ExternalString::cast(object_);
int length = string->length();
Map* map;
- int size;
- const char* resource;
+ int content_size;
+ int allocation_size;
+ const byte* resource;
// Find the map and size for the imaginary sequential string.
bool internalized = object_->IsInternalizedString();
if (object_->IsExternalOneByteString()) {
map = internalized ?
isolate->heap()->one_byte_internalized_string_map()
: isolate->heap()->one_byte_string_map();
- size = SeqOneByteString::SizeFor(length);
- resource = ExternalOneByteString::cast(string)->resource()->data();
+ allocation_size = SeqOneByteString::SizeFor(length);
+ content_size = length * kCharSize;
+ resource = reinterpret_cast<const byte*>(
+ ExternalOneByteString::cast(string)->resource()->data());
} else {
map = internalized ? isolate->heap()->internalized_string_map()
: isolate->heap()->string_map();
- size = SeqTwoByteString::SizeFor(length);
- resource = reinterpret_cast<const char*>(
+ allocation_size = SeqTwoByteString::SizeFor(length);
+ content_size = length * kShortSize;
+ resource = reinterpret_cast<const byte*>(
ExternalTwoByteString::cast(string)->resource()->data());
}
- AllocationSpace space =
- (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE;
- SerializePrologue(space, size, map);
+ AllocationSpace space = (allocation_size >
Page::kMaxRegularHeapObjectSize)
+ ? LO_SPACE
+ : OLD_DATA_SPACE;
+ SerializePrologue(space, allocation_size, map);
// Output the rest of the imaginary string.
- int bytes_to_output = size - HeapObject::kHeaderSize;
+ int bytes_to_output = allocation_size - HeapObject::kHeaderSize;
// Output raw data header. Do not bother with common raw length cases
here.
sink_->Put(kRawData, "RawDataForString");
@@ -1621,10 +1626,13 @@ void
Serializer::ObjectSerializer::SerializeExternalString() {
}
// Serialize string content.
- int content_length = size - SeqString::kHeaderSize;
- for (int i = 0; i < content_length; i++) {
- sink_->PutSection(resource[i], "StringContent");
- }
+ sink_->PutRaw(const_cast<byte*>(resource),
content_size, "StringContent");
+
+ // Since the allocation size is rounded up to object alignment, there
+ // maybe left-over bytes that need to be padded.
+ int padding_size = allocation_size - SeqString::kHeaderSize -
content_size;
+ DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
+ for (int i = 0; i < padding_size; i++)
sink_->PutSection(0, "StringPadding");
sink_->Put(kSkip, "SkipAfterString");
sink_->PutInt(bytes_to_output, "SkipDistance");
@@ -1871,9 +1879,7 @@ int Serializer::ObjectSerializer::OutputRawData(
}
const char* description = code_object_ ? "Code" : "Byte";
- for (int i = 0; i < bytes_to_output; i++) {
- sink_->PutSection(object_start[base + i], description);
- }
+ sink_->PutRaw(object_start + base, bytes_to_output, description);
if (code_object_) delete[] object_start;
}
if (to_skip != 0 && return_skip == kIgnoringReturn) {
Index: src/snapshot-source-sink.cc
diff --git a/src/snapshot-source-sink.cc b/src/snapshot-source-sink.cc
index
8e3b8a9d4436a88680fde5f8ee7ef4a964ead227..9935ff73963c7e157b40b33c3e4c2da6dbe5b380
100644
--- a/src/snapshot-source-sink.cc
+++ b/src/snapshot-source-sink.cc
@@ -54,9 +54,7 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const
char* description) {
void SnapshotByteSink::PutRaw(byte* data, int number_of_bytes,
const char* description) {
- for (int i = 0; i < number_of_bytes; ++i) {
- Put(data[i], description);
- }
+ data_.AddAll(Vector<byte>(data, number_of_bytes));
}
void SnapshotByteSink::PutBlob(byte* data, int number_of_bytes,
Index: test/cctest/test-serialize.cc
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index
62c1d8297770b5c8147b203a5c512beea7ed6582..83903e2134a9e53bf02183a7b1db8612c8d64f8c
100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -1054,7 +1054,7 @@ TEST(SerializeToplevelLargeExternalString) {
// Create a huge external internalized string to use as variable name.
Vector<const uint8_t> string =
ConstructSource(STATIC_CHAR_VECTOR(""), STATIC_CHAR_VECTOR("abcdef"),
- STATIC_CHAR_VECTOR(""), 1000000);
+ STATIC_CHAR_VECTOR(""), 999999);
Handle<String> name = f->NewStringFromOneByte(string).ToHandleChecked();
SerializerOneByteResource one_byte_resource(
reinterpret_cast<const char*>(string.start()), string.length());
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.