# HG changeset patch # User dlong # Date 1497374862 25200 # Node ID 7107dccce2b27013d68f86ae81c7655c6b65b490 # Parent 29467418d0ca072ae090f52070681e2aa1abeade 8181757: NonNMethod heap in segmented CodeCache is not scanned in some cases 8171365: nsk/jvmti/scenarios/events/EM04/em04t001: many errors for missed events Reviewed-by: thartmann, kvn diff -r 29467418d0ca -r 7107dccce2b2 src/share/vm/code/codeCache.cpp --- a/src/share/vm/code/codeCache.cpp Fri Jun 02 11:26:36 2017 +0200 +++ b/src/share/vm/code/codeCache.cpp Tue Jun 13 10:27:42 2017 -0700 @@ -130,6 +130,7 @@ // Iterate over all CodeHeaps #define FOR_ALL_HEAPS(heap) for (GrowableArrayIterator heap = _heaps->begin(); heap != _heaps->end(); ++heap) #define FOR_ALL_NMETHOD_HEAPS(heap) for (GrowableArrayIterator heap = _nmethod_heaps->begin(); heap != _nmethod_heaps->end(); ++heap) +#define FOR_ALL_ALLOCABLE_HEAPS(heap) for (GrowableArrayIterator heap = _allocable_heaps->begin(); heap != _allocable_heaps->end(); ++heap) // Iterate over all CodeBlobs (cb) on the given CodeHeap #define FOR_ALL_BLOBS(cb, heap) for (CodeBlob* cb = first_blob(heap); cb != NULL; cb = next_blob(heap, cb)) @@ -140,10 +141,11 @@ bool CodeCache::_needs_cache_clean = false; nmethod* CodeCache::_scavenge_root_nmethods = NULL; -// Initialize array of CodeHeaps +// Initialize arrays of CodeHeap subsets GrowableArray* CodeCache::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, true); GrowableArray* CodeCache::_compiled_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, true); GrowableArray* CodeCache::_nmethod_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, true); +GrowableArray* CodeCache::_allocable_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray (CodeBlobType::All, true); void CodeCache::check_heap_sizes(size_t non_nmethod_size, size_t profiled_size, size_t non_profiled_size, size_t cache_size, bool all_set) { size_t total_size = non_nmethod_size + profiled_size + non_profiled_size; @@ -338,6 +340,7 @@ return rs; } +// Heaps available for allocation bool CodeCache::heap_available(int code_blob_type) { if (!SegmentedCodeCache) { // No segmentation: use a single code heap @@ -391,6 +394,9 @@ if (code_blob_type_accepts_nmethod(type)) { _nmethod_heaps->insert_sorted(heap); } + if (code_blob_type_accepts_allocable(type)) { + _allocable_heaps->insert_sorted(heap); + } } void CodeCache::add_heap(ReservedSpace rs, const char* name, int code_blob_type) { @@ -620,7 +626,7 @@ void CodeCache::blobs_do(void f(CodeBlob* nm)) { assert_locked_or_safepoint(CodeCache_lock); - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_HEAPS(heap) { FOR_ALL_BLOBS(cb, *heap) { f(cb); } @@ -663,7 +669,7 @@ void CodeCache::blobs_do(CodeBlobClosure* f) { assert_locked_or_safepoint(CodeCache_lock); - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { FOR_ALL_BLOBS(cb, *heap) { if (cb->is_alive()) { f->do_code_blob(cb); @@ -960,7 +966,7 @@ size_t CodeCache::capacity() { size_t cap = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { cap += (*heap)->capacity(); } return cap; @@ -973,7 +979,7 @@ size_t CodeCache::unallocated_capacity() { size_t unallocated_cap = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { unallocated_cap += (*heap)->unallocated_capacity(); } return unallocated_cap; @@ -981,7 +987,7 @@ size_t CodeCache::max_capacity() { size_t max_cap = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { max_cap += (*heap)->max_capacity(); } return max_cap; @@ -1007,7 +1013,7 @@ size_t CodeCache::bytes_allocated_in_freelists() { size_t allocated_bytes = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { allocated_bytes += (*heap)->allocated_in_freelist(); } return allocated_bytes; @@ -1015,7 +1021,7 @@ int CodeCache::allocated_segments() { int number_of_segments = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { number_of_segments += (*heap)->allocated_segments(); } return number_of_segments; @@ -1023,7 +1029,7 @@ size_t CodeCache::freelists_length() { size_t length = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { length += (*heap)->freelist_length(); } return length; @@ -1354,7 +1360,7 @@ void CodeCache::print_memory_overhead() { size_t wasted_bytes = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { CodeHeap* curr_heap = *heap; for (CodeBlob* cb = (CodeBlob*)curr_heap->first(); cb != NULL; cb = (CodeBlob*)curr_heap->next(cb)) { HeapBlock* heap_block = ((HeapBlock*)cb) - 1; @@ -1400,7 +1406,7 @@ ResourceMark rm; int i = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { if ((_nmethod_heaps->length() >= 1) && Verbose) { tty->print_cr("-- %s --", (*heap)->name()); } @@ -1497,7 +1503,7 @@ CodeBlob_sizes live; CodeBlob_sizes dead; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { FOR_ALL_BLOBS(cb, *heap) { if (!cb->is_alive()) { dead.add(cb); @@ -1523,7 +1529,7 @@ int number_of_blobs = 0; int number_of_oop_maps = 0; int map_size = 0; - FOR_ALL_NMETHOD_HEAPS(heap) { + FOR_ALL_ALLOCABLE_HEAPS(heap) { FOR_ALL_BLOBS(cb, *heap) { if (cb->is_alive()) { number_of_blobs++; diff -r 29467418d0ca -r 7107dccce2b2 src/share/vm/code/codeCache.hpp --- a/src/share/vm/code/codeCache.hpp Fri Jun 02 11:26:36 2017 +0200 +++ b/src/share/vm/code/codeCache.hpp Tue Jun 13 10:27:42 2017 -0700 @@ -85,6 +85,7 @@ static GrowableArray* _heaps; static GrowableArray* _compiled_heaps; static GrowableArray* _nmethod_heaps; + static GrowableArray* _allocable_heaps; static address _low_bound; // Lower bound of CodeHeap addresses static address _high_bound; // Upper bound of CodeHeap addresses @@ -237,6 +238,11 @@ return type == CodeBlobType::All || type <= CodeBlobType::MethodProfiled; } + static bool code_blob_type_accepts_allocable(int type) { + return type <= CodeBlobType::All; + } + + // Returns the CodeBlobType for the given compilation level static int get_code_blob_type(int comp_level) { if (comp_level == CompLevel_none ||