1.1 --- a/src/share/vm/oops/methodDataOop.cpp Mon Aug 31 05:27:29 2009 -0700 1.2 +++ b/src/share/vm/oops/methodDataOop.cpp Wed Sep 02 00:04:29 2009 -0700 1.3 @@ -49,6 +49,12 @@ 1.4 } 1.5 } 1.6 1.7 +void DataLayout::follow_weak_refs(BoolObjectClosure* cl) { 1.8 + ResourceMark m; 1.9 + data_in()->follow_weak_refs(cl); 1.10 +} 1.11 + 1.12 + 1.13 // ================================================================== 1.14 // ProfileData 1.15 // 1.16 @@ -145,42 +151,92 @@ 1.17 // which are used to store a type profile for the receiver of the check. 1.18 1.19 void ReceiverTypeData::follow_contents() { 1.20 - for (uint row = 0; row < row_limit(); row++) { 1.21 - if (receiver(row) != NULL) { 1.22 - MarkSweep::mark_and_push(adr_receiver(row)); 1.23 - } 1.24 - } 1.25 + // This is a set of weak references that need 1.26 + // to be followed at the end of the strong marking 1.27 + // phase. Memoize this object so it can be visited 1.28 + // in the weak roots processing phase. 1.29 + MarkSweep::revisit_mdo(data()); 1.30 } 1.31 1.32 #ifndef SERIALGC 1.33 void ReceiverTypeData::follow_contents(ParCompactionManager* cm) { 1.34 - for (uint row = 0; row < row_limit(); row++) { 1.35 - if (receiver(row) != NULL) { 1.36 - PSParallelCompact::mark_and_push(cm, adr_receiver(row)); 1.37 - } 1.38 - } 1.39 + // This is a set of weak references that need 1.40 + // to be followed at the end of the strong marking 1.41 + // phase. Memoize this object so it can be visited 1.42 + // in the weak roots processing phase. 1.43 + PSParallelCompact::revisit_mdo(cm, data()); 1.44 } 1.45 #endif // SERIALGC 1.46 1.47 void ReceiverTypeData::oop_iterate(OopClosure* blk) { 1.48 - for (uint row = 0; row < row_limit(); row++) { 1.49 - if (receiver(row) != NULL) { 1.50 - blk->do_oop(adr_receiver(row)); 1.51 - } 1.52 - } 1.53 -} 1.54 - 1.55 -void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) { 1.56 - for (uint row = 0; row < row_limit(); row++) { 1.57 - if (receiver(row) != NULL) { 1.58 - oop* adr = adr_receiver(row); 1.59 - if (mr.contains(adr)) { 1.60 + if (blk->should_remember_mdo()) { 1.61 + // This is a set of weak references that need 1.62 + // to be followed at the end of the strong marking 1.63 + // phase. Memoize this object so it can be visited 1.64 + // in the weak roots processing phase. 1.65 + blk->remember_mdo(data()); 1.66 + } else { // normal scan 1.67 + for (uint row = 0; row < row_limit(); row++) { 1.68 + if (receiver(row) != NULL) { 1.69 + oop* adr = adr_receiver(row); 1.70 blk->do_oop(adr); 1.71 } 1.72 } 1.73 } 1.74 } 1.75 1.76 +void ReceiverTypeData::oop_iterate_m(OopClosure* blk, MemRegion mr) { 1.77 + // Currently, this interface is called only during card-scanning for 1.78 + // a young gen gc, in which case this object cannot contribute anything, 1.79 + // since it does not contain any references that cross out of 1.80 + // the perm gen. However, for future more general use we allow 1.81 + // the possibility of calling for instance from more general 1.82 + // iterators (for example, a future regionalized perm gen for G1, 1.83 + // or the possibility of moving some references out of perm in 1.84 + // the case of other collectors). In that case, you will need 1.85 + // to relax or remove some of the assertions below. 1.86 +#ifdef ASSERT 1.87 + // Verify that none of the embedded oop references cross out of 1.88 + // this generation. 1.89 + for (uint row = 0; row < row_limit(); row++) { 1.90 + if (receiver(row) != NULL) { 1.91 + oop* adr = adr_receiver(row); 1.92 + CollectedHeap* h = Universe::heap(); 1.93 + assert(h->is_permanent(adr) && h->is_permanent_or_null(*adr), "Not intra-perm"); 1.94 + } 1.95 + } 1.96 +#endif // ASSERT 1.97 + assert(!blk->should_remember_mdo(), "Not expected to remember MDO"); 1.98 + return; // Nothing to do, see comment above 1.99 +#if 0 1.100 + if (blk->should_remember_mdo()) { 1.101 + // This is a set of weak references that need 1.102 + // to be followed at the end of the strong marking 1.103 + // phase. Memoize this object so it can be visited 1.104 + // in the weak roots processing phase. 1.105 + blk->remember_mdo(data()); 1.106 + } else { // normal scan 1.107 + for (uint row = 0; row < row_limit(); row++) { 1.108 + if (receiver(row) != NULL) { 1.109 + oop* adr = adr_receiver(row); 1.110 + if (mr.contains(adr)) { 1.111 + blk->do_oop(adr); 1.112 + } else if ((HeapWord*)adr >= mr.end()) { 1.113 + // Test that the current cursor and the two ends of the range 1.114 + // that we may have skipped iterating over are monotonically ordered; 1.115 + // this is just a paranoid assertion, just in case represetations 1.116 + // should change in the future rendering the short-circuit return 1.117 + // here invalid. 1.118 + assert((row+1 >= row_limit() || adr_receiver(row+1) > adr) && 1.119 + (row+2 >= row_limit() || adr_receiver(row_limit()-1) > adr_receiver(row+1)), "Reducing?"); 1.120 + break; // remaining should be outside this mr too 1.121 + } 1.122 + } 1.123 + } 1.124 + } 1.125 +#endif 1.126 +} 1.127 + 1.128 void ReceiverTypeData::adjust_pointers() { 1.129 for (uint row = 0; row < row_limit(); row++) { 1.130 if (receiver(row) != NULL) { 1.131 @@ -189,6 +245,15 @@ 1.132 } 1.133 } 1.134 1.135 +void ReceiverTypeData::follow_weak_refs(BoolObjectClosure* is_alive_cl) { 1.136 + for (uint row = 0; row < row_limit(); row++) { 1.137 + klassOop p = receiver(row); 1.138 + if (p != NULL && !is_alive_cl->do_object_b(p)) { 1.139 + clear_row(row); 1.140 + } 1.141 + } 1.142 +} 1.143 + 1.144 #ifndef SERIALGC 1.145 void ReceiverTypeData::update_pointers() { 1.146 for (uint row = 0; row < row_limit(); row++) { 1.147 @@ -625,30 +690,33 @@ 1.148 return NULL; 1.149 } 1.150 DataLayout* data_layout = data_layout_at(data_index); 1.151 + return data_layout->data_in(); 1.152 +} 1.153 1.154 - switch (data_layout->tag()) { 1.155 +ProfileData* DataLayout::data_in() { 1.156 + switch (tag()) { 1.157 case DataLayout::no_tag: 1.158 default: 1.159 ShouldNotReachHere(); 1.160 return NULL; 1.161 case DataLayout::bit_data_tag: 1.162 - return new BitData(data_layout); 1.163 + return new BitData(this); 1.164 case DataLayout::counter_data_tag: 1.165 - return new CounterData(data_layout); 1.166 + return new CounterData(this); 1.167 case DataLayout::jump_data_tag: 1.168 - return new JumpData(data_layout); 1.169 + return new JumpData(this); 1.170 case DataLayout::receiver_type_data_tag: 1.171 - return new ReceiverTypeData(data_layout); 1.172 + return new ReceiverTypeData(this); 1.173 case DataLayout::virtual_call_data_tag: 1.174 - return new VirtualCallData(data_layout); 1.175 + return new VirtualCallData(this); 1.176 case DataLayout::ret_data_tag: 1.177 - return new RetData(data_layout); 1.178 + return new RetData(this); 1.179 case DataLayout::branch_data_tag: 1.180 - return new BranchData(data_layout); 1.181 + return new BranchData(this); 1.182 case DataLayout::multi_branch_data_tag: 1.183 - return new MultiBranchData(data_layout); 1.184 + return new MultiBranchData(this); 1.185 case DataLayout::arg_info_data_tag: 1.186 - return new ArgInfoData(data_layout); 1.187 + return new ArgInfoData(this); 1.188 }; 1.189 } 1.190