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

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
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 isolate->set_object_id_ring(ring);
14 }
15
16
17 ObjectIdRing::~ObjectIdRing() {
18 ASSERT(table_ != NULL);
19 free(table_);
20 table_ = NULL;
21 if (isolate_ != NULL) {
22 isolate_->set_object_id_ring(NULL);
23 isolate_ = NULL;
24 }
25 }
26
27
28 int32_t ObjectIdRing::GetIdForObject(RawObject* object) {
29 return AllocateNewId(object);
30 }
31
32
33 RawObject* ObjectIdRing::GetObjectForId(int32_t id) {
34 int32_t index = IndexOfId(id);
35 if (index == kInvalidId) {
36 return Object::null();
37 }
38 ASSERT(index >= 0);
39 ASSERT(index < capacity_);
40 return table_[index];
41 }
42
43
44 void ObjectIdRing::VisitPointers(ObjectPointerVisitor* visitor) {
45 ASSERT(table_ != NULL);
46 visitor->VisitPointers(table_, capacity_);
47 }
48
49
50 ObjectIdRing::ObjectIdRing(Isolate* isolate, int32_t capacity) {
51 ASSERT(capacity > 0);
52 isolate_ = isolate;
53 serial_num_ = 0;
54 wrapped_ = false;
55 table_ = NULL;
56 SetCapacityAndMaxSerial(capacity, kMaxId);
57 }
58
59
60 void ObjectIdRing::SetCapacityAndMaxSerial(int32_t capacity,
61 int32_t max_serial) {
62 ASSERT(max_serial <= kMaxId);
63 capacity_ = capacity;
64 if (table_ != NULL) {
65 free(table_);
66 }
67 table_ = reinterpret_cast<RawObject**>(calloc(capacity_, kWordSize));
68 for (int i = 0; i < capacity_; i++) {
69 table_[i] = Object::null();
70 }
71 // The maximum serial number is a multiple of the capacity, so that when
72 // the serial number wraps, the index into table_ wraps with it.
73 max_serial_ = max_serial - (max_serial % capacity_);
74 }
75
76
77 int32_t ObjectIdRing::NextSerial() {
78 int32_t r = serial_num_;
79 serial_num_++;
80 if (serial_num_ >= max_serial_) {
81 serial_num_ = 0;
82 wrapped_ = true;
83 }
84 return r;
85 }
86
87
88 int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
89 ASSERT(raw_obj->IsHeapObject());
90 int32_t id = NextSerial();
91 ASSERT(id != kInvalidId);
92 int32_t cursor = IndexOfId(id);
93 ASSERT(cursor != kInvalidId);
94 if (table_[cursor] != Object::null()) {
95 // Free old handle.
96 table_[cursor] = Object::null();
97 }
98 ASSERT(table_[cursor] == Object::null());
99 table_[cursor] = raw_obj;
100 return id;
101 }
102
103
104 int32_t ObjectIdRing::IndexOfId(int32_t id) {
105 if (!IsValidId(id)) {
106 return kInvalidId;
107 }
108 ASSERT((id >= 0) && (id < max_serial_));
109 return id % capacity_;
110 }
111
112
113 bool ObjectIdRing::IsValidContiguous(int32_t id) {
114 ASSERT(id != kInvalidId);
115 ASSERT((id >= 0) && (id < max_serial_));
116 if (id >= serial_num_) {
117 // Too large.
118 return false;
119 }
120 int32_t bottom = 0;
121 if (serial_num_ >= capacity_) {
122 bottom = serial_num_ - capacity_;
123 }
124 return id >= bottom;
125 }
126
127
128 bool ObjectIdRing::IsValidId(int32_t id) {
129 if (id == kInvalidId) {
130 return false;
131 }
132 if (id >= max_serial_) {
133 return false;
134 }
135 ASSERT((id >= 0) && (id < max_serial_));
136 if (wrapped_) {
137 // Serial number has wrapped around to 0.
138 if (serial_num_ >= capacity_) {
139 // Serial number is larger than capacity, the serial
140 // numbers are contiguous again.
141 wrapped_ = false;
142 return IsValidContiguous(id);
143 } else {
144 // When the serial number first wraps, the valid serial number range
145 // spans two intervals:
146 // #1 [0, serial_num_)
147 // #2 [max_serial_ - (capacity_ - serial_num), max_serial_)
148 //
149 // Check for both.
150 if (id < serial_num_) {
151 // Interval #1
152 return true;
153 }
154 // Interval #2
155 const int32_t max_serial_num = max_serial_;
156 const int32_t bottom = max_serial_num - (capacity_ - serial_num_);
157 return id >= bottom && bottom < max_serial_num;
158 }
159 }
160 ASSERT(wrapped_ == false);
161 return IsValidContiguous(id);
162 }
163
164 } // namespace dart
OLDNEW
« 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