67 // 68 // This method is pretty bulky. It would be nice to split it up 69 // into smaller submethods, but we need to be careful not to hurt 70 // performance. 71 // 72 template<bool promote_immediately> 73 oop PSPromotionManager::copy_to_survivor_space(oop o) { 74 assert(PSScavenge::should_scavenge(&o), "Sanity"); 75 76 oop new_obj = NULL; 77 78 // NOTE! We must be very careful with any methods that access the mark 79 // in o. There may be multiple threads racing on it, and it may be forwarded 80 // at any time. Do not use oop methods for accessing the mark! 81 markOop test_mark = o->mark(); 82 83 // The same test as "o->is_forwarded()" 84 if (!test_mark->is_marked()) { 85 bool new_obj_is_tenured = false; 86 size_t new_obj_size = o->size(); 87 88 if (!promote_immediately) { 89 // Find the objects age, MT safe. 90 uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ? 91 test_mark->displaced_mark_helper()->age() : test_mark->age(); 92 93 // Try allocating obj in to-space (unless too old) 94 if (age < PSScavenge::tenuring_threshold()) { 95 new_obj = (oop) _young_lab.allocate(new_obj_size); 96 if (new_obj == NULL && !_young_gen_is_full) { 97 // Do we allocate directly, or flush and refill? 98 if (new_obj_size > (YoungPLABSize / 2)) { 99 // Allocate this object directly 100 new_obj = (oop)young_space()->cas_allocate(new_obj_size); 101 } else { 102 // Flush and fill 103 _young_lab.flush(); 104 105 HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize); 106 if (lab_base != NULL) { 107 _young_lab.initialize(MemRegion(lab_base, YoungPLABSize)); 108 // Try the young lab allocation again. 109 new_obj = (oop) _young_lab.allocate(new_obj_size); 110 } else { 111 _young_gen_is_full = true; 112 } 113 } 114 } 115 } 116 } 117 118 // Otherwise try allocating obj tenured 119 if (new_obj == NULL) { 120 #ifndef PRODUCT 121 if (Universe::heap()->promotion_should_fail()) { 122 return oop_promotion_failed(o, test_mark); 123 } 124 #endif // #ifndef PRODUCT 125 126 new_obj = (oop) _old_lab.allocate(new_obj_size); 127 new_obj_is_tenured = true; 128 129 if (new_obj == NULL) { 130 if (!_old_gen_is_full) { 131 // Do we allocate directly, or flush and refill? 132 if (new_obj_size > (OldPLABSize / 2)) { 133 // Allocate this object directly 134 new_obj = (oop)old_gen()->cas_allocate(new_obj_size); 135 } else { 136 // Flush and fill 137 _old_lab.flush(); 138 139 HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize); 140 if(lab_base != NULL) { 141 #ifdef ASSERT 142 // Delay the initialization of the promotion lab (plab). 143 // This exposes uninitialized plabs to card table processing. 144 if (GCWorkerDelayMillis > 0) { 145 os::sleep(Thread::current(), GCWorkerDelayMillis, false); 146 } 147 #endif 148 _old_lab.initialize(MemRegion(lab_base, OldPLABSize)); 149 // Try the old lab allocation again. 150 new_obj = (oop) _old_lab.allocate(new_obj_size); 151 } 152 } 153 } 154 155 // This is the promotion failed test, and code handling. 156 // The code belongs here for two reasons. It is slightly 157 // different than the code below, and cannot share the 158 // CAS testing code. Keeping the code here also minimizes 159 // the impact on the common case fast path code. 160 161 if (new_obj == NULL) { 162 _old_gen_is_full = true; 163 return oop_promotion_failed(o, test_mark); 164 } 165 } 166 } 167 168 assert(new_obj != NULL, "allocation should have succeeded"); 169 170 // Copy obj | 67 // 68 // This method is pretty bulky. It would be nice to split it up 69 // into smaller submethods, but we need to be careful not to hurt 70 // performance. 71 // 72 template<bool promote_immediately> 73 oop PSPromotionManager::copy_to_survivor_space(oop o) { 74 assert(PSScavenge::should_scavenge(&o), "Sanity"); 75 76 oop new_obj = NULL; 77 78 // NOTE! We must be very careful with any methods that access the mark 79 // in o. There may be multiple threads racing on it, and it may be forwarded 80 // at any time. Do not use oop methods for accessing the mark! 81 markOop test_mark = o->mark(); 82 83 // The same test as "o->is_forwarded()" 84 if (!test_mark->is_marked()) { 85 bool new_obj_is_tenured = false; 86 size_t new_obj_size = o->size(); 87 // Find the objects age, MT safe. 88 uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ? 89 test_mark->displaced_mark_helper()->age() : test_mark->age(); 90 91 if (!promote_immediately) { 92 // Try allocating obj in to-space (unless too old) 93 if (age < PSScavenge::tenuring_threshold()) { 94 new_obj = (oop) _young_lab.allocate(new_obj_size); 95 if (new_obj == NULL && !_young_gen_is_full) { 96 // Do we allocate directly, or flush and refill? 97 if (new_obj_size > (YoungPLABSize / 2)) { 98 // Allocate this object directly 99 new_obj = (oop)young_space()->cas_allocate(new_obj_size); 100 if (new_obj != NULL) { 101 PSScavenge::gc_tracer()->report_promotion_outside_plab_event(o, 102 new_obj_size, 103 age, 104 false); 105 } 106 } else { 107 // Flush and fill 108 _young_lab.flush(); 109 110 HeapWord* lab_base = young_space()->cas_allocate(YoungPLABSize); 111 if (lab_base != NULL) { 112 _young_lab.initialize(MemRegion(lab_base, YoungPLABSize)); 113 // Try the young lab allocation again. 114 new_obj = (oop) _young_lab.allocate(new_obj_size); 115 if (new_obj != NULL) { 116 size_t lab_size = pointer_delta(_young_lab.end(), _young_lab.bottom()); 117 PSScavenge::gc_tracer()->report_promotion_in_new_plab_event(o, 118 new_obj_size, 119 age, 120 false, 121 lab_size); 122 } 123 } else { 124 _young_gen_is_full = true; 125 } 126 } 127 } 128 } 129 } 130 131 // Otherwise try allocating obj tenured 132 if (new_obj == NULL) { 133 #ifndef PRODUCT 134 if (Universe::heap()->promotion_should_fail()) { 135 return oop_promotion_failed(o, test_mark); 136 } 137 #endif // #ifndef PRODUCT 138 139 new_obj = (oop) _old_lab.allocate(new_obj_size); 140 new_obj_is_tenured = true; 141 142 if (new_obj == NULL) { 143 if (!_old_gen_is_full) { 144 // Do we allocate directly, or flush and refill? 145 if (new_obj_size > (OldPLABSize / 2)) { 146 // Allocate this object directly 147 new_obj = (oop)old_gen()->cas_allocate(new_obj_size); 148 if (new_obj != NULL) { 149 PSScavenge::gc_tracer()->report_promotion_outside_plab_event(o, 150 new_obj_size, 151 age, 152 true); 153 } 154 } else { 155 // Flush and fill 156 _old_lab.flush(); 157 158 HeapWord* lab_base = old_gen()->cas_allocate(OldPLABSize); 159 if(lab_base != NULL) { 160 #ifdef ASSERT 161 // Delay the initialization of the promotion lab (plab). 162 // This exposes uninitialized plabs to card table processing. 163 if (GCWorkerDelayMillis > 0) { 164 os::sleep(Thread::current(), GCWorkerDelayMillis, false); 165 } 166 #endif 167 _old_lab.initialize(MemRegion(lab_base, OldPLABSize)); 168 // Try the old lab allocation again. 169 new_obj = (oop) _old_lab.allocate(new_obj_size); 170 if (new_obj != NULL) { 171 size_t lab_size = pointer_delta(_old_lab.end(), _old_lab.bottom()); 172 PSScavenge::gc_tracer()->report_promotion_in_new_plab_event(o, 173 new_obj_size, 174 age, 175 true, 176 lab_size); 177 } 178 } 179 } 180 } 181 182 // This is the promotion failed test, and code handling. 183 // The code belongs here for two reasons. It is slightly 184 // different than the code below, and cannot share the 185 // CAS testing code. Keeping the code here also minimizes 186 // the impact on the common case fast path code. 187 188 if (new_obj == NULL) { 189 _old_gen_is_full = true; 190 return oop_promotion_failed(o, test_mark); 191 } 192 } 193 } 194 195 assert(new_obj != NULL, "allocation should have succeeded"); 196 197 // Copy obj |