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

Side by Side Diff: runtime/vm/raw_object.cc

Issue 10450014: Request for comments on overall approach. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix scavenger and freelist handling Created 8 years, 7 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #include "vm/raw_object.h" 5 #include "vm/raw_object.h"
6 6
7 #include "vm/class_table.h" 7 #include "vm/class_table.h"
8 #include "vm/freelist.h" 8 #include "vm/freelist.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/object.h" 10 #include "vm/object.h"
11 #include "vm/visitor.h" 11 #include "vm/visitor.h"
12 12
13 13
14 namespace dart { 14 namespace dart {
15 15
16
17
18 RawClass* RawObject::GetClass(uword tags) {
19 if (FreeBit::decode(tags)) {
20 return FreeListElement::freelist_class();
21 } else {
22 return Isolate::Current()->class_table()->At(
23 ClassTag::decode(tags));
24 }
25 }
26
27
16 void RawObject::Validate(Isolate* isolate) const { 28 void RawObject::Validate(Isolate* isolate) const {
17 // Validation only happens in DEBUG builds. 29 // Validation only happens in DEBUG builds.
18 #if defined(DEBUG) 30 #if defined(DEBUG)
19 if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { 31 if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) {
20 // Validation relies on properly initialized class classes. Skip if the 32 // Validation relies on properly initialized class classes. Skip if the
21 // VM is still being initialized. 33 // VM is still being initialized.
22 return; 34 return;
23 } 35 }
24 // All Smi values are valid. 36 // All Smi values are valid.
25 if (!IsHeapObject()) { 37 if (!IsHeapObject()) {
26 return; 38 return;
27 } 39 }
28 // Validate that the class_ field is sensible.
29 RawClass* raw_class = ptr()->class_;
30 ASSERT(raw_class->IsHeapObject());
31 RawClass* raw_class_class = raw_class->ptr()->class_;
32 ASSERT(raw_class_class->IsHeapObject());
33 ASSERT(raw_class_class->ptr()->instance_kind_ == kClass);
34 40
35 // Validate that the tags_ field is sensible. 41 // Validate that the tags_ field is sensible.
36 uword tags = ptr()->tags_; 42 uword tags = ptr()->tags_;
37 ASSERT((tags & 0x000000f0) == 0); 43 ASSERT((tags & 0x000000f0) == 0);
38 intptr_t cid = ClassTag::decode(tags); 44 intptr_t cid = ClassTag::decode(tags);
39 RawClass* tag_class = isolate->class_table()->At(cid); 45 RawClass* raw_class = isolate->class_table()->At(cid);
40 ASSERT(tag_class == raw_class); 46 ASSERT(raw_class->IsHeapObject());
41 #endif 47 #endif
42 } 48 }
43 49
44 50
45 intptr_t RawObject::SizeFromClass() const { 51 intptr_t RawObject::SizeFromClass() const {
46 NoHandleScope no_handles(Isolate::Current()); 52 NoHandleScope no_handles(Isolate::Current());
47 53
48 // Only reasonable to be called on heap objects. 54 // Only reasonable to be called on heap objects.
49 ASSERT(IsHeapObject()); 55 ASSERT(IsHeapObject());
50 56
51 RawClass* raw_class = ptr()->class_; 57 RawClass* raw_class = GetClass();
52 intptr_t instance_size = raw_class->ptr()->instance_size_; 58 intptr_t instance_size = raw_class->ptr()->instance_size_;
53 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; 59 ObjectKind instance_kind = raw_class->ptr()->instance_kind_;
54 60
55 if (instance_size == 0) { 61 if (instance_size == 0) {
56 switch (instance_kind) { 62 switch (instance_kind) {
57 case kTokenStream: { 63 case kTokenStream: {
58 const RawTokenStream* raw_tokens = 64 const RawTokenStream* raw_tokens =
59 reinterpret_cast<const RawTokenStream*>(this); 65 reinterpret_cast<const RawTokenStream*>(this);
60 intptr_t tokens_length = Smi::Value(raw_tokens->ptr()->length_); 66 intptr_t tokens_length = Smi::Value(raw_tokens->ptr()->length_);
61 instance_size = TokenStream::InstanceSize(tokens_length); 67 instance_size = TokenStream::InstanceSize(tokens_length);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 const RawJSRegExp* raw_jsregexp = 237 const RawJSRegExp* raw_jsregexp =
232 reinterpret_cast<const RawJSRegExp*>(this); 238 reinterpret_cast<const RawJSRegExp*>(this);
233 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); 239 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_);
234 instance_size = JSRegExp::InstanceSize(data_length); 240 instance_size = JSRegExp::InstanceSize(data_length);
235 break; 241 break;
236 } 242 }
237 case kFreeListElement: { 243 case kFreeListElement: {
238 ASSERT(FreeBit::decode(ptr()->tags_)); 244 ASSERT(FreeBit::decode(ptr()->tags_));
239 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); 245 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
240 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); 246 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
241 instance_size = element->Size(); 247 instance_size = element->size();
242 break; 248 break;
243 } 249 }
244 default: 250 default:
245 UNREACHABLE(); 251 UNREACHABLE();
246 break; 252 break;
247 } 253 }
248 } 254 }
249 ASSERT(instance_size != 0); 255 ASSERT(instance_size != 0);
250 uword tags = ptr()->tags_; 256 uword tags = ptr()->tags_;
251 ASSERT((instance_size == SizeTag::decode(tags)) || 257 ASSERT((instance_size == SizeTag::decode(tags)) ||
252 (SizeTag::decode(tags) == 0) || 258 (SizeTag::decode(tags) == 0) ||
253 FreeBit::decode(tags)); 259 FreeBit::decode(tags));
254 return instance_size; 260 return instance_size;
255 } 261 }
256 262
257 263
258 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { 264 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) {
259 intptr_t size = 0; 265 intptr_t size = 0;
260 NoHandleScope no_handles(Isolate::Current()); 266 NoHandleScope no_handles(Isolate::Current());
261 267
262 // Only reasonable to be called on heap objects. 268 // Only reasonable to be called on heap objects.
263 ASSERT(IsHeapObject()); 269 ASSERT(IsHeapObject());
264 270
265 // Read the necessary data out of the class before visting the class itself. 271 // Read the necessary data out of the class before visiting the class itself.
266 RawClass* raw_class = ptr()->class_; 272 RawClass* raw_class = GetClass();
Ivan Posva 2012/05/26 04:34:46 The ObjectKind is equivalent to the instance_kind_
267 ObjectKind kind = raw_class->ptr()->instance_kind_; 273 ObjectKind kind = raw_class->ptr()->instance_kind_;
268 274
269 // Visit the class before visting the fields.
270 visitor->VisitPointer(reinterpret_cast<RawObject**>(&ptr()->class_));
271
272 switch (kind) { 275 switch (kind) {
273 #define RAW_VISITPOINTERS(clazz) \ 276 #define RAW_VISITPOINTERS(clazz) \
274 case clazz::kInstanceKind: { \ 277 case clazz::kInstanceKind: { \
275 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \ 278 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \
276 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \ 279 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \
277 break; \ 280 break; \
278 } 281 }
279 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS) 282 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS)
280 #undef RAW_VISITPOINTERS 283 #undef RAW_VISITPOINTERS
281 case kFreeListElement: { 284 case kFreeListElement: {
282 ASSERT(FreeBit::decode(ptr()->tags_)); 285 ASSERT(FreeBit::decode(ptr()->tags_));
283 // Nothing to visit for free list elements. 286 // Nothing to visit for free list elements.
284 uword addr = RawObject::ToAddr(this); 287 uword addr = RawObject::ToAddr(this);
285 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); 288 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
286 size = element->Size(); 289 size = element->size();
287 break; 290 break;
288 } 291 }
289 default: 292 default:
290 OS::Print("Kind: %d\n", kind); 293 OS::Print("Kind: %d\n", kind);
291 UNREACHABLE(); 294 UNREACHABLE();
292 break; 295 break;
293 } 296 }
294 297
295 ASSERT(size != 0); 298 ASSERT(size != 0);
296 ASSERT(size == Size()); 299 ASSERT(size == Size());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 435
433 intptr_t RawInstructions::VisitInstructionsPointers( 436 intptr_t RawInstructions::VisitInstructionsPointers(
434 RawInstructions* raw_obj, ObjectPointerVisitor* visitor) { 437 RawInstructions* raw_obj, ObjectPointerVisitor* visitor) {
435 RawInstructions* obj = raw_obj->ptr(); 438 RawInstructions* obj = raw_obj->ptr();
436 visitor->VisitPointer(reinterpret_cast<RawObject**>(&obj->code_)); 439 visitor->VisitPointer(reinterpret_cast<RawObject**>(&obj->code_));
437 return Instructions::InstanceSize(obj->size_); 440 return Instructions::InstanceSize(obj->size_);
438 } 441 }
439 442
440 443
441 bool RawInstructions::ContainsPC(RawObject* raw_obj, uword pc) { 444 bool RawInstructions::ContainsPC(RawObject* raw_obj, uword pc) {
442 RawClass* raw_class = raw_obj->ptr()->class_; 445 RawClass* raw_class = raw_obj->GetClass();
443 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; 446 ObjectKind instance_kind = raw_class->ptr()->instance_kind_;
444 if (instance_kind == kInstructions) { 447 if (instance_kind == kInstructions) {
Ivan Posva 2012/05/26 04:34:46 Just use the class id field here.
445 RawInstructions* raw_instr = reinterpret_cast<RawInstructions*>(raw_obj); 448 RawInstructions* raw_instr = reinterpret_cast<RawInstructions*>(raw_obj);
446 uword start_pc = 449 uword start_pc =
447 reinterpret_cast<uword>(raw_instr->ptr()) + Instructions::HeaderSize(); 450 reinterpret_cast<uword>(raw_instr->ptr()) + Instructions::HeaderSize();
448 uword end_pc = start_pc + raw_instr->ptr()->size_; 451 uword end_pc = start_pc + raw_instr->ptr()->size_;
449 ASSERT(end_pc > start_pc); 452 ASSERT(end_pc > start_pc);
450 if ((pc >= start_pc) && (pc < end_pc)) { 453 if ((pc >= start_pc) && (pc < end_pc)) {
451 return true; 454 return true;
452 } 455 }
453 } 456 }
454 return false; 457 return false;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 RawUnwindError* raw_obj, ObjectPointerVisitor* visitor) { 560 RawUnwindError* raw_obj, ObjectPointerVisitor* visitor) {
558 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); 561 visitor->VisitPointers(raw_obj->from(), raw_obj->to());
559 return UnwindError::InstanceSize(); 562 return UnwindError::InstanceSize();
560 } 563 }
561 564
562 565
563 intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj, 566 intptr_t RawInstance::VisitInstancePointers(RawInstance* raw_obj,
564 ObjectPointerVisitor* visitor) { 567 ObjectPointerVisitor* visitor) {
565 // Make sure that we got here with the tagged pointer as this. 568 // Make sure that we got here with the tagged pointer as this.
566 ASSERT(raw_obj->IsHeapObject()); 569 ASSERT(raw_obj->IsHeapObject());
567 RawInstance* obj = raw_obj->ptr(); 570 RawClass* raw_class = raw_obj->GetClass();
568 intptr_t instance_size = obj->class_->ptr()->instance_size_; 571 intptr_t instance_size = raw_class->ptr()->instance_size_;
569 intptr_t num_native_fields = obj->class_->ptr()->num_native_fields_; 572 intptr_t num_native_fields = raw_class->ptr()->num_native_fields_;
570 573
571 // Calculate the first and last raw object pointer fields. 574 // Calculate the first and last raw object pointer fields.
572 uword obj_addr = RawObject::ToAddr(raw_obj); 575 uword obj_addr = RawObject::ToAddr(raw_obj);
573 uword from = obj_addr + sizeof(RawObject) + num_native_fields * kWordSize; 576 uword from = obj_addr + sizeof(RawObject) + num_native_fields * kWordSize;
574 uword to = obj_addr + instance_size - kWordSize; 577 uword to = obj_addr + instance_size - kWordSize;
575 visitor->VisitPointers(reinterpret_cast<RawObject**>(from), 578 visitor->VisitPointers(reinterpret_cast<RawObject**>(from),
576 reinterpret_cast<RawObject**>(to)); 579 reinterpret_cast<RawObject**>(to));
577 return instance_size; 580 return instance_size;
578 } 581 }
579 582
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj, 938 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj,
936 ObjectPointerVisitor* visitor) { 939 ObjectPointerVisitor* visitor) {
937 // Make sure that we got here with the tagged pointer as this. 940 // Make sure that we got here with the tagged pointer as this.
938 ASSERT(raw_obj->IsHeapObject()); 941 ASSERT(raw_obj->IsHeapObject());
939 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_); 942 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_);
940 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); 943 visitor->VisitPointers(raw_obj->from(), raw_obj->to());
941 return JSRegExp::InstanceSize(length); 944 return JSRegExp::InstanceSize(length);
942 } 945 }
943 946
944 } // namespace dart 947 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698