Commit 4f9fd83d authored by yangguo@chromium.org's avatar yangguo@chromium.org

Break deserializer reservations into chunks that fit onto a page.

R=mvstanton@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24639 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 461a2f40
......@@ -1177,7 +1177,12 @@ Handle<SharedFunctionInfo> Compiler::CompileScript(
compile_options == ScriptCompiler::kConsumeCodeCache &&
!isolate->debug()->is_loaded()) {
HistogramTimerScope timer(isolate->counters()->compile_deserialize());
return CodeSerializer::Deserialize(isolate, *cached_data, source);
Handle<SharedFunctionInfo> result;
if (CodeSerializer::Deserialize(isolate, *cached_data, source)
.ToHandle(&result)) {
return result;
}
// Deserializer failed. Fall through to compile.
} else {
maybe_result = compilation_cache->LookupScript(
source, script_name, line_offset, column_offset,
......
......@@ -28,6 +28,7 @@
#include "src/natives.h"
#include "src/runtime-profiler.h"
#include "src/scopeinfo.h"
#include "src/serialize.h"
#include "src/snapshot.h"
#include "src/utils.h"
#include "src/v8threads.h"
......@@ -919,33 +920,41 @@ static bool AbortIncrementalMarkingAndCollectGarbage(
}
void Heap::ReserveSpace(int* sizes, Address* locations_out) {
bool Heap::ReserveSpace(Reservation* reservations) {
bool gc_performed = true;
int counter = 0;
static const int kThreshold = 20;
while (gc_performed && counter++ < kThreshold) {
gc_performed = false;
for (int space = NEW_SPACE; space < Serializer::kNumberOfSpaces; space++) {
if (sizes[space] == 0) continue;
Reservation* reservation = &reservations[space];
DCHECK_LE(1, reservation->length());
if (reservation->at(0).size == 0) continue;
bool perform_gc = false;
if (space == LO_SPACE) {
perform_gc = !lo_space()->CanAllocateSize(sizes[space]);
DCHECK_EQ(1, reservation->length());
perform_gc = !lo_space()->CanAllocateSize(reservation->at(0).size);
} else {
AllocationResult allocation;
if (space == NEW_SPACE) {
allocation = new_space()->AllocateRaw(sizes[space]);
} else {
allocation = paged_space(space)->AllocateRaw(sizes[space]);
}
FreeListNode* node;
if (allocation.To(&node)) {
// Mark with a free list node, in case we have a GC before
// deserializing.
node->set_size(this, sizes[space]);
DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
locations_out[space] = node->address();
} else {
perform_gc = true;
for (auto& chunk : *reservation) {
AllocationResult allocation;
int size = chunk.size;
if (space == NEW_SPACE) {
allocation = new_space()->AllocateRaw(size);
} else {
allocation = paged_space(space)->AllocateRaw(size);
}
FreeListNode* node;
if (allocation.To(&node)) {
// Mark with a free list node, in case we have a GC before
// deserializing.
node->set_size(this, size);
DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
chunk.start = node->address();
chunk.end = node->address() + size;
} else {
perform_gc = true;
break;
}
}
}
if (perform_gc) {
......@@ -963,10 +972,7 @@ void Heap::ReserveSpace(int* sizes, Address* locations_out) {
}
}
if (gc_performed) {
// Failed to reserve the space after several attempts.
V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
}
return !gc_performed;
}
......
......@@ -1009,7 +1009,16 @@ class Heap {
// Support for partial snapshots. After calling this we have a linear
// space to write objects in each space.
void ReserveSpace(int* sizes, Address* addresses);
struct Chunk {
uint32_t size;
Address start;
Address end;
};
typedef List<Chunk> Reservation;
// Returns false if not able to reserve.
bool ReserveSpace(Reservation* reservations);
//
// Support for the API.
......
......@@ -80,7 +80,9 @@ class List {
Vector<T> ToVector() const { return Vector<T>(data_, length_); }
Vector<const T> ToConstVector() { return Vector<const T>(data_, length_); }
Vector<const T> ToConstVector() const {
return Vector<const T>(data_, length_);
}
// Adds a copy of the given 'element' to the end of the list,
// expanding the list if necessary.
......
......@@ -91,14 +91,25 @@ class SnapshotWriter {
i::byte* snapshot_bytes = snapshot_data.begin();
sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot");
for (size_t i = 0; i < arraysize(spaces); ++i)
sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces");
for (size_t i = 0; i < arraysize(spaces); ++i) {
i::Vector<const uint32_t> chunks =
serializer.FinalAllocationChunks(spaces[i]);
// For the start-up snapshot, none of the reservations has more than
// one chunk (reservation for each space fits onto a single page).
CHECK_EQ(1, chunks.length());
sink.PutInt(chunks[0], "spaces");
}
i::byte* context_bytes = context_snapshot_data.begin();
sink.PutBlob(context_bytes, context_snapshot_data.length(), "context");
for (size_t i = 0; i < arraysize(spaces); ++i)
sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]),
"spaces");
for (size_t i = 0; i < arraysize(spaces); ++i) {
i::Vector<const uint32_t> chunks =
context_serializer.FinalAllocationChunks(spaces[i]);
// For the context snapshot, none of the reservations has more than
// one chunk (reservation for each space fits onto a single page).
CHECK_EQ(1, chunks.length());
sink.PutInt(chunks[0], "spaces");
}
size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(),
startup_blob_file_);
......@@ -203,8 +214,12 @@ class SnapshotWriter {
void WriteSizeVar(const i::Serializer& ser, const char* prefix,
const char* name, int space) const {
fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n",
prefix, name, ser.CurrentAllocationAddress(space));
i::Vector<const uint32_t> chunks = ser.FinalAllocationChunks(space);
// For the start-up snapshot, none of the reservations has more than
// one chunk (total reservation fits into a single page).
CHECK_EQ(1, chunks.length());
fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n", prefix, name,
chunks[0]);
}
void WriteSnapshotData(const i::List<i::byte>* data) const {
......@@ -416,6 +431,9 @@ int main(int argc, char** argv) {
context_ser.Serialize(&raw_context);
ser.SerializeWeakReferences();
context_ser.FinalizeAllocation();
ser.FinalizeAllocation();
{
SnapshotWriter writer(argv[1]);
if (i::FLAG_raw_file && i::FLAG_raw_context_file)
......
This diff is collapsed.
This diff is collapsed.
......@@ -15,14 +15,14 @@ namespace v8 {
namespace internal {
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_);
deserializer->set_reservation(LO_SPACE, lo_space_used_);
deserializer->AddReservation(NEW_SPACE, new_space_used_);
deserializer->AddReservation(OLD_POINTER_SPACE, pointer_space_used_);
deserializer->AddReservation(OLD_DATA_SPACE, data_space_used_);
deserializer->AddReservation(CODE_SPACE, code_space_used_);
deserializer->AddReservation(MAP_SPACE, map_space_used_);
deserializer->AddReservation(CELL_SPACE, cell_space_used_);
deserializer->AddReservation(PROPERTY_CELL_SPACE, property_cell_space_used_);
deserializer->AddReservation(LO_SPACE, lo_space_used_);
}
......@@ -59,15 +59,15 @@ Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
context_raw_size_);
Deserializer deserializer(&source);
Object* root;
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.set_reservation(LO_SPACE, context_lo_space_used_);
deserializer.AddReservation(NEW_SPACE, context_new_space_used_);
deserializer.AddReservation(OLD_POINTER_SPACE, context_pointer_space_used_);
deserializer.AddReservation(OLD_DATA_SPACE, context_data_space_used_);
deserializer.AddReservation(CODE_SPACE, context_code_space_used_);
deserializer.AddReservation(MAP_SPACE, context_map_space_used_);
deserializer.AddReservation(CELL_SPACE, context_cell_space_used_);
deserializer.AddReservation(PROPERTY_CELL_SPACE,
context_property_cell_space_used_);
deserializer.AddReservation(LO_SPACE, context_lo_space_used_);
deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsContext());
return Handle<Context>(Context::cast(root));
......
......@@ -58,17 +58,16 @@ bool Snapshot::Initialize(Isolate* isolate) {
}
SnapshotByteSource source(snapshot_impl_->data, snapshot_impl_->size);
Deserializer deserializer(&source);
deserializer.set_reservation(NEW_SPACE, snapshot_impl_->new_space_used);
deserializer.set_reservation(OLD_POINTER_SPACE,
snapshot_impl_->pointer_space_used);
deserializer.set_reservation(OLD_DATA_SPACE,
snapshot_impl_->data_space_used);
deserializer.set_reservation(CODE_SPACE, snapshot_impl_->code_space_used);
deserializer.set_reservation(MAP_SPACE, snapshot_impl_->map_space_used);
deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used);
deserializer.set_reservation(PROPERTY_CELL_SPACE,
snapshot_impl_->property_cell_space_used);
deserializer.set_reservation(LO_SPACE, snapshot_impl_->lo_space_used);
deserializer.AddReservation(NEW_SPACE, snapshot_impl_->new_space_used);
deserializer.AddReservation(OLD_POINTER_SPACE,
snapshot_impl_->pointer_space_used);
deserializer.AddReservation(OLD_DATA_SPACE, snapshot_impl_->data_space_used);
deserializer.AddReservation(CODE_SPACE, snapshot_impl_->code_space_used);
deserializer.AddReservation(MAP_SPACE, snapshot_impl_->map_space_used);
deserializer.AddReservation(CELL_SPACE, snapshot_impl_->cell_space_used);
deserializer.AddReservation(PROPERTY_CELL_SPACE,
snapshot_impl_->property_cell_space_used);
deserializer.AddReservation(LO_SPACE, snapshot_impl_->lo_space_used);
bool success = isolate->Init(&deserializer);
if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
......@@ -85,22 +84,21 @@ Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
SnapshotByteSource source(snapshot_impl_->context_data,
snapshot_impl_->context_size);
Deserializer deserializer(&source);
deserializer.set_reservation(NEW_SPACE,
snapshot_impl_->context_new_space_used);
deserializer.set_reservation(OLD_POINTER_SPACE,
snapshot_impl_->context_pointer_space_used);
deserializer.set_reservation(OLD_DATA_SPACE,
snapshot_impl_->context_data_space_used);
deserializer.set_reservation(CODE_SPACE,
snapshot_impl_->context_code_space_used);
deserializer.set_reservation(MAP_SPACE,
snapshot_impl_->context_map_space_used);
deserializer.set_reservation(CELL_SPACE,
snapshot_impl_->context_cell_space_used);
deserializer.set_reservation(PROPERTY_CELL_SPACE,
snapshot_impl_->
context_property_cell_space_used);
deserializer.set_reservation(LO_SPACE, snapshot_impl_->context_lo_space_used);
deserializer.AddReservation(NEW_SPACE,
snapshot_impl_->context_new_space_used);
deserializer.AddReservation(OLD_POINTER_SPACE,
snapshot_impl_->context_pointer_space_used);
deserializer.AddReservation(OLD_DATA_SPACE,
snapshot_impl_->context_data_space_used);
deserializer.AddReservation(CODE_SPACE,
snapshot_impl_->context_code_space_used);
deserializer.AddReservation(MAP_SPACE,
snapshot_impl_->context_map_space_used);
deserializer.AddReservation(CELL_SPACE,
snapshot_impl_->context_cell_space_used);
deserializer.AddReservation(PROPERTY_CELL_SPACE,
snapshot_impl_->context_property_cell_space_used);
deserializer.AddReservation(LO_SPACE, snapshot_impl_->context_lo_space_used);
Object* root;
deserializer.DeserializePartial(isolate, &root);
CHECK(root->IsContext());
......
......@@ -58,6 +58,10 @@ class Vector {
T& last() { return start_[length_ - 1]; }
typedef T* iterator;
inline iterator begin() const { return &start_[0]; }
inline iterator end() const { return &start_[length_]; }
// Returns a clone of this vector with a new backing store.
Vector<T> Clone() const {
T* result = NewArray<T>(length_);
......
This diff is collapsed.
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