Skip to content

Commit e8bc971

Browse files
author
Albert Noll
committed
8029799: vm/mlvm/anonloader/stress/oome prints warning: CodeHeap: # of free blocks > 10000
Double CodeCacheSegmentSize from 64 byte to 128 bytes if tiered compilation is enabled Reviewed-by: kvn, twisti
1 parent 87b278c commit e8bc971

File tree

6 files changed

+201
-168
lines changed

6 files changed

+201
-168
lines changed

hotspot/src/share/vm/code/codeCache.cpp

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,12 @@ CodeBlob* CodeCache::allocate(int size, bool is_critical) {
198198
}
199199
maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() -
200200
(address)_heap->low_boundary()) - unallocated_capacity());
201-
verify_if_often();
202201
print_trace("allocation", cb, size);
203202
return cb;
204203
}
205204

206205
void CodeCache::free(CodeBlob* cb) {
207206
assert_locked_or_safepoint(CodeCache_lock);
208-
verify_if_often();
209207

210208
print_trace("free", cb);
211209
if (cb->is_nmethod()) {
@@ -221,7 +219,6 @@ void CodeCache::free(CodeBlob* cb) {
221219

222220
_heap->deallocate(cb);
223221

224-
verify_if_often();
225222
assert(_number_of_blobs >= 0, "sanity check");
226223
}
227224

@@ -244,12 +241,6 @@ void CodeCache::commit(CodeBlob* cb) {
244241
}
245242

246243

247-
void CodeCache::flush() {
248-
assert_locked_or_safepoint(CodeCache_lock);
249-
Unimplemented();
250-
}
251-
252-
253244
// Iteration over CodeBlobs
254245

255246
#define FOR_ALL_BLOBS(var) for (CodeBlob *var = first() ; var != NULL; var = next(var) )
@@ -269,7 +260,7 @@ bool CodeCache::contains(void *p) {
269260
CodeBlob* CodeCache::find_blob(void* start) {
270261
CodeBlob* result = find_blob_unsafe(start);
271262
if (result == NULL) return NULL;
272-
// We could potientially look up non_entrant methods
263+
// We could potentially look up non_entrant methods
273264
guarantee(!result->is_zombie() || result->is_locked_by_vm() || is_error_reported(), "unsafe access to zombie method");
274265
return result;
275266
}
@@ -741,17 +732,26 @@ void CodeCache::report_codemem_full() {
741732
}
742733
}
743734

735+
void CodeCache::print_memory_overhead() {
736+
size_t wasted_bytes = 0;
737+
CodeBlob *cb;
738+
for (cb = first(); cb != NULL; cb = next(cb)) {
739+
HeapBlock* heap_block = ((HeapBlock*)cb) - 1;
740+
wasted_bytes += heap_block->length() * CodeCacheSegmentSize - cb->size();
741+
}
742+
// Print bytes that are allocated in the freelist
743+
ttyLocker ttl;
744+
tty->print_cr("Number of elements in freelist: %d", freelist_length());
745+
tty->print_cr("Allocated in freelist: %dkB", bytes_allocated_in_freelist()/K);
746+
tty->print_cr("Unused bytes in CodeBlobs: %dkB", (int)(wasted_bytes/K));
747+
tty->print_cr("Segment map size: %dkB", allocated_segments()/K); // 1 byte per segment
748+
}
749+
744750
//------------------------------------------------------------------------------------------------
745751
// Non-product version
746752

747753
#ifndef PRODUCT
748754

749-
void CodeCache::verify_if_often() {
750-
if (VerifyCodeCacheOften) {
751-
_heap->verify();
752-
}
753-
}
754-
755755
void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
756756
if (PrintCodeCache2) { // Need to add a new flag
757757
ResourceMark rm;
@@ -774,7 +774,7 @@ void CodeCache::print_internals() {
774774
int nmethodUnloaded = 0;
775775
int nmethodJava = 0;
776776
int nmethodNative = 0;
777-
int maxCodeSize = 0;
777+
int max_nm_size = 0;
778778
ResourceMark rm;
779779

780780
CodeBlob *cb;
@@ -798,13 +798,11 @@ void CodeCache::print_internals() {
798798
if(nm->is_not_entrant()) { nmethodNotEntrant++; }
799799
if(nm->is_zombie()) { nmethodZombie++; }
800800
if(nm->is_unloaded()) { nmethodUnloaded++; }
801-
if(nm->is_native_method()) { nmethodNative++; }
801+
if(nm->method() != NULL && nm->is_native_method()) { nmethodNative++; }
802802

803803
if(nm->method() != NULL && nm->is_java_method()) {
804804
nmethodJava++;
805-
if (nm->insts_size() > maxCodeSize) {
806-
maxCodeSize = nm->insts_size();
807-
}
805+
max_nm_size = MAX2(max_nm_size, nm->size());
808806
}
809807
} else if (cb->is_runtime_stub()) {
810808
runtimeStubCount++;
@@ -820,18 +818,19 @@ void CodeCache::print_internals() {
820818
}
821819

822820
int bucketSize = 512;
823-
int bucketLimit = maxCodeSize / bucketSize + 1;
821+
int bucketLimit = max_nm_size / bucketSize + 1;
824822
int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode);
825-
memset(buckets,0,sizeof(int) * bucketLimit);
823+
memset(buckets, 0, sizeof(int) * bucketLimit);
826824

827825
for (cb = first(); cb != NULL; cb = next(cb)) {
828826
if (cb->is_nmethod()) {
829827
nmethod* nm = (nmethod*)cb;
830828
if(nm->is_java_method()) {
831-
buckets[nm->insts_size() / bucketSize]++;
832-
}
829+
buckets[nm->size() / bucketSize]++;
830+
}
833831
}
834832
}
833+
835834
tty->print_cr("Code Cache Entries (total of %d)",total);
836835
tty->print_cr("-------------------------------------------------");
837836
tty->print_cr("nmethods: %d",nmethodCount);
@@ -858,6 +857,7 @@ void CodeCache::print_internals() {
858857
}
859858

860859
FREE_C_HEAP_ARRAY(int, buckets, mtCode);
860+
print_memory_overhead();
861861
}
862862

863863
#endif // !PRODUCT

hotspot/src/share/vm/code/codeCache.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ class CodeCache : AllStatic {
5858
static bool _needs_cache_clean;
5959
static nmethod* _scavenge_root_nmethods; // linked via nm->scavenge_root_link()
6060

61-
static void verify_if_often() PRODUCT_RETURN;
62-
6361
static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
6462
static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
6563

6664
static int _codemem_full_count;
65+
static size_t bytes_allocated_in_freelist() { return _heap->allocated_in_freelist(); }
66+
static int allocated_segments() { return _heap->allocated_segments(); }
67+
static size_t freelist_length() { return _heap->freelist_length(); }
6768

6869
public:
6970

@@ -78,7 +79,6 @@ class CodeCache : AllStatic {
7879
static int alignment_unit(); // guaranteed alignment of all CodeBlobs
7980
static int alignment_offset(); // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
8081
static void free(CodeBlob* cb); // frees a CodeBlob
81-
static void flush(); // flushes all CodeBlobs
8282
static bool contains(void *p); // returns whether p is included
8383
static void blobs_do(void f(CodeBlob* cb)); // iterates over all CodeBlobs
8484
static void blobs_do(CodeBlobClosure* f); // iterates over all CodeBlobs
@@ -150,6 +150,7 @@ class CodeCache : AllStatic {
150150
// Printing/debugging
151151
static void print(); // prints summary
152152
static void print_internals();
153+
static void print_memory_overhead();
153154
static void verify(); // verifies the code cache
154155
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
155156
static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage

0 commit comments

Comments
 (0)