v8/src/snapshot-common.cc

87 lines
3.0 KiB
C++
Raw Normal View History

// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The common functionality when building with or without snapshots.
#include "src/v8.h"
#include "src/api.h"
#include "src/base/platform/platform.h"
#include "src/serialize.h"
#include "src/snapshot.h"
namespace v8 {
namespace internal {
Refactoring of snapshots. This simplifies and improves the speed of deserializing code. The current startup time improvement for V8 is around 6%, but code deserialization is speeded up disproportionately, and we will soon have more code in the snapshot. * Removed support for deserializing into large object space. The regular pages are 1Mbyte now and that is plenty. This is a big simplification. * Instead of reserving space for the snapshot we actually allocate it now. This removes some special casing from the memory management and simplifies deserialization since we are just bumping a pointer rather than calling the normal allocation routines during deserialization. * Record in the snapshot how much we need to boot up and allocate it instead of just assuming that allocations in a new VM will always be linear. * In the snapshot we always address an object as a negative offset from the current allocation point. We used to sometimes address from the start of the deserialized data, but this is less useful now that we have good support for roots and repetitions in the deserialization data. * Code objects were previously deserialized (like other objects) by alternating raw data (deserialized with memcpy) and pointers (to external references, other objects, etc.). Now we deserialize code objects with a single memcpy, followed by a series of skips and pointers that partially overwrite the code we memcopied out of the snapshot. The skips are sometimes merged into the following instruction in the deserialization data to reduce dispatch time. * Integers in the snapshot were stored in a variable length format that gives a compact representation for small positive integers. This is still the case, but the new encoding can be decoded without branches or conditional instructions, which is faster on a modern CPU. Review URL: https://chromiumcodereview.appspot.com/10918067 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12505 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2012-09-14 11:16:56 +00:00
void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
deserializer->set_reservation(NEW_SPACE, new_space_used_);
deserializer->set_reservation(OLD_POINTER_SPACE, pointer_space_used_);
deserializer->set_reservation(OLD_DATA_SPACE, data_space_used_);
deserializer->set_reservation(CODE_SPACE, code_space_used_);
deserializer->set_reservation(MAP_SPACE, map_space_used_);
deserializer->set_reservation(CELL_SPACE, cell_space_used_);
deserializer->set_reservation(PROPERTY_CELL_SPACE,
property_cell_space_used_);
}
bool Snapshot::Initialize() {
if (size_ > 0) {
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) {
timer.Start();
}
Refactoring of snapshots. This simplifies and improves the speed of deserializing code. The current startup time improvement for V8 is around 6%, but code deserialization is speeded up disproportionately, and we will soon have more code in the snapshot. * Removed support for deserializing into large object space. The regular pages are 1Mbyte now and that is plenty. This is a big simplification. * Instead of reserving space for the snapshot we actually allocate it now. This removes some special casing from the memory management and simplifies deserialization since we are just bumping a pointer rather than calling the normal allocation routines during deserialization. * Record in the snapshot how much we need to boot up and allocate it instead of just assuming that allocations in a new VM will always be linear. * In the snapshot we always address an object as a negative offset from the current allocation point. We used to sometimes address from the start of the deserialized data, but this is less useful now that we have good support for roots and repetitions in the deserialization data. * Code objects were previously deserialized (like other objects) by alternating raw data (deserialized with memcpy) and pointers (to external references, other objects, etc.). Now we deserialize code objects with a single memcpy, followed by a series of skips and pointers that partially overwrite the code we memcopied out of the snapshot. The skips are sometimes merged into the following instruction in the deserialization data to reduce dispatch time. * Integers in the snapshot were stored in a variable length format that gives a compact representation for small positive integers. This is still the case, but the new encoding can be decoded without branches or conditional instructions, which is faster on a modern CPU. Review URL: https://chromiumcodereview.appspot.com/10918067 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12505 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2012-09-14 11:16:56 +00:00
SnapshotByteSource source(raw_data_, raw_size_);
Deserializer deserializer(&source);
ReserveSpaceForLinkedInSnapshot(&deserializer);
bool success = V8::Initialize(&deserializer);
if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
}
return success;
}
return false;
}
bool Snapshot::HaveASnapshotToStartFrom() {
return size_ != 0;
}
Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
if (context_size_ == 0) {
return Handle<Context>();
}
SnapshotByteSource source(context_raw_data_,
context_raw_size_);
Deserializer deserializer(&source);
Object* root;
Refactoring of snapshots. This simplifies and improves the speed of deserializing code. The current startup time improvement for V8 is around 6%, but code deserialization is speeded up disproportionately, and we will soon have more code in the snapshot. * Removed support for deserializing into large object space. The regular pages are 1Mbyte now and that is plenty. This is a big simplification. * Instead of reserving space for the snapshot we actually allocate it now. This removes some special casing from the memory management and simplifies deserialization since we are just bumping a pointer rather than calling the normal allocation routines during deserialization. * Record in the snapshot how much we need to boot up and allocate it instead of just assuming that allocations in a new VM will always be linear. * In the snapshot we always address an object as a negative offset from the current allocation point. We used to sometimes address from the start of the deserialized data, but this is less useful now that we have good support for roots and repetitions in the deserialization data. * Code objects were previously deserialized (like other objects) by alternating raw data (deserialized with memcpy) and pointers (to external references, other objects, etc.). Now we deserialize code objects with a single memcpy, followed by a series of skips and pointers that partially overwrite the code we memcopied out of the snapshot. The skips are sometimes merged into the following instruction in the deserialization data to reduce dispatch time. * Integers in the snapshot were stored in a variable length format that gives a compact representation for small positive integers. This is still the case, but the new encoding can be decoded without branches or conditional instructions, which is faster on a modern CPU. Review URL: https://chromiumcodereview.appspot.com/10918067 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12505 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
2012-09-14 11:16:56 +00:00
deserializer.set_reservation(NEW_SPACE, context_new_space_used_);
deserializer.set_reservation(OLD_POINTER_SPACE, context_pointer_space_used_);
deserializer.set_reservation(OLD_DATA_SPACE, context_data_space_used_);
deserializer.set_reservation(CODE_SPACE, context_code_space_used_);
deserializer.set_reservation(MAP_SPACE, context_map_space_used_);
deserializer.set_reservation(CELL_SPACE, context_cell_space_used_);
deserializer.set_reservation(PROPERTY_CELL_SPACE,
context_property_cell_space_used_);
deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsContext());
return Handle<Context>(Context::cast(root));
}
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
// Dummy implementations of Set*FromFile(..) APIs.
//
// These are meant for use with snapshot-external.cc. Should this file
// be compiled with those options we just supply these dummy implementations
// below. This happens when compiling the mksnapshot utility.
void SetNativesFromFile(StartupData* data) { CHECK(false); }
void SetSnapshotFromFile(StartupData* data) { CHECK(false); }
#endif // V8_USE_EXTERNAL_STARTUP_DATA
} } // namespace v8::internal