From 01cc7d3cd26bc1211ab9ee4fd1f1be72db3d6492 Mon Sep 17 00:00:00 2001 From: "asiva@google.com" Date: Fri, 22 Mar 2013 22:43:46 +0000 Subject: [PATCH] - Canonicalize types, type_arguments only when the object is marked as being from the core libraries. - adjust the snapshot write buffer growth policy - turn off the heap growth rate adjustments when reading from a snapshot. Review URL: https://codereview.chromium.org//12578009 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@20423 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/vm/dart_api_impl.cc | 2 ++ runtime/vm/dart_api_message.h | 7 +++-- runtime/vm/datastream.h | 20 +++++++----- runtime/vm/heap.cc | 23 ++++++++++++-- runtime/vm/heap.h | 15 ++++++++- runtime/vm/object.cc | 4 +-- runtime/vm/pages.h | 15 ++++++--- runtime/vm/raw_object_snapshot.cc | 51 ++++++++++++++++++++++++++++--- runtime/vm/snapshot.cc | 10 +++--- runtime/vm/snapshot.h | 16 +++++----- runtime/vm/snapshot_test.cc | 4 +-- 11 files changed, 127 insertions(+), 40 deletions(-) diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 233352332eb..06730d96cfa 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -4401,6 +4401,8 @@ DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer, if (buffer == NULL) { RETURN_NULL_ERROR(buffer); } + NoHeapGrowthControlScope no_growth_control; + const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer); if (!snapshot->IsScriptSnapshot()) { return Api::NewError("%s expects parameter 'buffer' to be a script type" diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h index 7103fa10a57..84d44a8cf35 100644 --- a/runtime/vm/dart_api_message.h +++ b/runtime/vm/dart_api_message.h @@ -119,10 +119,11 @@ class ApiMessageReader : public BaseReader { class ApiMessageWriter : public BaseWriter { public: - static const intptr_t kIncrementSize = 512; + static const intptr_t kInitialSize = 512; ApiMessageWriter(uint8_t** buffer, ReAlloc alloc) - : BaseWriter(buffer, alloc, kIncrementSize), object_id_(0), - forward_list_(NULL), forward_list_length_(0), forward_id_(0) { + : BaseWriter(buffer, alloc, kInitialSize), + object_id_(0), forward_list_(NULL), + forward_list_length_(0), forward_id_(0) { ASSERT(kDartCObjectTypeMask >= Dart_CObject::kNumberOfTypes - 1); } ~ApiMessageWriter() { diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h index 652d942070f..1aa299b9461 100644 --- a/runtime/vm/datastream.h +++ b/runtime/vm/datastream.h @@ -136,22 +136,22 @@ class ReadStream : public ValueObject { // Stream for writing various types into a buffer. class WriteStream : public ValueObject { public: - WriteStream(uint8_t** buffer, ReAlloc alloc, intptr_t increment_size) : + WriteStream(uint8_t** buffer, ReAlloc alloc, intptr_t initial_size) : buffer_(buffer), end_(NULL), current_(NULL), current_size_(0), alloc_(alloc), - increment_size_(increment_size) { + initial_size_(initial_size) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); *buffer_ = reinterpret_cast(alloc_(NULL, 0, - increment_size_)); + initial_size_)); ASSERT(*buffer_ != NULL); current_ = *buffer_; - current_size_ = increment_size_; - end_ = *buffer_ + increment_size_; + current_size_ = initial_size_; + end_ = *buffer_ + initial_size_; } uint8_t* buffer() const { return *buffer_; } @@ -234,8 +234,12 @@ class WriteStream : public ValueObject { void Resize(intptr_t size_needed) { intptr_t position = current_ - *buffer_; - intptr_t new_size = current_size_ + - Utils::RoundUp(size_needed, increment_size_); + intptr_t increment_size = current_size_; + if (size_needed > increment_size) { + increment_size = Utils::RoundUp(size_needed, initial_size_); + } + intptr_t new_size = current_size_ + increment_size; + ASSERT(new_size > current_size_); *buffer_ = reinterpret_cast(alloc_(*buffer_, current_size_, new_size)); @@ -252,7 +256,7 @@ class WriteStream : public ValueObject { uint8_t* current_; intptr_t current_size_; ReAlloc alloc_; - intptr_t increment_size_; + intptr_t initial_size_; DISALLOW_COPY_AND_ASSIGN(WriteStream); }; diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc index 7cf859f3635..08099176c12 100644 --- a/runtime/vm/heap.cc +++ b/runtime/vm/heap.cc @@ -201,8 +201,13 @@ void Heap::CollectAllGarbage() { } -void Heap::EnableGrowthControl() { - old_space_->EnableGrowthControl(); +void Heap::SetGrowthControlState(bool state) { + old_space_->SetGrowthControlState(state); +} + + +bool Heap::GrowthControlState() { + return old_space_->GrowthControlState(); } @@ -482,4 +487,18 @@ NoGCScope::~NoGCScope() { } #endif // defined(DEBUG) + +NoHeapGrowthControlScope::NoHeapGrowthControlScope() + : StackResource(Isolate::Current()) { + Heap* heap = reinterpret_cast(isolate())->heap(); + current_growth_controller_state_ = heap->GrowthControlState(); + heap->DisableGrowthControl(); +} + + +NoHeapGrowthControlScope::~NoHeapGrowthControlScope() { + Heap* heap = reinterpret_cast(isolate())->heap(); + heap->SetGrowthControlState(current_growth_controller_state_); +} + } // namespace dart diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h index 3090efa9ded..ab0f5db3134 100644 --- a/runtime/vm/heap.h +++ b/runtime/vm/heap.h @@ -132,7 +132,10 @@ class Heap { // Enables growth control on the page space heaps. This should be // called before any user code is executed. - void EnableGrowthControl(); + void EnableGrowthControl() { SetGrowthControlState(true); } + void DisableGrowthControl() { SetGrowthControlState(false); } + void SetGrowthControlState(bool state); + bool GrowthControlState(); // Protect access to the heap. void WriteProtect(bool read_only); @@ -274,6 +277,16 @@ class NoGCScope : public ValueObject { }; #endif // defined(DEBUG) + +class NoHeapGrowthControlScope : public StackResource { + public: + NoHeapGrowthControlScope(); + ~NoHeapGrowthControlScope(); + private: + bool current_growth_controller_state_; + DISALLOW_COPY_AND_ASSIGN(NoHeapGrowthControlScope); +}; + } // namespace dart #endif // VM_HEAP_H_ diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 121788bb9ca..8ed8799f33f 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -5166,10 +5166,10 @@ RawTokenStream* TokenStream::New(intptr_t len) { // Helper class for creation of compressed token stream data. class CompressedTokenStreamData : public ValueObject { public: - static const intptr_t kIncrementSize = 16 * KB; + static const intptr_t kInitialSize = 16 * KB; CompressedTokenStreamData() : buffer_(NULL), - stream_(&buffer_, Reallocate, kIncrementSize), + stream_(&buffer_, Reallocate, kInitialSize), token_objects_(GrowableObjectArray::Handle( GrowableObjectArray::New(kInitialTokenCount, Heap::kOld))), token_obj_(Object::Handle()), diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h index 69632b66c38..f3e67a36dfb 100644 --- a/runtime/vm/pages.h +++ b/runtime/vm/pages.h @@ -127,8 +127,11 @@ class PageSpaceController { void EvaluateGarbageCollection(intptr_t in_use_before, intptr_t in_use_after, int64_t start, int64_t end); - void Enable() { - is_enabled_ = true; + void set_is_enabled(bool state) { + is_enabled_ = state; + } + bool is_enabled() { + return is_enabled_; } private: @@ -204,8 +207,12 @@ class PageSpace { void StartEndAddress(uword* start, uword* end) const; - void EnableGrowthControl() { - page_space_controller_.Enable(); + void SetGrowthControlState(bool state) { + page_space_controller_.set_is_enabled(state); + } + + bool GrowthControlState() { + return page_space_controller_.is_enabled(); } void WriteProtect(bool read_only); diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc index 6d397571174..76ba4c1af71 100644 --- a/runtime/vm/raw_object_snapshot.cc +++ b/runtime/vm/raw_object_snapshot.cc @@ -205,7 +205,16 @@ RawType* Type::ReadFrom(SnapshotReader* reader, } // If object needs to be a canonical object, Canonicalize it. - if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) { + // When reading a full snapshot we don't need to canonicalize the object + // as it would already be a canonical object. + // When reading a script snapshot we need to canonicalize only those object + // references that are objects from the core library (loaded from a + // full snapshot). Objects that are only in the script need not be + // canonicalized as they are already canonical. + // When reading a message snapshot we always have to canonicalize the object. + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags) && + (RawObject::IsCreatedFromSnapshot(tags) || + (kind == Snapshot::kMessage))) { type ^= type.Canonicalize(); } @@ -458,7 +467,16 @@ RawTypeArguments* TypeArguments::ReadFrom(SnapshotReader* reader, } // If object needs to be a canonical object, Canonicalize it. - if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) { + // When reading a full snapshot we don't need to canonicalize the object + // as it would already be a canonical object. + // When reading a script snapshot we need to canonicalize only those object + // references that are objects from the core library (loaded from a + // full snapshot). Objects that are only in the script need not be + // canonicalized as they are already canonical. + // When reading a message snapshot we always have to canonicalize the object. + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags) && + (RawObject::IsCreatedFromSnapshot(tags) || + (kind == Snapshot::kMessage))) { type_arguments ^= type_arguments.Canonicalize(); } @@ -1597,7 +1615,14 @@ RawMint* Mint::ReadFrom(SnapshotReader* reader, if (kind == Snapshot::kFull) { mint = reader->NewMint(value); } else { - if (RawObject::IsCanonical(tags)) { + // When reading a script snapshot we need to canonicalize only those object + // references that are objects from the core library (loaded from a + // full snapshot). Objects that are only in the script need not be + // canonicalized as they are already canonical. + // When reading a message snapshot we always have to canonicalize. + if (RawObject::IsCanonical(tags) && + (RawObject::IsCreatedFromSnapshot(tags) || + (kind == Snapshot::kMessage))) { mint = Mint::NewCanonical(value); } else { mint = Mint::New(value, HEAP_SPACE(kind)); @@ -1648,7 +1673,16 @@ RawBigint* Bigint::ReadFrom(SnapshotReader* reader, BigintOperations::FromHexCString(str, HEAP_SPACE(kind)))); // If it is a canonical constant make it one. - if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags)) { + // When reading a full snapshot we don't need to canonicalize the object + // as it would already be a canonical object. + // When reading a script snapshot we need to canonicalize only those object + // references that are objects from the core library (loaded from a + // full snapshot). Objects that are only in the script need not be + // canonicalized as they are already canonical. + // When reading a message snapshot we always have to canonicalize the object. + if ((kind != Snapshot::kFull) && RawObject::IsCanonical(tags) && + (RawObject::IsCreatedFromSnapshot(tags) || + (kind == Snapshot::kMessage))) { obj ^= obj.Canonicalize(); } reader->AddBackRef(object_id, &obj, kIsDeserialized); @@ -1715,7 +1749,14 @@ RawDouble* Double::ReadFrom(SnapshotReader* reader, if (kind == Snapshot::kFull) { dbl = reader->NewDouble(value); } else { - if (RawObject::IsCanonical(tags)) { + // When reading a script snapshot we need to canonicalize only those object + // references that are objects from the core library (loaded from a + // full snapshot). Objects that are only in the script need not be + // canonicalized as they are already canonical. + // When reading a message snapshot we always have to canonicalize. + if (RawObject::IsCanonical(tags) && + (RawObject::IsCreatedFromSnapshot(tags) || + (kind == Snapshot::kMessage))) { dbl = Double::NewCanonical(value); } else { dbl = Double::New(value, HEAP_SPACE(kind)); diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc index c477c7cd2cc..454b60bb3bc 100644 --- a/runtime/vm/snapshot.cc +++ b/runtime/vm/snapshot.cc @@ -19,7 +19,7 @@ namespace dart { static const int kNumInitialReferencesInFullSnapshot = 160 * KB; -static const int kNumInitialReferences = 4; +static const int kNumInitialReferences = 64; static bool IsSingletonClassId(intptr_t class_id) { @@ -840,10 +840,10 @@ void SnapshotReader::ArrayReadFrom(const Array& result, SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, - uint8_t** buffer, - ReAlloc alloc, - intptr_t increment_size) - : BaseWriter(buffer, alloc, increment_size), + uint8_t** buffer, + ReAlloc alloc, + intptr_t initial_size) + : BaseWriter(buffer, alloc, initial_size), kind_(kind), object_store_(Isolate::Current()->object_store()), class_table_(Isolate::Current()->class_table()), diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index 5d199f684cc..743712734f1 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -416,7 +416,7 @@ class BaseWriter { protected: BaseWriter(uint8_t** buffer, ReAlloc alloc, - intptr_t increment_size) : stream_(buffer, alloc, increment_size) { + intptr_t initial_size) : stream_(buffer, alloc, initial_size) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); } @@ -445,7 +445,7 @@ class SnapshotWriter : public BaseWriter { SnapshotWriter(Snapshot::Kind kind, uint8_t** buffer, ReAlloc alloc, - intptr_t increment_size); + intptr_t initial_size); public: // Snapshot kind. @@ -534,9 +534,9 @@ class SnapshotWriter : public BaseWriter { class FullSnapshotWriter : public SnapshotWriter { public: - static const intptr_t kIncrementSize = 64 * KB; + static const intptr_t kInitialSize = 64 * KB; FullSnapshotWriter(uint8_t** buffer, ReAlloc alloc) - : SnapshotWriter(Snapshot::kFull, buffer, alloc, kIncrementSize) { + : SnapshotWriter(Snapshot::kFull, buffer, alloc, kInitialSize) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); } @@ -552,9 +552,9 @@ class FullSnapshotWriter : public SnapshotWriter { class ScriptSnapshotWriter : public SnapshotWriter { public: - static const intptr_t kIncrementSize = 64 * KB; + static const intptr_t kInitialSize = 64 * KB; ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc) - : SnapshotWriter(Snapshot::kScript, buffer, alloc, kIncrementSize) { + : SnapshotWriter(Snapshot::kScript, buffer, alloc, kInitialSize) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); } @@ -570,9 +570,9 @@ class ScriptSnapshotWriter : public SnapshotWriter { class MessageWriter : public SnapshotWriter { public: - static const intptr_t kIncrementSize = 512; + static const intptr_t kInitialSize = 512; MessageWriter(uint8_t** buffer, ReAlloc alloc) - : SnapshotWriter(Snapshot::kMessage, buffer, alloc, kIncrementSize) { + : SnapshotWriter(Snapshot::kMessage, buffer, alloc, kInitialSize) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); } diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 021569c4402..9e947951a19 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -744,9 +744,9 @@ TEST_CASE(SerializeEmptyByteArray) { class TestSnapshotWriter : public SnapshotWriter { public: - static const intptr_t kIncrementSize = 64 * KB; + static const intptr_t kInitialSize = 64 * KB; TestSnapshotWriter(uint8_t** buffer, ReAlloc alloc) - : SnapshotWriter(Snapshot::kScript, buffer, alloc, kIncrementSize) { + : SnapshotWriter(Snapshot::kScript, buffer, alloc, kInitialSize) { ASSERT(buffer != NULL); ASSERT(alloc != NULL); }