OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 return GetVisitorIdForSize(kVisitStruct, | 204 return GetVisitorIdForSize(kVisitStruct, |
205 kVisitStructGeneric, | 205 kVisitStructGeneric, |
206 instance_size); | 206 instance_size); |
207 | 207 |
208 default: | 208 default: |
209 UNREACHABLE(); | 209 UNREACHABLE(); |
210 return kVisitorIdCount; | 210 return kVisitorIdCount; |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 | |
215 template <class T> | |
ulan
2014/04/07 07:42:19
Code from here to the end of file comes from heap.
| |
216 struct WeakListVisitor; | |
217 | |
218 | |
219 template <class T> | |
220 Object* VisitWeakList(Heap* heap, | |
221 Object* list, | |
222 WeakObjectRetainer* retainer, | |
223 bool record_slots) { | |
224 Object* undefined = heap->undefined_value(); | |
225 Object* head = undefined; | |
226 T* tail = NULL; | |
227 MarkCompactCollector* collector = heap->mark_compact_collector(); | |
228 while (list != undefined) { | |
229 // Check whether to keep the candidate in the list. | |
230 T* candidate = reinterpret_cast<T*>(list); | |
231 Object* retained = retainer->RetainAs(list); | |
232 if (retained != NULL) { | |
233 if (head == undefined) { | |
234 // First element in the list. | |
235 head = retained; | |
236 } else { | |
237 // Subsequent elements in the list. | |
238 ASSERT(tail != NULL); | |
239 WeakListVisitor<T>::SetWeakNext(tail, retained); | |
240 if (record_slots) { | |
241 Object** next_slot = | |
242 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset()); | |
243 collector->RecordSlot(next_slot, next_slot, retained); | |
244 } | |
245 } | |
246 // Retained object is new tail. | |
247 ASSERT(!retained->IsUndefined()); | |
248 candidate = reinterpret_cast<T*>(retained); | |
249 tail = candidate; | |
250 | |
251 | |
252 // tail is a live object, visit it. | |
253 WeakListVisitor<T>::VisitLiveObject( | |
254 heap, tail, retainer, record_slots); | |
255 } else { | |
256 WeakListVisitor<T>::VisitPhantomObject(heap, candidate); | |
257 } | |
258 | |
259 // Move to next element in the list. | |
260 list = WeakListVisitor<T>::WeakNext(candidate); | |
261 } | |
262 | |
263 // Terminate the list if there is one or more elements. | |
264 if (tail != NULL) { | |
265 WeakListVisitor<T>::SetWeakNext(tail, undefined); | |
266 } | |
267 return head; | |
268 } | |
269 | |
270 | |
271 template <class T> | |
272 static void ClearWeakList(Heap* heap, | |
273 Object* list) { | |
274 Object* undefined = heap->undefined_value(); | |
275 while (list != undefined) { | |
276 T* candidate = reinterpret_cast<T*>(list); | |
277 list = WeakListVisitor<T>::WeakNext(candidate); | |
278 WeakListVisitor<T>::SetWeakNext(candidate, undefined); | |
279 } | |
280 } | |
281 | |
282 | |
283 template<> | |
284 struct WeakListVisitor<JSFunction> { | |
285 static void SetWeakNext(JSFunction* function, Object* next) { | |
286 function->set_next_function_link(next); | |
287 } | |
288 | |
289 static Object* WeakNext(JSFunction* function) { | |
290 return function->next_function_link(); | |
291 } | |
292 | |
293 static int WeakNextOffset() { | |
294 return JSFunction::kNextFunctionLinkOffset; | |
295 } | |
296 | |
297 static void VisitLiveObject(Heap*, JSFunction*, | |
298 WeakObjectRetainer*, bool) { | |
299 } | |
300 | |
301 static void VisitPhantomObject(Heap*, JSFunction*) { | |
302 } | |
303 }; | |
304 | |
305 | |
306 template<> | |
307 struct WeakListVisitor<Code> { | |
308 static void SetWeakNext(Code* code, Object* next) { | |
309 code->set_next_code_link(next); | |
310 } | |
311 | |
312 static Object* WeakNext(Code* code) { | |
313 return code->next_code_link(); | |
314 } | |
315 | |
316 static int WeakNextOffset() { | |
317 return Code::kNextCodeLinkOffset; | |
318 } | |
319 | |
320 static void VisitLiveObject(Heap*, Code*, | |
321 WeakObjectRetainer*, bool) { | |
322 } | |
323 | |
324 static void VisitPhantomObject(Heap*, Code*) { | |
325 } | |
326 }; | |
327 | |
328 | |
329 template<> | |
330 struct WeakListVisitor<Context> { | |
331 static void SetWeakNext(Context* context, Object* next) { | |
332 context->set(Context::NEXT_CONTEXT_LINK, | |
333 next, | |
334 UPDATE_WRITE_BARRIER); | |
335 } | |
336 | |
337 static Object* WeakNext(Context* context) { | |
338 return context->get(Context::NEXT_CONTEXT_LINK); | |
339 } | |
340 | |
341 static void VisitLiveObject(Heap* heap, | |
342 Context* context, | |
343 WeakObjectRetainer* retainer, | |
344 bool record_slots) { | |
345 // Process the three weak lists linked off the context. | |
346 DoWeakList<JSFunction>(heap, context, retainer, record_slots, | |
347 Context::OPTIMIZED_FUNCTIONS_LIST); | |
348 DoWeakList<Code>(heap, context, retainer, record_slots, | |
349 Context::OPTIMIZED_CODE_LIST); | |
350 DoWeakList<Code>(heap, context, retainer, record_slots, | |
351 Context::DEOPTIMIZED_CODE_LIST); | |
352 } | |
353 | |
354 template<class T> | |
355 static void DoWeakList(Heap* heap, | |
356 Context* context, | |
357 WeakObjectRetainer* retainer, | |
358 bool record_slots, | |
359 int index) { | |
360 // Visit the weak list, removing dead intermediate elements. | |
361 Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer, | |
362 record_slots); | |
363 | |
364 // Update the list head. | |
365 context->set(index, list_head, UPDATE_WRITE_BARRIER); | |
366 | |
367 if (record_slots) { | |
368 // Record the updated slot if necessary. | |
369 Object** head_slot = HeapObject::RawField( | |
370 context, FixedArray::SizeFor(index)); | |
371 heap->mark_compact_collector()->RecordSlot( | |
372 head_slot, head_slot, list_head); | |
373 } | |
374 } | |
375 | |
376 static void VisitPhantomObject(Heap* heap, Context* context) { | |
377 ClearWeakList<JSFunction>(heap, | |
378 context->get(Context::OPTIMIZED_FUNCTIONS_LIST)); | |
379 ClearWeakList<Code>(heap, context->get(Context::OPTIMIZED_CODE_LIST)); | |
380 ClearWeakList<Code>(heap, context->get(Context::DEOPTIMIZED_CODE_LIST)); | |
381 } | |
382 | |
383 static int WeakNextOffset() { | |
384 return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK); | |
385 } | |
386 }; | |
387 | |
388 | |
389 template<> | |
390 struct WeakListVisitor<JSArrayBufferView> { | |
391 static void SetWeakNext(JSArrayBufferView* obj, Object* next) { | |
392 obj->set_weak_next(next); | |
393 } | |
394 | |
395 static Object* WeakNext(JSArrayBufferView* obj) { | |
396 return obj->weak_next(); | |
397 } | |
398 | |
399 static void VisitLiveObject(Heap*, | |
400 JSArrayBufferView* obj, | |
401 WeakObjectRetainer* retainer, | |
402 bool record_slots) {} | |
403 | |
404 static void VisitPhantomObject(Heap*, JSArrayBufferView*) {} | |
405 | |
406 static int WeakNextOffset() { | |
407 return JSArrayBufferView::kWeakNextOffset; | |
408 } | |
409 }; | |
410 | |
411 | |
412 template<> | |
413 struct WeakListVisitor<JSArrayBuffer> { | |
414 static void SetWeakNext(JSArrayBuffer* obj, Object* next) { | |
415 obj->set_weak_next(next); | |
416 } | |
417 | |
418 static Object* WeakNext(JSArrayBuffer* obj) { | |
419 return obj->weak_next(); | |
420 } | |
421 | |
422 static void VisitLiveObject(Heap* heap, | |
423 JSArrayBuffer* array_buffer, | |
424 WeakObjectRetainer* retainer, | |
425 bool record_slots) { | |
426 Object* typed_array_obj = | |
427 VisitWeakList<JSArrayBufferView>( | |
428 heap, | |
429 array_buffer->weak_first_view(), | |
430 retainer, record_slots); | |
431 array_buffer->set_weak_first_view(typed_array_obj); | |
432 if (typed_array_obj != heap->undefined_value() && record_slots) { | |
433 Object** slot = HeapObject::RawField( | |
434 array_buffer, JSArrayBuffer::kWeakFirstViewOffset); | |
435 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj); | |
436 } | |
437 } | |
438 | |
439 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) { | |
440 Runtime::FreeArrayBuffer(heap->isolate(), phantom); | |
441 } | |
442 | |
443 static int WeakNextOffset() { | |
444 return JSArrayBuffer::kWeakNextOffset; | |
445 } | |
446 }; | |
447 | |
448 | |
449 template<> | |
450 struct WeakListVisitor<AllocationSite> { | |
451 static void SetWeakNext(AllocationSite* obj, Object* next) { | |
452 obj->set_weak_next(next); | |
453 } | |
454 | |
455 static Object* WeakNext(AllocationSite* obj) { | |
456 return obj->weak_next(); | |
457 } | |
458 | |
459 static void VisitLiveObject(Heap* heap, | |
460 AllocationSite* site, | |
461 WeakObjectRetainer* retainer, | |
462 bool record_slots) {} | |
463 | |
464 static void VisitPhantomObject(Heap* heap, AllocationSite* phantom) {} | |
465 | |
466 static int WeakNextOffset() { | |
467 return AllocationSite::kWeakNextOffset; | |
468 } | |
469 }; | |
470 | |
471 | |
472 template Object* VisitWeakList<Code>( | |
473 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | |
474 | |
475 | |
476 template Object* VisitWeakList<JSFunction>( | |
477 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | |
478 | |
479 | |
480 template Object* VisitWeakList<Context>( | |
481 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | |
482 | |
483 | |
484 template Object* VisitWeakList<JSArrayBuffer>( | |
485 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | |
486 | |
487 | |
488 template Object* VisitWeakList<AllocationSite>( | |
489 Heap* heap, Object* list, WeakObjectRetainer* retainer, bool record_slots); | |
490 | |
214 } } // namespace v8::internal | 491 } } // namespace v8::internal |
OLD | NEW |