- 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
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+12
-8
@@ -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<uint8_t*>(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<uint8_t*>(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);
|
||||
};
|
||||
|
||||
+21
-2
@@ -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*>(isolate())->heap();
|
||||
current_growth_controller_state_ = heap->GrowthControlState();
|
||||
heap->DisableGrowthControl();
|
||||
}
|
||||
|
||||
|
||||
NoHeapGrowthControlScope::~NoHeapGrowthControlScope() {
|
||||
Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
|
||||
heap->SetGrowthControlState(current_growth_controller_state_);
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
||||
+14
-1
@@ -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_
|
||||
|
||||
@@ -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()),
|
||||
|
||||
+11
-4
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user