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

Unified Diff: runtime/vm/object_id_ring.cc

Issue 18259014: Object ID Ring with tests (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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/object_id_ring.h ('k') | runtime/vm/object_id_ring_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object_id_ring.cc
diff --git a/runtime/vm/object_id_ring.cc b/runtime/vm/object_id_ring.cc
new file mode 100644
index 0000000000000000000000000000000000000000..024d0a04f9204b231baab7dcf8a438f66fd68f92
--- /dev/null
+++ b/runtime/vm/object_id_ring.cc
@@ -0,0 +1,152 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "platform/assert.h"
+#include "vm/dart_api_state.h"
+#include "vm/object_id_ring.h"
+
+namespace dart {
+
+
+void ObjectIdRing::Init(Isolate* isolate, intptr_t capacity) {
+ ObjectIdRing* ring = new ObjectIdRing(isolate, capacity);
+ if (isolate != NULL) {
+ isolate->set_object_id_ring(ring);
+ }
+}
+
+
+ObjectIdRing::~ObjectIdRing() {
+ ASSERT(table_ != NULL);
+ free(table_);
+ table_ = NULL;
+ if (isolate_ != NULL) {
+ isolate_->set_object_id_ring(NULL);
+ isolate_ = NULL;
+ }
+}
+
+
+intptr_t ObjectIdRing::GetIdForObject(RawObject* object) {
+ return AllocateNewId(object);
+}
+
+
+RawObject* ObjectIdRing::GetObjectForId(intptr_t id) {
+ intptr_t index = IndexOfId(id);
+ if (index == kInvalidId) {
+ return Object::null();
Ivan Posva 2013/07/10 01:10:13 We might want to return an object that is known to
Cutch 2013/07/10 17:23:10 Do we want to distinguish between the following tw
+ }
+ ASSERT(index >= 0);
+ ASSERT(index < capacity_);
+ return table_[index];
+}
+
+
+ObjectIdRing::ObjectIdRing(Isolate* isolate, intptr_t capacity) {
+ ASSERT(capacity > 0);
+ isolate_ = isolate;
+ capacity_ = capacity;
+ serial_num_ = 0;
+ wrapped_ = false;
+ RawObject* sizer = NULL;
+ const size_t table_size = sizeof(sizer)*capacity_;
+ table_ = reinterpret_cast<RawObject**>(malloc(table_size));
+ for (int i = 0; i < capacity_; i++) {
+ table_[i] = Object::null();
+ }
+ // The maximum serial number is a multiple of the capacity, so that when
+ // the serial number wraps, the index into table_ wraps with it.
+ max_serial_ = INTPTR_MAX - (INTPTR_MAX % capacity_);
+}
+
+
+intptr_t ObjectIdRing::NextSerial() {
+ intptr_t r = serial_num_;
+ serial_num_++;
+ if (serial_num_ >= max_serial_) {
+ serial_num_ = 0;
+ wrapped_ = true;
+ }
+ return r;
+}
+
+
+intptr_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
+ ASSERT(raw_obj->IsHeapObject());
Ivan Posva 2013/07/10 01:10:13 How do you intend to represent Smis on the wire?
Cutch 2013/07/10 17:23:10 When sending objects as JSON there is always a "ty
+ intptr_t id = NextSerial();
+ ASSERT(id != kInvalidId);
+ intptr_t cursor = IndexOfId(id);
+ ASSERT(cursor != kInvalidId);
+ if (table_[cursor] != Object::null()) {
+ // Free old handle.
+ table_[cursor] = Object::null();
+ }
+ ASSERT(table_[cursor] == Object::null());
+ table_[cursor] = raw_obj;
+ return id;
+}
+
+
+intptr_t ObjectIdRing::IndexOfId(intptr_t id) {
+ if (!IsValidId(id)) {
+ return kInvalidId;
+ }
+ ASSERT((id >= 0) && (id < max_serial_));
+ return id % capacity_;
+}
+
+
+bool ObjectIdRing::IsValidContiguous(intptr_t id) {
+ ASSERT(id != kInvalidId);
+ ASSERT((id >= 0) && (id < max_serial_));
+ if (id >= serial_num_) {
+ // Too large.
+ return false;
+ }
+ intptr_t bottom = 0;
+ if (serial_num_ >= capacity_) {
+ bottom = serial_num_ - capacity_;
+ }
+ return id >= bottom;
+}
+
+
+bool ObjectIdRing::IsValidId(intptr_t id) {
+ if (id == kInvalidId) {
+ return false;
+ }
+ if (id >= max_serial_) {
+ return false;
+ }
+ ASSERT((id >= 0) && (id < max_serial_));
+ if (wrapped_) {
+ // Serial number has wrapped around to 0.
+ if (serial_num_ >= capacity_) {
+ // Serial number is larger than capacity, the serial
+ // numbers are contiguous again.
+ wrapped_ = false;
+ return IsValidContiguous(id);
+ } else {
+ // When the serial number first wraps, the valid serial number range
+ // spans two intervals:
+ // #1 [0, serial_num_)
+ // #2 [max_serial_ - (capacity_ - serial_num), max_serial_)
+ //
+ // Check for both.
+ if (id < serial_num_) {
+ // Interval #1
+ return true;
+ }
+ // Interval #2
+ const intptr_t max_serial_num = max_serial_;
+ const intptr_t bottom = max_serial_num - (capacity_ - serial_num_);
+ return id >= bottom && bottom < max_serial_num;
+ }
+ }
+ ASSERT(wrapped_ == false);
+ return IsValidContiguous(id);
+}
+
+} // namespace dart
« no previous file with comments | « runtime/vm/object_id_ring.h ('k') | runtime/vm/object_id_ring_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698