Commit 518ddc93 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Make block writes in the serializer more efficient.

And also fix a OOB read in SerializeExternalString.

R=vogelheim@chromium.org

Review URL: https://codereview.chromium.org/671633004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24858 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8189922e
...@@ -1586,29 +1586,34 @@ void Serializer::ObjectSerializer::SerializeExternalString() { ...@@ -1586,29 +1586,34 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
ExternalString* string = ExternalString::cast(object_); ExternalString* string = ExternalString::cast(object_);
int length = string->length(); int length = string->length();
Map* map; Map* map;
int size; int content_size;
const char* resource; int allocation_size;
const byte* resource;
// Find the map and size for the imaginary sequential string. // Find the map and size for the imaginary sequential string.
bool internalized = object_->IsInternalizedString(); bool internalized = object_->IsInternalizedString();
if (object_->IsExternalOneByteString()) { if (object_->IsExternalOneByteString()) {
map = internalized ? isolate->heap()->one_byte_internalized_string_map() map = internalized ? isolate->heap()->one_byte_internalized_string_map()
: isolate->heap()->one_byte_string_map(); : isolate->heap()->one_byte_string_map();
size = SeqOneByteString::SizeFor(length); allocation_size = SeqOneByteString::SizeFor(length);
resource = ExternalOneByteString::cast(string)->resource()->data(); content_size = length * kCharSize;
resource = reinterpret_cast<const byte*>(
ExternalOneByteString::cast(string)->resource()->data());
} else { } else {
map = internalized ? isolate->heap()->internalized_string_map() map = internalized ? isolate->heap()->internalized_string_map()
: isolate->heap()->string_map(); : isolate->heap()->string_map();
size = SeqTwoByteString::SizeFor(length); allocation_size = SeqTwoByteString::SizeFor(length);
resource = reinterpret_cast<const char*>( content_size = length * kShortSize;
resource = reinterpret_cast<const byte*>(
ExternalTwoByteString::cast(string)->resource()->data()); ExternalTwoByteString::cast(string)->resource()->data());
} }
AllocationSpace space = AllocationSpace space = (allocation_size > Page::kMaxRegularHeapObjectSize)
(size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE; ? LO_SPACE
SerializePrologue(space, size, map); : OLD_DATA_SPACE;
SerializePrologue(space, allocation_size, map);
// Output the rest of the imaginary string. // 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. // Output raw data header. Do not bother with common raw length cases here.
sink_->Put(kRawData, "RawDataForString"); sink_->Put(kRawData, "RawDataForString");
...@@ -1621,10 +1626,13 @@ void Serializer::ObjectSerializer::SerializeExternalString() { ...@@ -1621,10 +1626,13 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
} }
// Serialize string content. // Serialize string content.
int content_length = size - SeqString::kHeaderSize; sink_->PutRaw(const_cast<byte*>(resource), content_size, "StringContent");
for (int i = 0; i < content_length; i++) {
sink_->PutSection(resource[i], "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_->Put(kSkip, "SkipAfterString");
sink_->PutInt(bytes_to_output, "SkipDistance"); sink_->PutInt(bytes_to_output, "SkipDistance");
...@@ -1871,9 +1879,7 @@ int Serializer::ObjectSerializer::OutputRawData( ...@@ -1871,9 +1879,7 @@ int Serializer::ObjectSerializer::OutputRawData(
} }
const char* description = code_object_ ? "Code" : "Byte"; const char* description = code_object_ ? "Code" : "Byte";
for (int i = 0; i < bytes_to_output; i++) { sink_->PutRaw(object_start + base, bytes_to_output, description);
sink_->PutSection(object_start[base + i], description);
}
if (code_object_) delete[] object_start; if (code_object_) delete[] object_start;
} }
if (to_skip != 0 && return_skip == kIgnoringReturn) { if (to_skip != 0 && return_skip == kIgnoringReturn) {
......
...@@ -54,9 +54,7 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { ...@@ -54,9 +54,7 @@ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
void SnapshotByteSink::PutRaw(byte* data, int number_of_bytes, void SnapshotByteSink::PutRaw(byte* data, int number_of_bytes,
const char* description) { const char* description) {
for (int i = 0; i < number_of_bytes; ++i) { data_.AddAll(Vector<byte>(data, number_of_bytes));
Put(data[i], description);
}
} }
void SnapshotByteSink::PutBlob(byte* data, int number_of_bytes, void SnapshotByteSink::PutBlob(byte* data, int number_of_bytes,
......
...@@ -1054,7 +1054,7 @@ TEST(SerializeToplevelLargeExternalString) { ...@@ -1054,7 +1054,7 @@ TEST(SerializeToplevelLargeExternalString) {
// Create a huge external internalized string to use as variable name. // Create a huge external internalized string to use as variable name.
Vector<const uint8_t> string = Vector<const uint8_t> string =
ConstructSource(STATIC_CHAR_VECTOR(""), STATIC_CHAR_VECTOR("abcdef"), ConstructSource(STATIC_CHAR_VECTOR(""), STATIC_CHAR_VECTOR("abcdef"),
STATIC_CHAR_VECTOR(""), 1000000); STATIC_CHAR_VECTOR(""), 999999);
Handle<String> name = f->NewStringFromOneByte(string).ToHandleChecked(); Handle<String> name = f->NewStringFromOneByte(string).ToHandleChecked();
SerializerOneByteResource one_byte_resource( SerializerOneByteResource one_byte_resource(
reinterpret_cast<const char*>(string.start()), string.length()); reinterpret_cast<const char*>(string.start()), string.length());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment