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

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