Commit aaa104c8 authored by yangguo@chromium.org's avatar yangguo@chromium.org

De-virtualize snapshot sink.

R=vogelheim@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24836 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4568813a
......@@ -463,7 +463,7 @@ DEFINE_BOOL(trace_stub_failures, false,
"trace deoptimization of generated code stubs")
DEFINE_BOOL(serialize_toplevel, false, "enable caching of toplevel scripts")
DEFINE_INT(serializer_trace_level, 0, "trace code serializer (0 .. 2)")
DEFINE_BOOL(trace_code_serializer, false, "print code serializer trace")
// compiler.cc
DEFINE_INT(min_preparse_length, 1024,
......
......@@ -78,11 +78,9 @@ class SnapshotWriter {
const i::Serializer& serializer,
const i::List<i::byte>& context_snapshot_data,
const i::Serializer& context_serializer) const {
if (!startup_blob_file_)
return;
if (!startup_blob_file_) return;
i::List<i::byte> startup_blob;
i::ListSnapshotSink sink(&startup_blob);
i::SnapshotByteSink sink;
int spaces[] = {i::NEW_SPACE, i::OLD_POINTER_SPACE,
i::OLD_DATA_SPACE, i::CODE_SPACE,
......@@ -111,9 +109,10 @@ class SnapshotWriter {
sink.PutInt(chunks[0], "spaces");
}
const i::List<i::byte>& startup_blob = sink.data();
size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(),
startup_blob_file_);
if (written != (size_t)startup_blob.length()) {
if (written != static_cast<size_t>(startup_blob.length())) {
i::PrintF("Writing snapshot file failed.. Aborting.\n");
exit(1);
}
......@@ -420,14 +419,12 @@ int main(int argc, char** argv) {
// This results in a somewhat smaller snapshot, probably because it gets
// rid of some things that are cached between garbage collections.
i::List<i::byte> snapshot_data;
i::ListSnapshotSink snapshot_sink(&snapshot_data);
i::SnapshotByteSink snapshot_sink;
i::StartupSerializer ser(internal_isolate, &snapshot_sink);
ser.SerializeStrongReferences();
i::List<i::byte> context_data;
i::ListSnapshotSink contex_sink(&context_data);
i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
i::SnapshotByteSink context_sink;
i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
context_ser.Serialize(&raw_context);
ser.SerializeWeakReferences();
......@@ -444,7 +441,8 @@ int main(int argc, char** argv) {
BZip2Compressor bzip2;
writer.SetCompressor(&bzip2);
#endif
writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
writer.WriteSnapshot(snapshot_sink.data(), ser, context_sink.data(),
context_ser);
}
}
......
......@@ -1952,7 +1952,7 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
Handle<String> source) {
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start();
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF("[Serializing from");
Object* script = info->script();
if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
......@@ -1960,13 +1960,8 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
}
// Serialize code object.
List<byte> payload;
ListSnapshotSink list_sink(&payload);
DebugSnapshotSink debug_sink(&list_sink);
SnapshotByteSink* sink = FLAG_serializer_trace_level > 1
? static_cast<SnapshotByteSink*>(&debug_sink)
: static_cast<SnapshotByteSink*>(&list_sink);
CodeSerializer cs(isolate, sink, *source, info->code());
SnapshotByteSink sink(info->code()->CodeSize() * 2);
CodeSerializer cs(isolate, &sink, *source, info->code());
DisallowHeapAllocation no_gc;
Object** location = Handle<Object>::cast(info).location();
cs.VisitPointer(location);
......@@ -1980,7 +1975,7 @@ ScriptData* CodeSerializer::Serialize(Isolate* isolate,
}
}
SerializedCodeData data(&payload, &cs);
SerializedCodeData data(sink.data(), &cs);
ScriptData* script_data = data.GetScriptData();
if (FLAG_profile_deserialization) {
......@@ -1997,7 +1992,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
WhereToPoint where_to_point, int skip) {
int root_index = root_index_map_.Lookup(obj);
if (root_index != RootIndexMap::kInvalidRootIndex) {
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" Encoding root: %d\n", root_index);
}
PutRoot(root_index, obj, how_to_code, where_to_point, skip);
......@@ -2006,7 +2001,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
BackReference back_reference = back_reference_map_.Lookup(obj);
if (back_reference.is_valid()) {
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" Encoding back reference to: ");
obj->ShortPrint();
PrintF("\n");
......@@ -2074,7 +2069,7 @@ void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
void CodeSerializer::SerializeGeneric(HeapObject* heap_object,
HowToCode how_to_code,
WhereToPoint where_to_point) {
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" Encoding heap object: ");
heap_object->ShortPrint();
PrintF("\n");
......@@ -2097,7 +2092,7 @@ void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code,
DCHECK_LT(builtin_index, Builtins::builtin_count);
DCHECK_LE(0, builtin_index);
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" Encoding builtin: %s\n",
isolate()->builtins()->name(builtin_index));
}
......@@ -2117,7 +2112,7 @@ void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code,
int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" Encoding code stub %s as %d\n",
CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false),
index);
......@@ -2133,7 +2128,7 @@ void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
// The IC may be implemented as a stub.
uint32_t stub_key = ic->stub_key();
if (stub_key != CodeStub::NoCacheKey()) {
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind()));
}
SerializeCodeStub(stub_key, how_to_code, where_to_point);
......@@ -2147,7 +2142,7 @@ void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
Builtins::Name name = static_cast<Builtins::Name>(builtin_index);
Code* builtin = isolate()->builtins()->builtin(name);
if (builtin == ic) {
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind()));
}
DCHECK(ic->kind() == Code::KEYED_LOAD_IC ||
......@@ -2158,7 +2153,7 @@ void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
}
// The IC may also just be a piece of code kept in the non_monomorphic_cache.
// In that case, just serialize as a normal code object.
if (FLAG_serializer_trace_level > 0) {
if (FLAG_trace_code_serializer) {
PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind()));
}
DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC);
......@@ -2180,7 +2175,7 @@ int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
WhereToPoint where_to_point) {
if (FLAG_serializer_trace_level > 0) PrintF(" Encoding source object\n");
if (FLAG_trace_code_serializer) PrintF(" Encoding source object\n");
DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
......@@ -2248,7 +2243,8 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
}
SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
SerializedCodeData::SerializedCodeData(const List<byte>& payload,
CodeSerializer* cs)
: script_data_(NULL), owns_script_data_(true) {
DisallowHeapAllocation no_gc;
List<uint32_t>* stub_keys = cs->stub_keys();
......@@ -2273,7 +2269,7 @@ SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
int num_stub_keys = stub_keys->length();
int stub_keys_size = stub_keys->length() * kInt32Size;
int data_length =
kHeaderSize + reservation_size + stub_keys_size + payload->length();
kHeaderSize + reservation_size + stub_keys_size + payload.length();
// Allocate backing store and create result data.
byte* data = NewArray<byte>(data_length);
......@@ -2286,7 +2282,7 @@ SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings());
SetHeaderValue(kReservationsOffset, reservations.length());
SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
SetHeaderValue(kPayloadLengthOffset, payload->length());
SetHeaderValue(kPayloadLengthOffset, payload.length());
// Copy reservation chunk sizes.
CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
......@@ -2298,7 +2294,7 @@ SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
// Copy serialized data.
CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size,
payload->begin(), static_cast<size_t>(payload->length()));
payload.begin(), static_cast<size_t>(payload.length()));
}
......
......@@ -739,7 +739,7 @@ class SerializedCodeData {
}
// Used when producing.
SerializedCodeData(List<byte>* payload, CodeSerializer* cs);
SerializedCodeData(const List<byte>& payload, CodeSerializer* cs);
~SerializedCodeData() {
if (owns_script_data_) delete script_data_;
......
......@@ -89,11 +89,5 @@ bool SnapshotByteSource::GetBlob(const byte** data, int* number_of_bytes) {
}
}
void DebugSnapshotSink::Put(byte b, const char* description) {
PrintF("%24s: %x\n", description, b);
sink_->Put(b, description);
}
} // namespace v8::internal
} // namespace v8
......@@ -70,53 +70,27 @@ class SnapshotByteSource FINAL {
*/
class SnapshotByteSink {
public:
virtual ~SnapshotByteSink() { }
virtual void Put(byte b, const char* description) = 0;
virtual void PutSection(int b, const char* description) {
SnapshotByteSink() {}
explicit SnapshotByteSink(int initial_size) : data_(initial_size) {}
~SnapshotByteSink() {}
void Put(byte b, const char* description) { data_.Add(b); }
void PutSection(int b, const char* description) {
DCHECK_LE(b, kMaxUInt8);
Put(static_cast<byte>(b), description);
}
void PutInt(uintptr_t integer, const char* description);
void PutRaw(byte* data, int number_of_bytes, const char* description);
void PutBlob(byte* data, int number_of_bytes, const char* description);
virtual int Position() = 0;
};
int Position() { return data_.length(); }
class DummySnapshotSink : public SnapshotByteSink {
public:
DummySnapshotSink() : length_(0) {}
virtual ~DummySnapshotSink() {}
virtual void Put(byte b, const char* description) { length_++; }
virtual int Position() { return length_; }
private:
int length_;
};
// Wrap a SnapshotByteSink into a DebugSnapshotSink to get debugging output.
class DebugSnapshotSink : public SnapshotByteSink {
public:
explicit DebugSnapshotSink(SnapshotByteSink* chained) : sink_(chained) {}
virtual void Put(byte b, const char* description) OVERRIDE;
virtual int Position() OVERRIDE { return sink_->Position(); }
private:
SnapshotByteSink* sink_;
};
class ListSnapshotSink : public i::SnapshotByteSink {
public:
explicit ListSnapshotSink(i::List<byte>* data) : data_(data) {}
virtual void Put(byte b, const char* description) OVERRIDE {
data_->Add(b);
}
virtual int Position() OVERRIDE { return data_->length(); }
const List<byte>& data() const { return data_; }
private:
i::List<byte>* data_;
List<byte> data_;
};
} // namespace v8::internal
......
......@@ -114,41 +114,25 @@ TEST(ExternalReferenceDecoder) {
}
class FileByteSink : public SnapshotByteSink {
public:
explicit FileByteSink(const char* snapshot_file) {
fp_ = v8::base::OS::FOpen(snapshot_file, "wb");
file_name_ = snapshot_file;
if (fp_ == NULL) {
PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
exit(1);
}
}
virtual ~FileByteSink() {
if (fp_ != NULL) {
fclose(fp_);
}
void WritePayload(const List<byte>& payload, const char* file_name) {
FILE* file = v8::base::OS::FOpen(file_name, "wb");
if (file == NULL) {
PrintF("Unable to write to snapshot file \"%s\"\n", file_name);
exit(1);
}
virtual void Put(byte b, const char* description) {
if (fp_ != NULL) {
fputc(b, fp_);
}
}
virtual int Position() {
return ftell(fp_);
size_t written = fwrite(payload.begin(), 1, payload.length(), file);
if (written != static_cast<size_t>(payload.length())) {
i::PrintF("Writing snapshot file failed.. Aborting.\n");
exit(1);
}
void WriteSpaceUsed(Serializer* serializer);
private:
FILE* fp_;
const char* file_name_;
};
fclose(file);
}
void FileByteSink::WriteSpaceUsed(Serializer* ser) {
int file_name_length = StrLength(file_name_) + 10;
void WriteSpaceUsed(Serializer* ser, const char* file_name) {
int file_name_length = StrLength(file_name) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
SNPrintF(name, "%s.size", file_name_);
SNPrintF(name, "%s.size", file_name);
FILE* fp = v8::base::OS::FOpen(name.start(), "w");
name.Dispose();
......@@ -181,12 +165,13 @@ void FileByteSink::WriteSpaceUsed(Serializer* ser) {
static bool WriteToFile(Isolate* isolate, const char* snapshot_file) {
FileByteSink file(snapshot_file);
StartupSerializer ser(isolate, &file);
SnapshotByteSink sink;
StartupSerializer ser(isolate, &sink);
ser.Serialize();
ser.FinalizeAllocation();
file.WriteSpaceUsed(&ser);
WritePayload(sink.data(), snapshot_file);
WriteSpaceUsed(&ser, snapshot_file);
return true;
}
......@@ -440,21 +425,26 @@ UNINITIALIZED_TEST(PartialSerialization) {
}
env.Reset();
FileByteSink startup_sink(startup_name.start());
SnapshotByteSink startup_sink;
StartupSerializer startup_serializer(isolate, &startup_sink);
startup_serializer.SerializeStrongReferences();
FileByteSink partial_sink(FLAG_testing_serialization_file);
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
p_ser.Serialize(&raw_foo);
SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer,
&partial_sink);
partial_serializer.Serialize(&raw_foo);
startup_serializer.SerializeWeakReferences();
p_ser.FinalizeAllocation();
partial_serializer.FinalizeAllocation();
startup_serializer.FinalizeAllocation();
partial_sink.WriteSpaceUsed(&p_ser);
WritePayload(partial_sink.data(), FLAG_testing_serialization_file);
WritePayload(startup_sink.data(), startup_name.start());
WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file);
WriteSpaceUsed(&startup_serializer, startup_name.start());
startup_sink.WriteSpaceUsed(&startup_serializer);
startup_name.Dispose();
}
v8_isolate->Exit();
......@@ -552,21 +542,25 @@ UNINITIALIZED_TEST(ContextSerialization) {
env.Reset();
FileByteSink startup_sink(startup_name.start());
SnapshotByteSink startup_sink;
StartupSerializer startup_serializer(isolate, &startup_sink);
startup_serializer.SerializeStrongReferences();
FileByteSink partial_sink(FLAG_testing_serialization_file);
PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
p_ser.Serialize(&raw_context);
SnapshotByteSink partial_sink;
PartialSerializer partial_serializer(isolate, &startup_serializer,
&partial_sink);
partial_serializer.Serialize(&raw_context);
startup_serializer.SerializeWeakReferences();
p_ser.FinalizeAllocation();
partial_serializer.FinalizeAllocation();
startup_serializer.FinalizeAllocation();
partial_sink.WriteSpaceUsed(&p_ser);
WritePayload(partial_sink.data(), FLAG_testing_serialization_file);
WritePayload(startup_sink.data(), startup_name.start());
WriteSpaceUsed(&partial_serializer, FLAG_testing_serialization_file);
WriteSpaceUsed(&startup_serializer, startup_name.start());
startup_sink.WriteSpaceUsed(&startup_serializer);
startup_name.Dispose();
}
v8_isolate->Dispose();
......
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