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/gc_marker.cc

Issue 8761006: - Implement a simple old-generation marker. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years 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 | « vm/gc_marker.h ('k') | vm/heap.h » ('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) 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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "vm/gc_marker.h"
6
7 #include "vm/allocation.h"
8 #include "vm/isolate.h"
9 #include "vm/pages.h"
10 #include "vm/raw_object.h"
11 #include "vm/stack_frame.h"
12 #include "vm/visitor.h"
13
14 namespace dart {
15
16 // A simple chunked marking stack.
17 class MarkingStack : public ValueObject {
18 public:
19 MarkingStack()
20 : head_(new MarkingStackChunk()),
21 empty_chunks_(NULL),
22 marking_stack_(NULL),
23 top_(0) {
24 marking_stack_ = head_->MarkingStackChunkMemory();
25 }
26
27 ~MarkingStack() {
28 // TODO(iposva): Consider caching a couple emtpy marking stack chunks.
29 ASSERT(IsEmpty());
30 delete head_;
31 MarkingStackChunk* next;
32 while (empty_chunks_ != NULL) {
33 next = empty_chunks_->next();
34 delete empty_chunks_;
35 empty_chunks_ = next;
36 }
37 }
38
39 bool IsEmpty() const {
40 return IsMarkingStackChunkEmpty() && (head_->next() == NULL);
41 }
42
43 void Push(RawObject* value) {
44 ASSERT(!IsMarkingStackChunkFull());
45 marking_stack_[top_] = value;
46 top_++;
47 if (IsMarkingStackChunkFull()) {
48 MarkingStackChunk* new_chunk;
49 if (empty_chunks_ == NULL) {
50 new_chunk = new MarkingStackChunk();
51 } else {
52 new_chunk = empty_chunks_;
53 empty_chunks_ = new_chunk->next();
54 }
55 new_chunk->set_next(head_);
56 head_ = new_chunk;
57 marking_stack_ = head_->MarkingStackChunkMemory();
58 top_ = 0;
59 }
60 }
61
62 RawObject* Pop() {
63 ASSERT(head_ != NULL);
64 ASSERT(!IsEmpty());
65 if (IsMarkingStackChunkEmpty()) {
66 MarkingStackChunk* empty_chunk = head_;
67 head_ = head_->next();
68 empty_chunk->set_next(empty_chunks_);
69 empty_chunks_ = empty_chunk;
70 marking_stack_ = head_->MarkingStackChunkMemory();
71 top_ = MarkingStackChunk::kMarkingStackChunkSize;
72 }
73 top_--;
74 return marking_stack_[top_];
75 }
76
77 private:
78 class MarkingStackChunk {
79 public:
80 MarkingStackChunk() : next_(NULL) {}
81 ~MarkingStackChunk() {}
82
83 RawObject** MarkingStackChunkMemory() {
84 return &memory_[0];
85 }
86
87 MarkingStackChunk* next() const { return next_; }
88 void set_next(MarkingStackChunk* value) { next_ = value; }
89
90 static const uint32_t kMarkingStackChunkSize = 1024;
91
92 private:
93 RawObject* memory_[kMarkingStackChunkSize];
94 MarkingStackChunk* next_;
95
96 DISALLOW_COPY_AND_ASSIGN(MarkingStackChunk);
97 };
98
99 bool IsMarkingStackChunkFull() const {
100 return top_ == MarkingStackChunk::kMarkingStackChunkSize;
101 }
102
103 bool IsMarkingStackChunkEmpty() const {
104 return top_ == 0;
105 }
106
107 MarkingStackChunk* head_;
108 MarkingStackChunk* empty_chunks_;
109 RawObject** marking_stack_;
110 uint32_t top_;
111
112 DISALLOW_COPY_AND_ASSIGN(MarkingStack);
113 };
114
115
116 class MarkingVisitor : public ObjectPointerVisitor {
117 public:
118 MarkingVisitor(Heap* heap, PageSpace* page_space, MarkingStack* marking_stack)
119 : heap_(heap),
120 vm_heap_(Dart::vm_isolate()->heap()),
121 page_space_(page_space),
122 marking_stack_(marking_stack) {}
123
124 MarkingStack* marking_stack() const { return marking_stack_; }
125
126 void VisitPointers(RawObject** first, RawObject** last) {
127 for (RawObject** current = first; current <= last; current++) {
128 MarkObject(*current);
129 }
130 }
131
132 private:
133 void MarkAndPush(RawObject* raw_obj) {
134 ASSERT(raw_obj->IsHeapObject());
135
136 // Mark the object and push it on the marking stack.
137 ASSERT(!raw_obj->IsMarked());
138 RawClass* raw_class = raw_obj->ptr()->class_;
139 raw_obj->SetMarkBit();
140 marking_stack_->Push(raw_obj);
141
142 // TODO(iposva): Should we mark the classes early?
143 MarkObject(raw_class);
144 }
145
146 void MarkObject(RawObject* raw_obj) {
147 // Fast exit if the raw object is a Smi.
148 if (!raw_obj->IsHeapObject()) return;
149
150 // Fast exit if the raw object is marked.
151 if (raw_obj->IsMarked()) return;
152
153 // Skip over new objects, but verify consistency of heap while at it.
154 if (raw_obj->IsNewObject()) {
155 // TODO(iposva): Add consistency check.
156 return;
157 }
158
159 uword raw_addr = RawObject::ToAddr(raw_obj);
160 // TODO(iposva): Premark vm_isolate objects, to avoid this extra check here.
161 if (vm_heap_->Contains(raw_addr)) {
162 return;
163 }
164 // TODO(iposva): merge old and code spaces.
165 // ASSERT(page_space_->Contains(raw_addr));
166
167 MarkAndPush(raw_obj);
168 }
169
170 Heap* heap_;
171 Heap* vm_heap_;
172 PageSpace* page_space_;
173 MarkingStack* marking_stack_;
174
175 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor);
176 };
177
178
179 void GCMarker::Prologue(Isolate* isolate) {
180 // Nothing to do at the moment.
181 }
182
183
184 void GCMarker::IterateRoots(Isolate* isolate, MarkingVisitor* visitor) {
185 isolate->VisitObjectPointers(visitor,
186 StackFrameIterator::kDontValidateFrames);
187 heap_->IterateNewPointers(visitor);
188 }
189
190
191 void GCMarker::DrainMarkingStack(Isolate* isolate, MarkingVisitor* visitor) {
192 while (!visitor->marking_stack()->IsEmpty()) {
193 RawObject* raw_obj = visitor->marking_stack()->Pop();
194 raw_obj->VisitPointers(visitor);
195 }
196 }
197
198
199 void GCMarker::MarkObjects(Isolate* isolate, PageSpace* page_space) {
200 MarkingStack marking_stack;
201 Prologue(isolate);
202 MarkingVisitor mark(heap_, page_space, &marking_stack);
203 IterateRoots(isolate, &mark);
204 DrainMarkingStack(isolate, &mark);
205 }
206
207 } // namespace dart
OLDNEW
« no previous file with comments | « vm/gc_marker.h ('k') | vm/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698