Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Unified Diff: runtime/vm/snapshot.cc

Issue 1123813002: Move symbol table from per isolate snapshot to vm isolate snapshot, this reduces the per isolate in… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/snapshot.cc
===================================================================
--- runtime/vm/snapshot.cc (revision 45789)
+++ runtime/vm/snapshot.cc (working copy)
@@ -7,6 +7,7 @@
#include "platform/assert.h"
#include "vm/bootstrap.h"
#include "vm/class_finalizer.h"
+#include "vm/dart.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/heap.h"
@@ -21,6 +22,7 @@
namespace dart {
+static const int kNumVmIsolateSnapshotReferences = 32 * KB;
static const int kNumInitialReferencesInFullSnapshot = 160 * KB;
static const int kNumInitialReferences = 64;
@@ -161,11 +163,13 @@
}
-SnapshotReader::SnapshotReader(const uint8_t* buffer,
- intptr_t size,
- Snapshot::Kind kind,
- Isolate* isolate,
- Zone* zone)
+SnapshotReader::SnapshotReader(
+ const uint8_t* buffer,
+ intptr_t size,
+ Snapshot::Kind kind,
+ ZoneGrowableArray<BackRefNode>* backward_refs,
+ Isolate* isolate,
+ Zone* zone)
: BaseReader(buffer, size),
kind_(kind),
isolate_(isolate),
@@ -185,9 +189,9 @@
stream_(TokenStream::Handle(isolate)),
data_(ExternalTypedData::Handle(isolate)),
error_(UnhandledException::Handle(isolate)),
- backward_references_((kind == Snapshot::kFull) ?
- kNumInitialReferencesInFullSnapshot :
- kNumInitialReferences) {
+ max_vm_isolate_object_id_(
+ Object::vm_isolate_snapshot_object_table().Length()),
+ backward_references_(backward_refs) {
}
@@ -196,10 +200,10 @@
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl());
- for (intptr_t i = 0; i < backward_references_.length(); i++) {
- if (!backward_references_[i].is_deserialized()) {
+ for (intptr_t i = 0; i < backward_references_->length(); i++) {
+ if (!(*backward_references_)[i].is_deserialized()) {
ReadObjectImpl();
- backward_references_[i].set_state(kIsDeserialized);
+ (*backward_references_)[i].set_state(kIsDeserialized);
}
}
return obj.raw();
@@ -292,7 +296,8 @@
intptr_t SnapshotReader::NextAvailableObjectId() const {
- return backward_references_.length() + kMaxPredefinedObjectIds;
+ return backward_references_->length() +
+ kMaxPredefinedObjectIds + max_vm_isolate_object_id_;
}
@@ -314,6 +319,11 @@
}
+RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const {
+ return Object::vm_isolate_snapshot_object_table().At(index);
+}
+
+
RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
if (IsVMIsolateObject(header_value)) {
return ReadVMIsolateObject(header_value);
@@ -447,9 +457,11 @@
Object* obj,
DeserializeState state) {
intptr_t index = (id - kMaxPredefinedObjectIds);
- ASSERT(index == backward_references_.length());
+ ASSERT(index >= max_vm_isolate_object_id_);
+ index -= max_vm_isolate_object_id_;
+ ASSERT(index == backward_references_->length());
BackRefNode node(obj, state);
- backward_references_.Add(node);
+ backward_references_->Add(node);
}
@@ -456,8 +468,10 @@
Object* SnapshotReader::GetBackRef(intptr_t id) {
ASSERT(id >= kMaxPredefinedObjectIds);
intptr_t index = (id - kMaxPredefinedObjectIds);
- if (index < backward_references_.length()) {
- return backward_references_[index].reference();
+ ASSERT(index >= max_vm_isolate_object_id_);
+ index -= max_vm_isolate_object_id_;
+ if (index < backward_references_->length()) {
+ return (*backward_references_)[index].reference();
}
return NULL;
}
@@ -504,10 +518,10 @@
for (intptr_t i = 0; i <= num_flds; i++) {
*(object_store->from() + i) = ReadObjectImpl();
}
- for (intptr_t i = 0; i < backward_references_.length(); i++) {
- if (!backward_references_[i].is_deserialized()) {
+ for (intptr_t i = 0; i < backward_references_->length(); i++) {
+ if (!(*backward_references_)[i].is_deserialized()) {
ReadObjectImpl();
- backward_references_[i].set_state(kIsDeserialized);
+ (*backward_references_)[i].set_state(kIsDeserialized);
}
}
@@ -979,8 +993,12 @@
return GetType(object_store(), object_id); // return type obj.
}
}
- Object* object = GetBackRef(object_id);
- return object->raw();
+ ASSERT(object_id >= kMaxPredefinedObjectIds);
+ intptr_t index = (object_id - kMaxPredefinedObjectIds);
+ if (index < max_vm_isolate_object_id_) {
+ return VmIsolateSnapshotObject(index);
+ }
+ return GetBackRef(object_id)->raw();
}
@@ -1108,18 +1126,134 @@
result.SetTypeArguments(*TypeArgumentsHandle());
bool is_canonical = RawObject::IsCanonical(tags);
+ Object& obj = Object::Handle(isolate());
for (intptr_t i = 0; i < len; i++) {
*PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef();
+ obj = (*PassiveObjectHandle()).raw();
result.SetAt(i, *PassiveObjectHandle());
}
}
+VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer,
+ intptr_t size,
+ Zone* zone)
+ : SnapshotReader(buffer,
+ size,
+ Snapshot::kFull,
+ new ZoneGrowableArray<BackRefNode>(
+ kNumVmIsolateSnapshotReferences),
+ Dart::vm_isolate(),
+ zone) {
+}
+
+
+VmIsolateSnapshotReader::~VmIsolateSnapshotReader() {
+ intptr_t len = GetBackwardReferenceTable()->length();
+ Object::InitVmIsolateSnapshotObjectTable(len);
+ ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable();
+ for (intptr_t i = 0; i < len; i++) {
+ Object::vm_isolate_snapshot_object_table().SetAt(
+ i, *(backrefs->At(i).reference()));
+ }
+ ResetBackwardReferenceTable();
+}
+
+
+RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
+ ASSERT(kind() == Snapshot::kFull);
+ Isolate* isolate = Isolate::Current();
+ ASSERT(isolate != NULL);
+ ASSERT(isolate == Dart::vm_isolate());
+ ObjectStore* object_store = isolate->object_store();
+ ASSERT(object_store != NULL);
+
+ // First read the version string, and check that it matches.
+ RawApiError* error = VerifyVersion();
+ if (error != ApiError::null()) {
+ return error;
+ }
+
+ // The version string matches. Read the rest of the snapshot.
+
+ {
+ NoSafepointScope no_safepoint;
+ HeapLocker hl(isolate, old_space());
+
+ // Read in the symbol table.
+ object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
+
+ // Validate the class table.
+#if defined(DEBUG)
+ isolate->ValidateClassTable();
+#endif
+
+ return ApiError::null();
+ }
+}
+
+
+IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer,
+ intptr_t size,
+ Isolate* isolate,
+ Zone* zone)
+ : SnapshotReader(buffer,
+ size,
+ Snapshot::kFull,
+ new ZoneGrowableArray<BackRefNode>(
+ kNumInitialReferencesInFullSnapshot),
+ isolate,
+ zone) {
+}
+
+
+IsolateSnapshotReader::~IsolateSnapshotReader() {
+ ResetBackwardReferenceTable();
+}
+
+
+ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer,
+ intptr_t size,
+ Isolate* isolate,
+ Zone* zone)
+ : SnapshotReader(buffer,
+ size,
+ Snapshot::kScript,
+ new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
+ isolate,
+ zone) {
+}
+
+
+ScriptSnapshotReader::~ScriptSnapshotReader() {
+ ResetBackwardReferenceTable();
+}
+
+
+MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer,
+ intptr_t size,
+ Isolate* isolate,
+ Zone* zone)
+ : SnapshotReader(buffer,
+ size,
+ Snapshot::kMessage,
+ new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
+ isolate,
+ zone) {
+}
+
+
+MessageSnapshotReader::~MessageSnapshotReader() {
+ ResetBackwardReferenceTable();
+}
+
+
SnapshotWriter::SnapshotWriter(Snapshot::Kind kind,
uint8_t** buffer,
ReAlloc alloc,
intptr_t initial_size,
+ ForwardList* forward_list,
bool can_send_any_object)
: BaseWriter(buffer, alloc, initial_size),
kind_(kind),
@@ -1126,11 +1260,12 @@
isolate_(Isolate::Current()),
object_store_(isolate_->object_store()),
class_table_(isolate_->class_table()),
- forward_list_(kMaxPredefinedObjectIds),
+ forward_list_(forward_list),
exception_type_(Exceptions::kNone),
exception_msg_(NULL),
unmarked_objects_(false),
can_send_any_object_(can_send_any_object) {
+ ASSERT(forward_list_ != NULL);
}
@@ -1202,7 +1337,6 @@
}
}
-
// Check it is a predefined symbol in the VM isolate.
id = Symbols::LookupVMSymbol(rawobj);
if (id != kInvalidIndex) {
@@ -1210,6 +1344,12 @@
return;
}
+ // Check if it is an object from the vm isolate snapshot object table.
+ id = FindVmSnapshotObject(rawobj);
+ if (id != kInvalidIndex) {
+ WriteIndexedObject(id);
+ return;
+ }
UNREACHABLE();
}
@@ -1233,7 +1373,7 @@
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
// will serialize the object when we go through the forward list.
- forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
@@ -1253,7 +1393,7 @@
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
// will serialize the object when we go through the forward list.
- forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
@@ -1276,7 +1416,7 @@
// to this object in the snapshot will use this object id. Mark it as having
// been serialized so that we do not serialize the object when we go through
// the forward list.
- forward_list_.MarkAndAddObject(raw, kIsSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsSerialized);
switch (class_id) {
#define SNAPSHOT_WRITE(clazz) \
case clazz::kClassId: { \
@@ -1312,27 +1452,100 @@
}
-void FullSnapshotWriter::WriteFullSnapshot() {
- ASSERT(isolate() != NULL);
- ObjectStore* object_store = isolate()->object_store();
+FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
+ uint8_t** isolate_snapshot_buffer,
+ ReAlloc alloc)
+ : vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
+ isolate_snapshot_buffer_(isolate_snapshot_buffer),
+ alloc_(alloc),
+ vm_isolate_snapshot_size_(0),
+ isolate_snapshot_size_(0),
+ forward_list_(SnapshotWriter::FirstObjectId()) {
+ ASSERT(isolate_snapshot_buffer_ != NULL);
+ ASSERT(alloc_ != NULL);
+}
+
+
+void FullSnapshotWriter::WriteVmIsolateSnapshot() {
+ ASSERT(vm_isolate_snapshot_buffer_ != NULL);
+ SnapshotWriter writer(Snapshot::kFull,
+ vm_isolate_snapshot_buffer_,
+ alloc_,
+ kInitialSize,
+ &forward_list_,
+ true); // Can send any kind of object.
+ Isolate* isolate = writer.isolate();
+ ASSERT(isolate != NULL);
+ ObjectStore* object_store = isolate->object_store();
ASSERT(object_store != NULL);
ASSERT(ClassFinalizer::AllClassesFinalized());
// Ensure the class table is valid.
#if defined(DEBUG)
- isolate()->ValidateClassTable();
+ isolate->ValidateClassTable();
#endif
+ // Write full snapshot for a regular isolate.
// Setup for long jump in case there is an exception while writing
// the snapshot.
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
// Reserve space in the output buffer for a snapshot header.
- ReserveHeader();
+ writer.ReserveHeader();
// Write out the version string.
- WriteVersion();
+ writer.WriteVersion();
+ // Write out the symbol table.
+ {
+ NoSafepointScope no_safepoint;
+
+ // Write out the symbol table and reset the symbol table for the
+ // regular isolate so that we do not write these symbols into the
+ // snapshot of a regular dart isolate.
+ writer.WriteObject(object_store->symbol_table());
+
+ writer.FillHeader(writer.kind());
+ }
+ vm_isolate_snapshot_size_ = writer.BytesWritten();
+ // Reset the symbol table for the regular isolate so that we do not
+ // write these symbols into the snapshot of a regular dart isolate.
+ Symbols::SetupSymbolTable(isolate);
+ } else {
+ writer.ThrowException(writer.exception_type(), writer.exception_msg());
+ }
+}
+
+
+void FullSnapshotWriter::WriteIsolateFullSnapshot() {
+ SnapshotWriter writer(Snapshot::kFull,
+ isolate_snapshot_buffer_,
+ alloc_,
+ kInitialSize,
+ &forward_list_,
+ true);
+ Isolate* isolate = writer.isolate();
+ ASSERT(isolate != NULL);
+ ObjectStore* object_store = isolate->object_store();
+ ASSERT(object_store != NULL);
+ ASSERT(ClassFinalizer::AllClassesFinalized());
+
+ // Ensure the class table is valid.
+#if defined(DEBUG)
+ isolate->ValidateClassTable();
+#endif
+
+ // Write full snapshot for a regular isolate.
+ // Setup for long jump in case there is an exception while writing
+ // the snapshot.
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ // Reserve space in the output buffer for a snapshot header.
+ writer.ReserveHeader();
+
+ // Write out the version string.
+ writer.WriteVersion();
+
// Write out the full snapshot.
{
NoSafepointScope no_safepoint;
@@ -1339,26 +1552,35 @@
// Write out all the objects in the object store of the isolate which
// is the root set for all dart allocated objects at this point.
- SnapshotWriterVisitor visitor(this, false);
+ SnapshotWriterVisitor visitor(&writer, false);
object_store->VisitObjectPointers(&visitor);
// Write out all forwarded objects.
- WriteForwardedObjects();
+ writer.WriteForwardedObjects();
- FillHeader(kind());
- UnmarkAll();
+ writer.FillHeader(writer.kind());
+ writer.UnmarkAll();
}
+ isolate_snapshot_size_ = writer.BytesWritten();
} else {
- ThrowException(exception_type(), exception_msg());
+ writer.ThrowException(writer.exception_type(), writer.exception_msg());
}
}
+void FullSnapshotWriter::WriteFullSnapshot() {
+ if (vm_isolate_snapshot_buffer() != NULL) {
+ WriteVmIsolateSnapshot();
+ }
+ WriteIsolateFullSnapshot();
+}
+
+
uword SnapshotWriter::GetObjectTags(RawObject* raw) {
uword tags = raw->ptr()->tags_;
if (SerializedHeaderTag::decode(tags) == kObjectId) {
intptr_t id = SerializedHeaderData::decode(tags);
- return forward_list_.NodeForObjectId(id)->tags();
+ return forward_list_->NodeForObjectId(id)->tags();
} else {
return tags;
}
@@ -1392,7 +1614,7 @@
intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) {
NoSafepointScope no_safepoint;
intptr_t object_id = next_object_id();
- ASSERT(object_id <= kMaxObjectId);
+ ASSERT(object_id > 0 && object_id <= kMaxObjectId);
uword value = 0;
value = SerializedHeaderTag::update(kObjectId, value);
value = SerializedHeaderData::update(object_id, value);
@@ -1407,11 +1629,13 @@
void ForwardList::UnmarkAll() const {
- NoSafepointScope no_safepoint;
- for (intptr_t id = first_object_id(); id < next_object_id(); ++id) {
- const Node* node = NodeForObjectId(id);
- RawObject* raw = node->raw();
- raw->ptr()->tags_ = node->tags(); // Restore original tags.
+ {
+ NoSafepointScope no_safepoint;
+ for (intptr_t id = first_object_id(); id < next_object_id(); ++id) {
+ const Node* node = NodeForObjectId(id);
+ RawObject* raw = node->raw();
+ raw->ptr()->tags_ = node->tags(); // Restore original tags.
+ }
}
}
@@ -1512,7 +1736,7 @@
// Object is being serialized, add it to the forward ref list and mark
// it so that future references to this object in the snapshot will use
// an object id, instead of trying to serialize it again.
- forward_list_.MarkAndAddObject(raw, kIsSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsSerialized);
WriteInlinedObject(raw);
}
@@ -1528,7 +1752,7 @@
uword tags = raw->ptr()->tags_;
ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
intptr_t object_id = SerializedHeaderData::decode(tags);
- tags = forward_list_.NodeForObjectId(object_id)->tags();
+ tags = forward_list_->NodeForObjectId(object_id)->tags();
RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
intptr_t class_id = cls->ptr()->id_;
@@ -1600,7 +1824,7 @@
void SnapshotWriter::WriteForwardedObjects() {
WriteInlinedObjectVisitor visitor(this);
- forward_list_.SerializeAll(&visitor);
+ forward_list_->SerializeAll(&visitor);
}
@@ -1842,11 +2066,11 @@
// to this object in the snapshot will use this object id. Mark it as having
// been serialized so that we do not serialize the object when we go through
// the forward list.
- forward_list_.MarkAndAddObject(raw, kIsSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsSerialized);
uword tags = raw->ptr()->tags_;
ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
intptr_t object_id = SerializedHeaderData::decode(tags);
- tags = forward_list_.NodeForObjectId(object_id)->tags();
+ tags = forward_list_->NodeForObjectId(object_id)->tags();
WriteStaticImplicitClosure(object_id, func, tags);
return;
}
@@ -1855,7 +2079,7 @@
// it so that future references to this object in the snapshot will use
// this object id. Mark it as not having been serialized yet so that we
// will serialize the object when we go through the forward list.
- forward_list_.MarkAndAddObject(raw, kIsNotSerialized);
+ forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
// Write out the serialization header value for this object.
WriteInlinedObjectHeader(kOmittedObjectId);
@@ -1874,6 +2098,17 @@
}
+intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) {
+ intptr_t length = Object::vm_isolate_snapshot_object_table().Length();
+ for (intptr_t i = 0; i < length; i++) {
+ if (Object::vm_isolate_snapshot_object_table().At(i) == rawobj) {
+ return (i + kMaxPredefinedObjectIds);
+ }
+ }
+ return kInvalidIndex;
+}
+
+
void SnapshotWriter::ThrowException(Exceptions::ExceptionType type,
const char* msg) {
object_store()->clear_sticky_error();
@@ -1898,6 +2133,27 @@
}
+intptr_t SnapshotWriter::FirstObjectId() {
+ intptr_t max_vm_isolate_object_id =
+ Object::vm_isolate_snapshot_object_table().Length();
+ return kMaxPredefinedObjectIds + max_vm_isolate_object_id;
+}
+
+
+ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
+ ReAlloc alloc)
+ : SnapshotWriter(Snapshot::kScript,
+ buffer,
+ alloc,
+ kInitialSize,
+ &forward_list_,
+ true),
+ forward_list_(SnapshotWriter::FirstObjectId()) {
+ ASSERT(buffer != NULL);
+ ASSERT(alloc != NULL);
+}
+
+
void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) {
ASSERT(kind() == Snapshot::kScript);
ASSERT(isolate() != NULL);
@@ -1941,6 +2197,21 @@
}
+MessageWriter::MessageWriter(uint8_t** buffer,
+ ReAlloc alloc,
+ bool can_send_any_object)
+ : SnapshotWriter(Snapshot::kMessage,
+ buffer,
+ alloc,
+ kInitialSize,
+ &forward_list_,
+ can_send_any_object),
+ forward_list_(SnapshotWriter::FirstObjectId()) {
+ ASSERT(buffer != NULL);
+ ASSERT(alloc != NULL);
+}
+
+
void MessageWriter::WriteMessage(const Object& obj) {
ASSERT(kind() == Snapshot::kMessage);
ASSERT(isolate() != NULL);
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698