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

Side by Side Diff: vm/raw_object.h

Issue 9072011: - Add a size field to the header. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 8 years, 11 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
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_RAW_OBJECT_H_ 5 #ifndef VM_RAW_OBJECT_H_
6 #define VM_RAW_OBJECT_H_ 6 #define VM_RAW_OBJECT_H_
7 7
8 #include "vm/assert.h" 8 #include "vm/assert.h"
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #include "vm/snapshot.h" 10 #include "vm/snapshot.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 kFreeListElement, 84 kFreeListElement,
85 kNumOfObjectKinds = kFreeListElement 85 kNumOfObjectKinds = kFreeListElement
86 }; 86 };
87 87
88 enum ObjectAlignment { 88 enum ObjectAlignment {
89 // Alignment offsets are used to determine object age. 89 // Alignment offsets are used to determine object age.
90 kNewObjectAlignmentOffset = kWordSize, 90 kNewObjectAlignmentOffset = kWordSize,
91 kOldObjectAlignmentOffset = 0, 91 kOldObjectAlignmentOffset = 0,
92 // Object sizes are aligned to kObjectAlignment. 92 // Object sizes are aligned to kObjectAlignment.
93 kObjectAlignment = 2 * kWordSize, 93 kObjectAlignment = 2 * kWordSize,
94 kObjectAlignmentLog2 = kWordSizeLog2 + 1,
94 kObjectAlignmentMask = kObjectAlignment - 1, 95 kObjectAlignmentMask = kObjectAlignment - 1,
95 }; 96 };
96 97
97 enum { 98 enum {
98 kSmiTag = 0, 99 kSmiTag = 0,
99 kHeapObjectTag = 1, 100 kHeapObjectTag = 1,
100 kSmiTagSize = 1, 101 kSmiTagSize = 1,
101 kSmiTagMask = 1, 102 kSmiTagMask = 1,
102 kSmiTagShift = 1, 103 kSmiTagShift = 1,
103 }; 104 };
(...skipping 22 matching lines...) Expand all
126 ASSERT(IsHeapObject()); \ 127 ASSERT(IsHeapObject()); \
127 return reinterpret_cast<Raw##object*>( \ 128 return reinterpret_cast<Raw##object*>( \
128 reinterpret_cast<uword>(this) - kHeapObjectTag); \ 129 reinterpret_cast<uword>(this) - kHeapObjectTag); \
129 } \ 130 } \
130 SNAPSHOT_WRITER_SUPPORT() \ 131 SNAPSHOT_WRITER_SUPPORT() \
131 132
132 133
133 // RawObject is the base class of all raw objects, even though it carries the 134 // RawObject is the base class of all raw objects, even though it carries the
134 // class_ field not all raw objects are allocated in the heap and thus cannot 135 // class_ field not all raw objects are allocated in the heap and thus cannot
135 // be dereferenced (e.g. RawSmi). 136 // be dereferenced (e.g. RawSmi).
136 //
137 // The tags field which is a part of the object header uses the following
138 // bit fields for storing tags.
139 //
140 // bit 0 - SmiTag
141 // bit 1 - Mark bit.
142 // bit 2 - Canonical object.
143 // bit 3 - Created from a full snapshot.
144 //
145 class RawObject { 137 class RawObject {
146 public: 138 public:
139 // The tags field which is a part of the object header uses the following
140 // bit fields for storing tags.
141 enum TagBits {
142 kFreeBit = 0,
143 kMarkBit = 1,
144 kCanonicalBit = 2,
145 kFromSnapshotBit = 3,
146 kReservedBit10K = 4,
147 kReservedBit100K = 5,
148 kReservedBit1M = 6,
149 kReservedBit10M = 7,
150 kSizeTagBit = 8,
151 kSizeTagSize = 8,
152 };
153
154 // Encodes the object size in the tag in units of object alignment.
155 class SizeTag {
156 public:
157 static const intptr_t kMaxSizeTag =
158 ((1 << RawObject::kSizeTagSize) - 1) << kObjectAlignmentLog2;
159
160 static uword encode(intptr_t size) {
161 return SizeBits::encode(SizeToTagValue(size));
162 }
163
164 static intptr_t decode(uword tag) {
165 return TagValueToSize(SizeBits::decode(tag));
166 }
167
168 static uword update(intptr_t size, uword tag) {
169 return SizeBits::update(SizeToTagValue(size), tag);
170 }
171
172 private:
173 // The actual unscaled bit field used within the tag field.
174 class SizeBits : public BitField<intptr_t, kSizeTagBit, kSizeTagSize> {};
175
176 static intptr_t SizeToTagValue(intptr_t size) {
177 ASSERT(Utils::IsAligned(size, kObjectAlignment));
178 return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2);
179 }
180 static intptr_t TagValueToSize(intptr_t value) {
181 return value << kObjectAlignmentLog2;
182 }
183 };
184
147 bool IsHeapObject() const { 185 bool IsHeapObject() const {
148 uword value = reinterpret_cast<uword>(this); 186 uword value = reinterpret_cast<uword>(this);
149 return (value & kSmiTagMask) == kHeapObjectTag; 187 return (value & kSmiTagMask) == kHeapObjectTag;
150 } 188 }
151 189
152 bool IsNewObject() const { 190 bool IsNewObject() const {
153 uword addr = reinterpret_cast<uword>(this); 191 uword addr = reinterpret_cast<uword>(this);
154 return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset; 192 return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
155 } 193 }
156 bool IsOldObject() const { 194 bool IsOldObject() const {
157 uword addr = reinterpret_cast<uword>(this); 195 uword addr = reinterpret_cast<uword>(this);
158 return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset; 196 return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
159 } 197 }
160 198
161 // Support for GC marking bit. 199 // Support for GC marking bit.
162 bool IsMarked() const { 200 bool IsMarked() const {
163 return MarkBit::decode(ptr()->tags_); 201 return MarkBit::decode(ptr()->tags_);
164 } 202 }
165 void SetMarkBit() { 203 void SetMarkBit() {
166 ASSERT(!IsMarked()); 204 ASSERT(!IsMarked());
167 intptr_t tags = ptr()->tags_; 205 uword tags = ptr()->tags_;
168 ptr()->tags_ = MarkBit::update(true, tags); 206 ptr()->tags_ = MarkBit::update(true, tags);
169 } 207 }
170 void ClearMarkBit() { 208 void ClearMarkBit() {
171 ASSERT(IsMarked()); 209 ASSERT(IsMarked());
172 intptr_t tags = ptr()->tags_; 210 uword tags = ptr()->tags_;
173 ptr()->tags_ = MarkBit::update(false, tags); 211 ptr()->tags_ = MarkBit::update(false, tags);
174 } 212 }
175 213
176 // Support for object tags. 214 // Support for object tags.
177 bool IsCanonical() const { 215 bool IsCanonical() const {
178 return CanonicalObjectTag::decode(ptr()->tags_); 216 return CanonicalObjectTag::decode(ptr()->tags_);
179 } 217 }
180 void SetCanonical() { 218 void SetCanonical() {
181 intptr_t tags = ptr()->tags_; 219 uword tags = ptr()->tags_;
182 ptr()->tags_ = CanonicalObjectTag::update(true, tags); 220 ptr()->tags_ = CanonicalObjectTag::update(true, tags);
183 } 221 }
184 bool IsCreatedFromSnapshot() { 222 bool IsCreatedFromSnapshot() const {
185 return CreatedFromSnapshotTag::decode(ptr()->tags_); 223 return CreatedFromSnapshotTag::decode(ptr()->tags_);
186 } 224 }
187 void SetCreatedFromSnapshot() { 225 void SetCreatedFromSnapshot() {
188 intptr_t tags = ptr()->tags_; 226 uword tags = ptr()->tags_;
189 ptr()->tags_ = CreatedFromSnapshotTag::update(true, tags); 227 ptr()->tags_ = CreatedFromSnapshotTag::update(true, tags);
190 } 228 }
191 229
230 intptr_t Size() const {
231 uword tags = ptr()->tags_;
232 intptr_t result = SizeTag::decode(tags);
233 if ((result != 0) && !FreeBit::decode(tags)) {
234 ASSERT(result == SizeFromClass());
235 return result;
236 }
237 result = SizeFromClass();
238 ASSERT((result > SizeTag::kMaxSizeTag) || FreeBit::decode(tags));
239 return result;
240 }
241
192 void Validate() const; 242 void Validate() const;
193 intptr_t Size() const;
194 intptr_t VisitPointers(ObjectPointerVisitor* visitor); 243 intptr_t VisitPointers(ObjectPointerVisitor* visitor);
195 244
196 static RawObject* FromAddr(uword addr) { 245 static RawObject* FromAddr(uword addr) {
197 // We expect the untagged address here. 246 // We expect the untagged address here.
198 ASSERT((addr & kSmiTagMask) != kHeapObjectTag); 247 ASSERT((addr & kSmiTagMask) != kHeapObjectTag);
199 return reinterpret_cast<RawObject*>(addr + kHeapObjectTag); 248 return reinterpret_cast<RawObject*>(addr + kHeapObjectTag);
200 } 249 }
201 250
202 static uword ToAddr(RawObject* raw_obj) { 251 static uword ToAddr(RawObject* raw_obj) {
203 return reinterpret_cast<uword>(raw_obj->ptr()); 252 return reinterpret_cast<uword>(raw_obj->ptr());
204 } 253 }
205 254
206 static bool IsCreatedFromSnapshot(intptr_t value) { 255 static bool IsCreatedFromSnapshot(intptr_t value) {
207 return CreatedFromSnapshotTag::decode(value); 256 return CreatedFromSnapshotTag::decode(value);
208 } 257 }
209 258
210 static bool IsCanonical(intptr_t value) { 259 static bool IsCanonical(intptr_t value) {
211 return CanonicalObjectTag::decode(value); 260 return CanonicalObjectTag::decode(value);
212 } 261 }
213 262
214 protected: 263 protected:
215 RawClass* class_; 264 RawClass* class_;
216 intptr_t tags_; // Various object tags (bits). 265 uword tags_; // Various object tags (bits).
217 266
218 private: 267 private:
219 enum { 268 class FreeBit : public BitField<bool, kFreeBit, 1> {};
220 kMarkBit = 1,
221 kCanonicalBit = 2,
222 kFromSnapshotBit = 3,
223 };
224 269
225 class MarkBit : public BitField<bool, kMarkBit, 1> {}; 270 class MarkBit : public BitField<bool, kMarkBit, 1> {};
226 271
227 class CanonicalObjectTag : public BitField<bool, kCanonicalBit, 1> {}; 272 class CanonicalObjectTag : public BitField<bool, kCanonicalBit, 1> {};
228 273
229 class CreatedFromSnapshotTag : public BitField<bool, kFromSnapshotBit, 1> {}; 274 class CreatedFromSnapshotTag : public BitField<bool, kFromSnapshotBit, 1> {};
230 275
231 RawObject* ptr() const { 276 RawObject* ptr() const {
232 ASSERT(IsHeapObject()); 277 ASSERT(IsHeapObject());
233 return reinterpret_cast<RawObject*>( 278 return reinterpret_cast<RawObject*>(
234 reinterpret_cast<uword>(this) - kHeapObjectTag); 279 reinterpret_cast<uword>(this) - kHeapObjectTag);
235 } 280 }
236 281
282 intptr_t SizeFromClass() const;
283
237 friend class Object; 284 friend class Object;
238 friend class Array; 285 friend class Array;
239 friend class SnapshotWriter; 286 friend class SnapshotWriter;
240 friend class SnapshotReader; 287 friend class SnapshotReader;
241 friend class MarkingVisitor; 288 friend class MarkingVisitor;
242 289
243 DISALLOW_ALLOCATION(); 290 DISALLOW_ALLOCATION();
244 DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject); 291 DISALLOW_IMPLICIT_CONSTRUCTORS(RawObject);
245 }; 292 };
246 293
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 intptr_t type_; // Uninitialized, simple or complex. 961 intptr_t type_; // Uninitialized, simple or complex.
915 intptr_t flags_; // Represents global/local, case insensitive, multiline. 962 intptr_t flags_; // Represents global/local, case insensitive, multiline.
916 963
917 // Variable length data follows here. 964 // Variable length data follows here.
918 uint8_t data_[0]; 965 uint8_t data_[0];
919 }; 966 };
920 967
921 } // namespace dart 968 } // namespace dart
922 969
923 #endif // VM_RAW_OBJECT_H_ 970 #endif // VM_RAW_OBJECT_H_
OLDNEW
« no previous file with comments | « vm/object.cc ('k') | vm/raw_object.cc » ('j') | vm/stub_code_x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698