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

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 // Maximum positive smi on 32-bit architecture.
12 #define ID_MAX 0x3FFFFFFF
Ivan Posva 2013/07/10 01:10:13 Probably better as a const int32_t kIdMax in class
Cutch 2013/07/10 17:23:10 Done.
13
14 void ObjectIdRing::Init(Isolate* isolate, int32_t capacity) {
15 ObjectIdRing* ring = new ObjectIdRing(isolate, capacity);
16 if (isolate != NULL) {
Ivan Posva 2013/07/10 01:10:13 In which case would the isolate be NULL?
Cutch 2013/07/10 17:23:10 In a unit test.
17 isolate->set_object_id_ring(ring);
18 }
19 }
20
21
22 ObjectIdRing::~ObjectIdRing() {
23 ASSERT(table_ != NULL);
24 free(table_);
25 table_ = NULL;
26 if (isolate_ != NULL) {
27 isolate_->set_object_id_ring(NULL);
28 isolate_ = NULL;
29 }
30 }
31
32
33 int32_t ObjectIdRing::GetIdForObject(RawObject* object) {
34 return AllocateNewId(object);
35 }
36
37
38 RawObject* ObjectIdRing::GetObjectForId(int32_t id) {
39 int32_t index = IndexOfId(id);
40 if (index == kInvalidId) {
41 return Object::null();
42 }
43 ASSERT(index >= 0);
44 ASSERT(index < capacity_);
45 return table_[index];
46 }
47
48
49 ObjectIdRing::ObjectIdRing(Isolate* isolate, int32_t capacity) {
50 ASSERT(capacity > 0);
51 isolate_ = isolate;
52 capacity_ = capacity;
53 serial_num_ = 0;
54 wrapped_ = false;
55 RawObject* sizer = NULL;
56 const size_t table_size = sizeof(sizer)*capacity_;
Ivan Posva 2013/07/10 01:10:13 kWordSize * capacity_ or even better use calloc be
Cutch 2013/07/10 17:23:10 Done.
57 table_ = reinterpret_cast<RawObject**>(malloc(table_size));
58 for (int i = 0; i < capacity_; i++) {
59 table_[i] = Object::null();
60 }
61 // The maximum serial number is a multiple of the capacity, so that when
62 // the serial number wraps, the index into table_ wraps with it.
63 max_serial_ = ID_MAX - (ID_MAX % capacity_);
64 }
65
66
67 int32_t ObjectIdRing::NextSerial() {
68 int32_t r = serial_num_;
69 serial_num_++;
70 if (serial_num_ >= max_serial_) {
71 serial_num_ = 0;
72 wrapped_ = true;
73 }
74 return r;
75 }
76
77
78 int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
79 ASSERT(raw_obj->IsHeapObject());
80 int32_t id = NextSerial();
81 ASSERT(id != kInvalidId);
82 int32_t cursor = IndexOfId(id);
83 ASSERT(cursor != kInvalidId);
84 if (table_[cursor] != Object::null()) {
85 // Free old handle.
86 table_[cursor] = Object::null();
87 }
88 ASSERT(table_[cursor] == Object::null());
89 table_[cursor] = raw_obj;
90 return id;
91 }
92
93
94 int32_t ObjectIdRing::IndexOfId(int32_t id) {
95 if (!IsValidId(id)) {
96 return kInvalidId;
97 }
98 ASSERT((id >= 0) && (id < max_serial_));
99 return id % capacity_;
100 }
101
102
103 bool ObjectIdRing::IsValidContiguous(int32_t id) {
104 ASSERT(id != kInvalidId);
105 ASSERT((id >= 0) && (id < max_serial_));
106 if (id >= serial_num_) {
107 // Too large.
108 return false;
109 }
110 int32_t bottom = 0;
111 if (serial_num_ >= capacity_) {
112 bottom = serial_num_ - capacity_;
113 }
114 return id >= bottom;
115 }
116
117
118 bool ObjectIdRing::IsValidId(int32_t id) {
119 if (id == kInvalidId) {
120 return false;
121 }
122 if (id >= max_serial_) {
123 return false;
124 }
125 ASSERT((id >= 0) && (id < max_serial_));
126 if (wrapped_) {
127 // Serial number has wrapped around to 0.
128 if (serial_num_ >= capacity_) {
129 // Serial number is larger than capacity, the serial
130 // numbers are contiguous again.
131 wrapped_ = false;
132 return IsValidContiguous(id);
133 } else {
134 // When the serial number first wraps, the valid serial number range
135 // spans two intervals:
136 // #1 [0, serial_num_)
137 // #2 [max_serial_ - (capacity_ - serial_num), max_serial_)
138 //
139 // Check for both.
140 if (id < serial_num_) {
141 // Interval #1
142 return true;
143 }
144 // Interval #2
145 const int32_t max_serial_num = max_serial_;
146 const int32_t bottom = max_serial_num - (capacity_ - serial_num_);
147 return id >= bottom && bottom < max_serial_num;
148 }
149 }
150 ASSERT(wrapped_ == false);
151 return IsValidContiguous(id);
152 }
153
154 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698