blob: 856ae06b7b133bb126371b40fbc42b9eed43b176 [file] [log] [blame]
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00001// Copyright 2012 the V8 project authors. All rights reserved.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_OBJECTS_VISITING_INL_H_
29#define V8_OBJECTS_VISITING_INL_H_
30
31
32namespace v8 {
33namespace internal {
34
35template<typename StaticVisitor>
36void StaticNewSpaceVisitor<StaticVisitor>::Initialize() {
37 table_.Register(kVisitShortcutCandidate,
38 &FixedBodyVisitor<StaticVisitor,
39 ConsString::BodyDescriptor,
40 int>::Visit);
41
42 table_.Register(kVisitConsString,
43 &FixedBodyVisitor<StaticVisitor,
44 ConsString::BodyDescriptor,
45 int>::Visit);
46
47 table_.Register(kVisitSlicedString,
48 &FixedBodyVisitor<StaticVisitor,
49 SlicedString::BodyDescriptor,
50 int>::Visit);
51
52 table_.Register(kVisitFixedArray,
53 &FlexibleBodyVisitor<StaticVisitor,
54 FixedArray::BodyDescriptor,
55 int>::Visit);
56
57 table_.Register(kVisitFixedDoubleArray, &VisitFixedDoubleArray);
58
yangguo@chromium.org46839fb2012-08-28 09:06:19 +000059 table_.Register(kVisitNativeContext,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000060 &FixedBodyVisitor<StaticVisitor,
61 Context::ScavengeBodyDescriptor,
62 int>::Visit);
63
64 table_.Register(kVisitByteArray, &VisitByteArray);
65
66 table_.Register(kVisitSharedFunctionInfo,
67 &FixedBodyVisitor<StaticVisitor,
68 SharedFunctionInfo::BodyDescriptor,
69 int>::Visit);
70
71 table_.Register(kVisitSeqAsciiString, &VisitSeqAsciiString);
72
73 table_.Register(kVisitSeqTwoByteString, &VisitSeqTwoByteString);
74
erik.corry@gmail.comed49e962012-04-17 11:57:53 +000075 table_.Register(kVisitJSFunction, &VisitJSFunction);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000076
77 table_.Register(kVisitFreeSpace, &VisitFreeSpace);
78
79 table_.Register(kVisitJSWeakMap, &JSObjectVisitor::Visit);
80
81 table_.Register(kVisitJSRegExp, &JSObjectVisitor::Visit);
82
83 table_.template RegisterSpecializations<DataObjectVisitor,
84 kVisitDataObject,
85 kVisitDataObjectGeneric>();
86
87 table_.template RegisterSpecializations<JSObjectVisitor,
88 kVisitJSObject,
89 kVisitJSObjectGeneric>();
90 table_.template RegisterSpecializations<StructVisitor,
91 kVisitStruct,
92 kVisitStructGeneric>();
93}
94
95
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +000096template<typename StaticVisitor>
97void StaticMarkingVisitor<StaticVisitor>::Initialize() {
98 table_.Register(kVisitShortcutCandidate,
99 &FixedBodyVisitor<StaticVisitor,
100 ConsString::BodyDescriptor,
101 void>::Visit);
102
103 table_.Register(kVisitConsString,
104 &FixedBodyVisitor<StaticVisitor,
105 ConsString::BodyDescriptor,
106 void>::Visit);
107
108 table_.Register(kVisitSlicedString,
109 &FixedBodyVisitor<StaticVisitor,
110 SlicedString::BodyDescriptor,
111 void>::Visit);
112
113 table_.Register(kVisitFixedArray,
114 &FlexibleBodyVisitor<StaticVisitor,
115 FixedArray::BodyDescriptor,
116 void>::Visit);
117
118 table_.Register(kVisitFixedDoubleArray, &DataObjectVisitor::Visit);
119
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000120 table_.Register(kVisitNativeContext, &VisitNativeContext);
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000121
122 table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
123
124 table_.Register(kVisitFreeSpace, &DataObjectVisitor::Visit);
125
126 table_.Register(kVisitSeqAsciiString, &DataObjectVisitor::Visit);
127
128 table_.Register(kVisitSeqTwoByteString, &DataObjectVisitor::Visit);
129
130 table_.Register(kVisitJSWeakMap, &StaticVisitor::VisitJSWeakMap);
131
132 table_.Register(kVisitOddball,
133 &FixedBodyVisitor<StaticVisitor,
134 Oddball::BodyDescriptor,
135 void>::Visit);
136
danno@chromium.org2ab0c3b2012-10-05 08:50:56 +0000137 table_.Register(kVisitMap,
138 &FixedBodyVisitor<StaticVisitor,
139 Map::BodyDescriptor,
140 void>::Visit);
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000141
danno@chromium.org2ab0c3b2012-10-05 08:50:56 +0000142 table_.Register(kVisitCode, &StaticVisitor::VisitCode);
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000143
144 // Registration for kVisitSharedFunctionInfo is done by StaticVisitor.
145
146 // Registration for kVisitJSFunction is done by StaticVisitor.
147
148 // Registration for kVisitJSRegExp is done by StaticVisitor.
149
150 table_.Register(kVisitPropertyCell,
151 &FixedBodyVisitor<StaticVisitor,
152 JSGlobalPropertyCell::BodyDescriptor,
153 void>::Visit);
154
155 table_.template RegisterSpecializations<DataObjectVisitor,
156 kVisitDataObject,
157 kVisitDataObjectGeneric>();
158
159 table_.template RegisterSpecializations<JSObjectVisitor,
160 kVisitJSObject,
161 kVisitJSObjectGeneric>();
162
163 table_.template RegisterSpecializations<StructObjectVisitor,
164 kVisitStruct,
165 kVisitStructGeneric>();
166}
167
168
169template<typename StaticVisitor>
170void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry(
171 Heap* heap, Address entry_address) {
172 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
173 heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code);
174 StaticVisitor::MarkObject(heap, code);
175}
176
177
178template<typename StaticVisitor>
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000179void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer(
180 Heap* heap, RelocInfo* rinfo) {
181 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
182 ASSERT(!rinfo->target_object()->IsConsString());
183 HeapObject* object = HeapObject::cast(rinfo->target_object());
184 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object);
185 StaticVisitor::MarkObject(heap, object);
186}
187
188
189template<typename StaticVisitor>
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000190void StaticMarkingVisitor<StaticVisitor>::VisitGlobalPropertyCell(
191 Heap* heap, RelocInfo* rinfo) {
192 ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL);
193 JSGlobalPropertyCell* cell = rinfo->target_cell();
194 StaticVisitor::MarkObject(heap, cell);
195}
196
197
198template<typename StaticVisitor>
199void StaticMarkingVisitor<StaticVisitor>::VisitDebugTarget(
200 Heap* heap, RelocInfo* rinfo) {
201 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) &&
202 rinfo->IsPatchedReturnSequence()) ||
203 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
204 rinfo->IsPatchedDebugBreakSlotSequence()));
205 Code* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
206 heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
207 StaticVisitor::MarkObject(heap, target);
208}
209
210
211template<typename StaticVisitor>
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000212void StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget(
213 Heap* heap, RelocInfo* rinfo) {
214 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
215 Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
216 // Monomorphic ICs are preserved when possible, but need to be flushed
217 // when they might be keeping a Context alive, or when the heap is about
218 // to be serialized.
219 if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub()
danno@chromium.orgeb831462012-08-24 11:57:08 +0000220 && (target->ic_state() == MEGAMORPHIC || Serializer::enabled() ||
221 heap->isolate()->context_exit_happened() ||
222 target->ic_age() != heap->global_ic_age())) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000223 IC::Clear(rinfo->pc());
224 target = Code::GetCodeFromTargetAddress(rinfo->target_address());
225 }
226 heap->mark_compact_collector()->RecordRelocSlot(rinfo, target);
227 StaticVisitor::MarkObject(heap, target);
228}
229
230
231template<typename StaticVisitor>
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000232void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext(
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000233 Map* map, HeapObject* object) {
234 FixedBodyVisitor<StaticVisitor,
235 Context::MarkCompactBodyDescriptor,
236 void>::Visit(map, object);
237
238 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector();
239 for (int idx = Context::FIRST_WEAK_SLOT;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000240 idx < Context::NATIVE_CONTEXT_SLOTS;
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000241 ++idx) {
242 Object** slot =
243 HeapObject::RawField(object, FixedArray::OffsetOfElementAt(idx));
244 collector->RecordSlot(slot, slot, *slot);
245 }
246}
247
248
249template<typename StaticVisitor>
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000250void StaticMarkingVisitor<StaticVisitor>::VisitCode(
251 Map* map, HeapObject* object) {
252 Heap* heap = map->GetHeap();
253 Code* code = Code::cast(object);
254 if (FLAG_cleanup_code_caches_at_gc) {
255 code->ClearTypeFeedbackCells(heap);
256 }
257 code->CodeIterateBody<StaticVisitor>(heap);
258}
259
260
261template<typename StaticVisitor>
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +0000262void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(
263 Map* map, HeapObject* object) {
264 int last_property_offset =
265 JSRegExp::kSize + kPointerSize * map->inobject_properties();
danno@chromium.org2ab0c3b2012-10-05 08:50:56 +0000266 StaticVisitor::VisitPointers(map->GetHeap(),
267 HeapObject::RawField(object, JSRegExp::kPropertiesOffset),
268 HeapObject::RawField(object, last_property_offset));
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000269}
270
271
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000272void Code::CodeIterateBody(ObjectVisitor* v) {
273 int mode_mask = RelocInfo::kCodeTargetMask |
274 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
275 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
276 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
277 RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
278 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
279 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
280
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000281 // There are two places where we iterate code bodies: here and the
282 // templated CodeIterateBody (below). They should be kept in sync.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000283 IteratePointer(v, kRelocationInfoOffset);
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000284 IteratePointer(v, kHandlerTableOffset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000285 IteratePointer(v, kDeoptimizationDataOffset);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000286 IteratePointer(v, kTypeFeedbackInfoOffset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000287
288 RelocIterator it(this, mode_mask);
289 for (; !it.done(); it.next()) {
290 it.rinfo()->Visit(v);
291 }
292}
293
294
295template<typename StaticVisitor>
296void Code::CodeIterateBody(Heap* heap) {
297 int mode_mask = RelocInfo::kCodeTargetMask |
298 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
299 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
300 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
301 RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
302 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
303 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
304
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000305 // There are two places where we iterate code bodies: here and the
306 // non-templated CodeIterateBody (above). They should be kept in sync.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000307 StaticVisitor::VisitPointer(
308 heap,
309 reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset));
310 StaticVisitor::VisitPointer(
311 heap,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000312 reinterpret_cast<Object**>(this->address() + kHandlerTableOffset));
313 StaticVisitor::VisitPointer(
314 heap,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000315 reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset));
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000316 StaticVisitor::VisitPointer(
317 heap,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000318 reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000319
320 RelocIterator it(this, mode_mask);
321 for (; !it.done(); it.next()) {
322 it.rinfo()->template Visit<StaticVisitor>(heap);
323 }
324}
325
326
327} } // namespace v8::internal
328
329#endif // V8_OBJECTS_VISITING_INL_H_