143 // dynamic type check. It consists of a counter which counts the total times |
149 // dynamic type check. It consists of a counter which counts the total times |
144 // that the check is reached, and a series of (klassOop, count) pairs |
150 // that the check is reached, and a series of (klassOop, count) pairs |
145 // which are used to store a type profile for the receiver of the check. |
151 // which are used to store a type profile for the receiver of the check. |
146 |
152 |
147 void ReceiverTypeData::follow_contents() { |
153 void ReceiverTypeData::follow_contents() { |
148 for (uint row = 0; row < row_limit(); row++) { |
154 // This is a set of weak references that need |
149 if (receiver(row) != NULL) { |
155 // to be followed at the end of the strong marking |
150 MarkSweep::mark_and_push(adr_receiver(row)); |
156 // phase. Memoize this object so it can be visited |
151 } |
157 // in the weak roots processing phase. |
152 } |
158 MarkSweep::revisit_mdo(data()); |
153 } |
159 } |
154 |
160 |
155 #ifndef SERIALGC |
161 #ifndef SERIALGC |
156 void ReceiverTypeData::follow_contents(ParCompactionManager* cm) { |
162 void ReceiverTypeData::follow_contents(ParCompactionManager* cm) { |
157 for (uint row = 0; row < row_limit(); row++) { |
163 // This is a set of weak references that need |
158 if (receiver(row) != NULL) { |
164 // to be followed at the end of the strong marking |
159 PSParallelCompact::mark_and_push(cm, adr_receiver(row)); |
165 // phase. Memoize this object so it can be visited |
160 } |
166 // in the weak roots processing phase. |
161 } |
167 PSParallelCompact::revisit_mdo(cm, data()); |
162 } |
168 } |
163 #endif // SERIALGC |
169 #endif // SERIALGC |
164 |
170 |
165 void ReceiverTypeData::oop_iterate(OopClosure* blk) { |
171 void ReceiverTypeData::oop_iterate(OopClosure* blk) { |
166 for (uint row = 0; row < row_limit(); row++) { |
172 if (blk->should_remember_mdo()) { |
167 if (receiver(row) != NULL) { |
173 // This is a set of weak references that need |
168 blk->do_oop(adr_receiver(row)); |
174 // to be followed at the end of the strong marking |
|
175 // phase. Memoize this object so it can be visited |
|
176 // in the weak roots processing phase. |
|
177 blk->remember_mdo(data()); |
|
178 } else { // normal scan |
|
179 for (uint row = 0; row < row_limit(); row++) { |
|
180 if (receiver(row) != NULL) { |
|
181 oop* adr = adr_receiver(row); |
|
182 blk->do_oop(adr); |
|
183 } |
169 } |
184 } |
170 } |
185 } |
171 } |
186 } |
172 |
187 |
173 void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) { |
188 void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) { |
|
189 // Currently, this interface is called only during card-scanning for |
|
190 // a young gen gc, in which case this object cannot contribute anything, |
|
191 // since it does not contain any references that cross out of |
|
192 // the perm gen. However, for future more general use we allow |
|
193 // the possibility of calling for instance from more general |
|
194 // iterators (for example, a future regionalized perm gen for G1, |
|
195 // or the possibility of moving some references out of perm in |
|
196 // the case of other collectors). In that case, you will need |
|
197 // to relax or remove some of the assertions below. |
|
198 #ifdef ASSERT |
|
199 // Verify that none of the embedded oop references cross out of |
|
200 // this generation. |
174 for (uint row = 0; row < row_limit(); row++) { |
201 for (uint row = 0; row < row_limit(); row++) { |
175 if (receiver(row) != NULL) { |
202 if (receiver(row) != NULL) { |
176 oop* adr = adr_receiver(row); |
203 oop* adr = adr_receiver(row); |
177 if (mr.contains(adr)) { |
204 CollectedHeap* h = Universe::heap(); |
178 blk->do_oop(adr); |
205 assert(h->is_permanent(adr) && h->is_permanent_or_null(*adr), "Not intra-perm"); |
|
206 } |
|
207 } |
|
208 #endif // ASSERT |
|
209 assert(!blk->should_remember_mdo(), "Not expected to remember MDO"); |
|
210 return; // Nothing to do, see comment above |
|
211 #if 0 |
|
212 if (blk->should_remember_mdo()) { |
|
213 // This is a set of weak references that need |
|
214 // to be followed at the end of the strong marking |
|
215 // phase. Memoize this object so it can be visited |
|
216 // in the weak roots processing phase. |
|
217 blk->remember_mdo(data()); |
|
218 } else { // normal scan |
|
219 for (uint row = 0; row < row_limit(); row++) { |
|
220 if (receiver(row) != NULL) { |
|
221 oop* adr = adr_receiver(row); |
|
222 if (mr.contains(adr)) { |
|
223 blk->do_oop(adr); |
|
224 } else if ((HeapWord*)adr >= mr.end()) { |
|
225 // Test that the current cursor and the two ends of the range |
|
226 // that we may have skipped iterating over are monotonically ordered; |
|
227 // this is just a paranoid assertion, just in case represetations |
|
228 // should change in the future rendering the short-circuit return |
|
229 // here invalid. |
|
230 assert((row+1 >= row_limit() || adr_receiver(row+1) > adr) && |
|
231 (row+2 >= row_limit() || adr_receiver(row_limit()-1) > adr_receiver(row+1)), "Reducing?"); |
|
232 break; // remaining should be outside this mr too |
|
233 } |
179 } |
234 } |
180 } |
235 } |
181 } |
236 } |
|
237 #endif |
182 } |
238 } |
183 |
239 |
184 void ReceiverTypeData::adjust_pointers() { |
240 void ReceiverTypeData::adjust_pointers() { |
185 for (uint row = 0; row < row_limit(); row++) { |
241 for (uint row = 0; row < row_limit(); row++) { |
186 if (receiver(row) != NULL) { |
242 if (receiver(row) != NULL) { |
187 MarkSweep::adjust_pointer(adr_receiver(row)); |
243 MarkSweep::adjust_pointer(adr_receiver(row)); |
|
244 } |
|
245 } |
|
246 } |
|
247 |
|
248 void ReceiverTypeData::follow_weak_refs(BoolObjectClosure* is_alive_cl) { |
|
249 for (uint row = 0; row < row_limit(); row++) { |
|
250 klassOop p = receiver(row); |
|
251 if (p != NULL && !is_alive_cl->do_object_b(p)) { |
|
252 clear_row(row); |
188 } |
253 } |
189 } |
254 } |
190 } |
255 } |
191 |
256 |
192 #ifndef SERIALGC |
257 #ifndef SERIALGC |
623 ProfileData* methodDataOopDesc::data_at(int data_index) { |
688 ProfileData* methodDataOopDesc::data_at(int data_index) { |
624 if (out_of_bounds(data_index)) { |
689 if (out_of_bounds(data_index)) { |
625 return NULL; |
690 return NULL; |
626 } |
691 } |
627 DataLayout* data_layout = data_layout_at(data_index); |
692 DataLayout* data_layout = data_layout_at(data_index); |
628 |
693 return data_layout->data_in(); |
629 switch (data_layout->tag()) { |
694 } |
|
695 |
|
696 ProfileData* DataLayout::data_in() { |
|
697 switch (tag()) { |
630 case DataLayout::no_tag: |
698 case DataLayout::no_tag: |
631 default: |
699 default: |
632 ShouldNotReachHere(); |
700 ShouldNotReachHere(); |
633 return NULL; |
701 return NULL; |
634 case DataLayout::bit_data_tag: |
702 case DataLayout::bit_data_tag: |
635 return new BitData(data_layout); |
703 return new BitData(this); |
636 case DataLayout::counter_data_tag: |
704 case DataLayout::counter_data_tag: |
637 return new CounterData(data_layout); |
705 return new CounterData(this); |
638 case DataLayout::jump_data_tag: |
706 case DataLayout::jump_data_tag: |
639 return new JumpData(data_layout); |
707 return new JumpData(this); |
640 case DataLayout::receiver_type_data_tag: |
708 case DataLayout::receiver_type_data_tag: |
641 return new ReceiverTypeData(data_layout); |
709 return new ReceiverTypeData(this); |
642 case DataLayout::virtual_call_data_tag: |
710 case DataLayout::virtual_call_data_tag: |
643 return new VirtualCallData(data_layout); |
711 return new VirtualCallData(this); |
644 case DataLayout::ret_data_tag: |
712 case DataLayout::ret_data_tag: |
645 return new RetData(data_layout); |
713 return new RetData(this); |
646 case DataLayout::branch_data_tag: |
714 case DataLayout::branch_data_tag: |
647 return new BranchData(data_layout); |
715 return new BranchData(this); |
648 case DataLayout::multi_branch_data_tag: |
716 case DataLayout::multi_branch_data_tag: |
649 return new MultiBranchData(data_layout); |
717 return new MultiBranchData(this); |
650 case DataLayout::arg_info_data_tag: |
718 case DataLayout::arg_info_data_tag: |
651 return new ArgInfoData(data_layout); |
719 return new ArgInfoData(this); |
652 }; |
720 }; |
653 } |
721 } |
654 |
722 |
655 // Iteration over data. |
723 // Iteration over data. |
656 ProfileData* methodDataOopDesc::next_data(ProfileData* current) { |
724 ProfileData* methodDataOopDesc::next_data(ProfileData* current) { |