114 void BFSClosure::process(const oop* reference, const oop pointee) { 115 closure_impl(reference, pointee); 116 } 117 void BFSClosure::closure_impl(const oop* reference, const oop pointee) { 118 assert(reference != NULL, "invariant"); 119 assert(UnifiedOop::dereference(reference) == pointee, "invariant"); 120 121 if (GranularTimer::is_finished()) { 122 return; 123 } 124 125 if (_use_dfs) { 126 assert(_current_parent != NULL, "invariant"); 127 DFSClosure::find_leaks_from_edge(_edge_store, _mark_bits, _current_parent); 128 return; 129 } 130 131 if (!_mark_bits->is_marked(pointee)) { 132 _mark_bits->mark_obj(pointee); 133 // is the pointee a sample object? 134 if (0 == pointee->mark().value()) { 135 add_chain(reference, pointee); 136 } 137 138 // if we are processinig initial root set, don't add to queue 139 if (_current_parent != NULL) { 140 _edge_queue->add(_current_parent, reference); 141 } 142 143 if (_edge_queue->is_full()) { 144 dfs_fallback(); 145 } 146 } 147 } 148 149 void BFSClosure::add_chain(const oop* reference, const oop pointee) { 150 assert(pointee != NULL, "invariant"); 151 assert(0 == pointee->mark().value(), "invariant"); 152 Edge leak_edge(_current_parent, reference); 153 _edge_store->put_chain(&leak_edge, _current_parent == NULL ? 1 : _current_frontier_level + 2); 154 } 155 156 void BFSClosure::dfs_fallback() { 157 assert(_edge_queue->is_full(), "invariant"); 158 _use_dfs = true; 159 _dfs_fallback_idx = _edge_queue->bottom(); 160 while (!_edge_queue->is_empty()) { 161 const Edge* edge = _edge_queue->remove(); 162 if (edge->pointee() != NULL) { 163 DFSClosure::find_leaks_from_edge(_edge_store, _mark_bits, edge); 164 } 165 } 166 } 167 168 void BFSClosure::process_queue() { 169 assert(_current_frontier_level == 0, "invariant"); 170 assert(_next_frontier_idx == 0, "invariant"); 171 assert(_prev_frontier_idx == 0, "invariant"); | 114 void BFSClosure::process(const oop* reference, const oop pointee) { 115 closure_impl(reference, pointee); 116 } 117 void BFSClosure::closure_impl(const oop* reference, const oop pointee) { 118 assert(reference != NULL, "invariant"); 119 assert(UnifiedOop::dereference(reference) == pointee, "invariant"); 120 121 if (GranularTimer::is_finished()) { 122 return; 123 } 124 125 if (_use_dfs) { 126 assert(_current_parent != NULL, "invariant"); 127 DFSClosure::find_leaks_from_edge(_edge_store, _mark_bits, _current_parent); 128 return; 129 } 130 131 if (!_mark_bits->is_marked(pointee)) { 132 _mark_bits->mark_obj(pointee); 133 // is the pointee a sample object? 134 if (NULL == pointee->mark().to_pointer()) { 135 add_chain(reference, pointee); 136 } 137 138 // if we are processinig initial root set, don't add to queue 139 if (_current_parent != NULL) { 140 _edge_queue->add(_current_parent, reference); 141 } 142 143 if (_edge_queue->is_full()) { 144 dfs_fallback(); 145 } 146 } 147 } 148 149 void BFSClosure::add_chain(const oop* reference, const oop pointee) { 150 assert(pointee != NULL, "invariant"); 151 assert(NULL == pointee->mark().to_pointer(), "invariant"); 152 Edge leak_edge(_current_parent, reference); 153 _edge_store->put_chain(&leak_edge, _current_parent == NULL ? 1 : _current_frontier_level + 2); 154 } 155 156 void BFSClosure::dfs_fallback() { 157 assert(_edge_queue->is_full(), "invariant"); 158 _use_dfs = true; 159 _dfs_fallback_idx = _edge_queue->bottom(); 160 while (!_edge_queue->is_empty()) { 161 const Edge* edge = _edge_queue->remove(); 162 if (edge->pointee() != NULL) { 163 DFSClosure::find_leaks_from_edge(_edge_store, _mark_bits, edge); 164 } 165 } 166 } 167 168 void BFSClosure::process_queue() { 169 assert(_current_frontier_level == 0, "invariant"); 170 assert(_next_frontier_idx == 0, "invariant"); 171 assert(_prev_frontier_idx == 0, "invariant"); |