Commit 4a90166d authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Implement enough of the partial snapshots that we can deserialize

a single string.
Review URL: http://codereview.chromium.org/536077

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3619 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 82077880
......@@ -554,11 +554,10 @@ ExternalReferenceDecoder::~ExternalReferenceDecoder() {
bool Serializer::serialization_enabled_ = false;
bool Serializer::too_late_to_enable_now_ = false;
ExternalReferenceDecoder* Deserializer::external_reference_decoder_ = NULL;
Deserializer::Deserializer(SnapshotByteSource* source)
: source_(source),
external_reference_decoder_(NULL) {
Deserializer::Deserializer(SnapshotByteSource* source) : source_(source) {
}
......@@ -648,8 +647,26 @@ void Deserializer::Deserialize() {
external_reference_decoder_ = new ExternalReferenceDecoder();
Heap::IterateRoots(this, VISIT_ONLY_STRONG);
ASSERT(source_->AtEOF());
delete external_reference_decoder_;
external_reference_decoder_ = NULL;
}
void Deserializer::DeserializePartial(Object** root) {
// Don't GC while deserializing - just expand the heap.
AlwaysAllocateScope always_allocate;
// Don't use the free lists while deserializing.
LinearAllocationScope allocate_linearly;
if (external_reference_decoder_ == NULL) {
external_reference_decoder_ = new ExternalReferenceDecoder();
}
VisitPointer(root);
}
void Deserializer::TearDown() {
if (external_reference_decoder_ != NULL) {
delete external_reference_decoder_;
external_reference_decoder_ = NULL;
}
}
......@@ -862,6 +879,11 @@ void Deserializer::ReadChunk(Object** current,
*current++ = reinterpret_cast<Object*>(resource);
break;
}
case ROOT_SERIALIZATION: {
int root_id = source_->GetInt();
*current++ = Heap::roots_address()[root_id];
break;
}
default:
UNREACHABLE();
}
......@@ -915,7 +937,8 @@ Serializer::Serializer(SnapshotByteSink* sink)
: sink_(sink),
current_root_index_(0),
external_reference_encoder_(NULL),
partial_(false) {
partial_(false),
large_object_total_(0) {
for (int i = 0; i <= LAST_SPACE; i++) {
fullness_[i] = 0;
}
......@@ -1226,6 +1249,7 @@ int Serializer::Allocate(int space, int size, bool* new_page) {
// In large object space we merely number the objects instead of trying to
// determine some sort of address.
*new_page = true;
large_object_total_ += size;
return fullness_[LO_SPACE]++;
}
*new_page = false;
......
......@@ -239,10 +239,16 @@ class Deserializer: public SerDes {
// Deserialize the snapshot into an empty heap.
void Deserialize();
// Deserialize a single object and the objects reachable from it.
void DeserializePartial(Object** root);
#ifdef DEBUG
virtual void Synchronize(const char* tag);
#endif
static void TearDown();
private:
virtual void VisitPointers(Object** start, Object** end);
......@@ -267,7 +273,7 @@ class Deserializer: public SerDes {
List<Address> pages_[SerDes::kNumberOfSpaces];
SnapshotByteSource* source_;
ExternalReferenceDecoder* external_reference_decoder_;
static ExternalReferenceDecoder* external_reference_decoder_;
// This is the address of the next object that will be allocated in each
// space. It is used to calculate the addresses of back-references.
Address high_water_[LAST_SPACE + 1];
......@@ -302,7 +308,7 @@ class Serializer : public SerDes {
// You can call this after serialization to find out how much space was used
// in each space.
int CurrentAllocationAddress(int space) {
if (SpaceIsLarge(space)) space = LO_SPACE;
if (SpaceIsLarge(space)) return large_object_total_;
return fullness_[space];
}
......@@ -392,6 +398,7 @@ class Serializer : public SerDes {
static bool serialization_enabled_;
// Did we already make use of the fact that serialization was not enabled?
static bool too_late_to_enable_now_;
int large_object_total_;
friend class ObjectSerializer;
friend class Deserializer;
......
......@@ -146,6 +146,7 @@ void V8::TearDown() {
Heap::TearDown();
Logger::TearDown();
Deserializer::TearDown();
is_running_ = false;
has_been_disposed_ = true;
......
// Copyright 2007-2008 the V8 project authors. All rights reserved.
// Copyright 2007-2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
......@@ -277,6 +277,7 @@ class FileByteSink : public SnapshotByteSink {
public:
explicit FileByteSink(const char* snapshot_file) {
fp_ = 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);
......@@ -292,12 +293,44 @@ class FileByteSink : public SnapshotByteSink {
fputc(byte, fp_);
}
}
void WriteSpaceUsed(
int new_space_used,
int pointer_space_used,
int data_space_used,
int code_space_used,
int map_space_used,
int cell_space_used,
int large_space_used);
private:
FILE* fp_;
const char* file_name_;
};
void FileByteSink::WriteSpaceUsed(
int new_space_used,
int pointer_space_used,
int data_space_used,
int code_space_used,
int map_space_used,
int cell_space_used,
int large_space_used) {
int file_name_length = strlen(file_name_) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(name, "%s.size", file_name_);
FILE* fp = OS::FOpen(name.start(), "wa");
fprintf(fp, "new %d\n", new_space_used);
fprintf(fp, "pointer %d\n", pointer_space_used);
fprintf(fp, "data %d\n", data_space_used);
fprintf(fp, "code %d\n", code_space_used);
fprintf(fp, "map %d\n", map_space_used);
fprintf(fp, "cell %d\n", cell_space_used);
fprintf(fp, "large %d\n", large_space_used);
fclose(fp);
}
TEST(PartialSerialization) {
Serializer::Enable();
v8::V8::Initialize();
......@@ -312,6 +345,47 @@ TEST(PartialSerialization) {
i::Handle<i::String> internal_foo = v8::Utils::OpenHandle(*foo);
Object* raw_foo = *internal_foo;
ser.SerializePartial(&raw_foo);
file.WriteSpaceUsed(ser.CurrentAllocationAddress(NEW_SPACE),
ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
ser.CurrentAllocationAddress(OLD_DATA_SPACE),
ser.CurrentAllocationAddress(CODE_SPACE),
ser.CurrentAllocationAddress(MAP_SPACE),
ser.CurrentAllocationAddress(CELL_SPACE),
ser.CurrentAllocationAddress(LO_SPACE));
}
DEPENDENT_TEST(PartialDeserialization, PartialSerialization) {
v8::V8::Initialize();
const char* file_name = FLAG_testing_serialization_file;
int file_name_length = strlen(file_name) + 10;
Vector<char> name = Vector<char>::New(file_name_length + 1);
OS::SNPrintF(name, "%s.size", file_name);
FILE* fp = OS::FOpen(name.start(), "ra");
int new_size, pointer_size, data_size, code_size, map_size, cell_size;
int large_size;
CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
CHECK_EQ(1, fscanf(fp, "large %d\n", &large_size));
fclose(fp);
Heap::ReserveSpace(new_size,
pointer_size,
data_size,
code_size,
map_size,
cell_size,
large_size);
int snapshot_size = 0;
byte* snapshot = ReadBytes(file_name, &snapshot_size);
SnapshotByteSource source(snapshot, snapshot_size);
Deserializer deserializer(&source);
Object* root;
deserializer.DeserializePartial(&root);
CHECK(root->IsString());
}
......
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