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
This commit is contained in:
parent
4568813a34
commit
aaa104c8da
@ -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_; }
|
||||
const List<byte>& data() const { return data_; }
|
||||
|
||||
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(); }
|
||||
|
||||
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);
|
||||
}
|
||||
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 ~FileByteSink() {
|
||||
if (fp_ != NULL) {
|
||||
fclose(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);
|
||||
}
|
||||
virtual void Put(byte b, const char* description) {
|
||||
if (fp_ != NULL) {
|
||||
fputc(b, fp_);
|
||||
}
|
||||
}
|
||||
virtual int Position() {
|
||||
return ftell(fp_);
|
||||
}
|
||||
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();
|
||||
|
Loading…
Reference in New Issue
Block a user