1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20/* 21 ThreadLocalCollector.h 22 Thread Local Collector 23 Copyright (c) 2008-2011 Apple Inc. All rights reserved. 24 */ 25 26#pragma once 27#ifndef __AUTO_THREAD_LOCAL_COLLECTOR__ 28#define __AUTO_THREAD_LOCAL_COLLECTOR__ 29 30#include "Definitions.h" 31#include "Range.h" 32#include "SubZone.h" 33#include "Zone.h" 34 35namespace Auto { 36 37 //----- Collector -----// 38 39 // 40 // Responsible for garbage collection. 41 // 42 43 class ThreadLocalCollector { 44 public: 45 46 private: 47 Zone *_zone; 48 Range _coverage; 49 void *_stack_bottom; 50 Sentinel _localsGuard; 51 LocalBlocksHash &_localBlocks; 52 void **_tlcBuffer; // local_allocations_size_limit entries, backing lives in Thread. Used for several purposes in TLC. 53 size_t _tlcBufferCount; 54 Thread &_thread; 55 56 PtrHashSet *_zombies; 57 58 void scan_stack_range(const Range &range); 59 void mark_push_block(void *block); 60 void scan_range(const Range &range); 61 void scan_with_layout(const Range &range, const unsigned char* map); 62 void scan_local_block(Subzone *subzone, usword_t q, void *block); 63 void scan_pending_until_done(); 64 void scan_marked_blocks(); 65 void scavenge_local(size_t count, void *garbage[]); 66 void process_local_garbage(void (*garbage_list_handler)(ThreadLocalCollector *)); 67 68 friend class thread_local_scanner_helper; 69 70 static void finalize_local_garbage_now(ThreadLocalCollector *tlc); 71 static void finalize_local_garbage_later(ThreadLocalCollector *tlc); 72 static void unmark_local_garbage(ThreadLocalCollector *tlc); 73 static void mark_local_garbage(void **garbage_list, size_t garbage_count); 74 void trace_scanning_phase_end(); 75 void append_block(void *block); 76 77 public: 78 79 ThreadLocalCollector(Zone *zone, void *current_stack_bottom, Thread &thread) 80 : _zone(zone), _coverage(zone->coverage()), _stack_bottom(current_stack_bottom), _localsGuard(thread.localsGuard()), _localBlocks(thread.locals()), 81 _tlcBuffer(thread.tlc_buffer()), _tlcBufferCount(0), _thread(thread), _zombies(NULL) 82 { 83 } 84 85 ~ThreadLocalCollector() 86 { 87 if (_zombies) 88 delete _zombies; 89 } 90 91 // 92 // should_collect 93 // 94 static bool should_collect(Zone *zone, Thread &thread, bool canFinalizeNow); 95 96 // 97 // should_collect_suspended 98 // 99 static bool should_collect_suspended(Thread &thread); 100 101 // 102 // collect 103 // 104 void collect(bool finalizeNow); 105 106 // 107 // collect_suspended 108 // 109 void collect_suspended(Range ®isters, Range &stack); 110 111 // 112 // reap_all 113 // 114 void reap_all(); 115 116 // 117 // eject_local_block 118 // 119 // removes block and all referenced stack local blocks 120 // 121 void eject_local_block(void *startingBlock); 122 123 // 124 // block_in_garbage_list 125 // 126 // searches the garbage list and returns true if block is in it 127 bool block_in_garbage_list(void *block); 128 129 // 130 // evict_local_garbage 131 // 132 // scans the list of garbage blocks. any non-garbage local blocks which are reachable are made global 133 void evict_local_garbage(); 134 135 // 136 // add_zombie 137 // 138 // adds block as a thread local zombie 139 void add_zombie(void *block); 140 141 // 142 // is_zombie 143 // 144 // test if a block is a thread local zombie 145 inline bool is_zombie(void *block); 146 }; 147}; 148 149#endif 150