Mercurial > hg > truffle
comparison src/share/vm/services/memoryManager.cpp @ 4092:b5a5f30c483d
7110173: GCNotifier::pushNotification publishes stale data.
Summary: GCNotifier::pushNotification() references GCMemoryManager::_last_gc_stat but is called from GCMemoryManager::gc_end() before GCMemoryManager::_last_gc_stat is set up using the values in GCMemoryManager::_current_gc_stat. As a result the GC notification code accesses unitialized or stale data. Move the notification call after GCMemoryManager::_las_gc_stat is set, but inside the same if-block.
Reviewed-by: poonam, dholmes, fparain, mchung
author | johnc |
---|---|
date | Mon, 21 Nov 2011 09:24:56 -0800 |
parents | 436b4a3231bf |
children | bf864f701a4a |
comparison
equal
deleted
inserted
replaced
4091:d06a2d7fcd5b | 4092:b5a5f30c483d |
---|---|
166 | 166 |
167 GCStatInfo::GCStatInfo(int num_pools) { | 167 GCStatInfo::GCStatInfo(int num_pools) { |
168 // initialize the arrays for memory usage | 168 // initialize the arrays for memory usage |
169 _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); | 169 _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); |
170 _after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); | 170 _after_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools); |
171 size_t len = num_pools * sizeof(MemoryUsage); | |
172 memset(_before_gc_usage_array, 0, len); | |
173 memset(_after_gc_usage_array, 0, len); | |
174 _usage_array_size = num_pools; | 171 _usage_array_size = num_pools; |
172 clear(); | |
175 } | 173 } |
176 | 174 |
177 GCStatInfo::~GCStatInfo() { | 175 GCStatInfo::~GCStatInfo() { |
178 FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array); | 176 FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array); |
179 FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array); | 177 FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array); |
302 | 300 |
303 // Compare with GC usage threshold | 301 // Compare with GC usage threshold |
304 pool->set_last_collection_usage(usage); | 302 pool->set_last_collection_usage(usage); |
305 LowMemoryDetector::detect_after_gc_memory(pool); | 303 LowMemoryDetector::detect_after_gc_memory(pool); |
306 } | 304 } |
307 if(is_notification_enabled()) { | 305 } |
308 bool isMajorGC = this == MemoryService::get_major_gc_manager(); | 306 |
309 GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC", | |
310 GCCause::to_string(cause)); | |
311 } | |
312 } | |
313 if (countCollection) { | 307 if (countCollection) { |
314 _num_collections++; | 308 _num_collections++; |
315 // alternately update two objects making one public when complete | 309 // alternately update two objects making one public when complete |
316 { | 310 { |
317 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag); | 311 MutexLockerEx ml(_last_gc_lock, Mutex::_no_safepoint_check_flag); |
318 GCStatInfo *tmp = _last_gc_stat; | 312 GCStatInfo *tmp = _last_gc_stat; |
319 _last_gc_stat = _current_gc_stat; | 313 _last_gc_stat = _current_gc_stat; |
320 _current_gc_stat = tmp; | 314 _current_gc_stat = tmp; |
321 // reset the current stat for diagnosability purposes | 315 // reset the current stat for diagnosability purposes |
322 _current_gc_stat->clear(); | 316 _current_gc_stat->clear(); |
317 } | |
318 | |
319 if (is_notification_enabled()) { | |
320 bool isMajorGC = this == MemoryService::get_major_gc_manager(); | |
321 GCNotifier::pushNotification(this, isMajorGC ? "end of major GC" : "end of minor GC", | |
322 GCCause::to_string(cause)); | |
323 } | 323 } |
324 } | 324 } |
325 } | 325 } |
326 | 326 |
327 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) { | 327 size_t GCMemoryManager::get_last_gc_stat(GCStatInfo* dest) { |