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

Side by Side 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, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "platform/assert.h"
6 #include "vm/dart_api_state.h"
7 #include "vm/object_id_ring.h"
8
9 namespace dart {
10
11 void ObjectIdRing::Init(Isolate* isolate, int32_t capacity) {
12 ObjectIdRing* ring = new ObjectIdRing(isolate, capacity);
13 if (isolate != NULL) {
Ivan Posva 2013/07/11 17:01:42 I'd prefer it if the test case for wrapping was us
Cutch 2013/07/11 21:31:47 Done.
14 isolate->set_object_id_ring(ring);
15 }
16 }
17
18
19 ObjectIdRing::~ObjectIdRing() {
20 ASSERT(table_ != NULL);
21 free(table_);
22 table_ = NULL;
23 if (isolate_ != NULL) {
24 isolate_->set_object_id_ring(NULL);
25 isolate_ = NULL;
26 }
27 }
28
29
30 int32_t ObjectIdRing::GetIdForObject(RawObject* object) {
31 return AllocateNewId(object);
32 }
33
34
35 RawObject* ObjectIdRing::GetObjectForId(int32_t id) {
36 int32_t index = IndexOfId(id);
37 if (index == kInvalidId) {
38 return Object::null();
39 }
40 ASSERT(index >= 0);
41 ASSERT(index < capacity_);
42 return table_[index];
43 }
44
45
46 void ObjectIdRing::VisitPointers(ObjectPointerVisitor* visitor) {
47 if (table_ != NULL) {
Ivan Posva 2013/07/11 17:01:42 ASSERT(table_ != NULL); I don't see a way table_
Cutch 2013/07/11 21:31:47 Done.
48 visitor->VisitPointers(table_, capacity_);
49 }
50 }
51
52
53 ObjectIdRing::ObjectIdRing(Isolate* isolate, int32_t capacity) {
54 ASSERT(capacity > 0);
55 isolate_ = isolate;
56 capacity_ = capacity;
57 serial_num_ = 0;
58 wrapped_ = false;
59 table_ = reinterpret_cast<RawObject**>(calloc(capacity_, kWordSize));
60 for (int i = 0; i < capacity_; i++) {
61 table_[i] = Object::null();
62 }
63 // The maximum serial number is a multiple of the capacity, so that when
64 // the serial number wraps, the index into table_ wraps with it.
65 max_serial_ = kMaxId - (kMaxId % capacity_);
66 }
67
68
69 int32_t ObjectIdRing::NextSerial() {
70 int32_t r = serial_num_;
71 serial_num_++;
72 if (serial_num_ >= max_serial_) {
73 serial_num_ = 0;
74 wrapped_ = true;
75 }
76 return r;
77 }
78
79
80 int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
81 ASSERT(raw_obj->IsHeapObject());
82 int32_t id = NextSerial();
83 ASSERT(id != kInvalidId);
84 int32_t cursor = IndexOfId(id);
85 ASSERT(cursor != kInvalidId);
86 if (table_[cursor] != Object::null()) {
87 // Free old handle.
88 table_[cursor] = Object::null();
89 }
90 ASSERT(table_[cursor] == Object::null());
91 table_[cursor] = raw_obj;
92 return id;
93 }
94
95
96 int32_t ObjectIdRing::IndexOfId(int32_t id) {
97 if (!IsValidId(id)) {
98 return kInvalidId;
99 }
100 ASSERT((id >= 0) && (id < max_serial_));
101 return id % capacity_;
102 }
103
104
105 bool ObjectIdRing::IsValidContiguous(int32_t id) {
106 ASSERT(id != kInvalidId);
107 ASSERT((id >= 0) && (id < max_serial_));
108 if (id >= serial_num_) {
109 // Too large.
110 return false;
111 }
112 int32_t bottom = 0;
113 if (serial_num_ >= capacity_) {
114 bottom = serial_num_ - capacity_;
115 }
116 return id >= bottom;
117 }
118
119
120 bool ObjectIdRing::IsValidId(int32_t id) {
121 if (id == kInvalidId) {
122 return false;
123 }
124 if (id >= max_serial_) {
125 return false;
126 }
127 ASSERT((id >= 0) && (id < max_serial_));
128 if (wrapped_) {
129 // Serial number has wrapped around to 0.
130 if (serial_num_ >= capacity_) {
131 // Serial number is larger than capacity, the serial
132 // numbers are contiguous again.
133 wrapped_ = false;
134 return IsValidContiguous(id);
135 } else {
136 // When the serial number first wraps, the valid serial number range
137 // spans two intervals:
138 // #1 [0, serial_num_)
139 // #2 [max_serial_ - (capacity_ - serial_num), max_serial_)
140 //
141 // Check for both.
142 if (id < serial_num_) {
143 // Interval #1
144 return true;
145 }
146 // Interval #2
147 const int32_t max_serial_num = max_serial_;
148 const int32_t bottom = max_serial_num - (capacity_ - serial_num_);
149 return id >= bottom && bottom < max_serial_num;
150 }
151 }
152 ASSERT(wrapped_ == false);
153 return IsValidContiguous(id);
154 }
155
156 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698