8141421: Various test fail with OOME on win x86
Summary: Fix memory overuse in g1CodeCacheRemset
Reviewed-by: tschatzl, mgerdin
--- a/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Thu Jan 28 14:58:57 2016 +0300
+++ b/hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp Fri Jan 22 06:13:52 2016 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -74,10 +74,16 @@
static size_t static_mem_size() {
return sizeof(_purge_list);
}
+
+ size_t mem_size();
};
CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
+size_t CodeRootSetTable::mem_size() {
+ return sizeof(CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
+}
+
CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
unsigned int hash = compute_hash(nm);
Entry* entry = (Entry*) new_entry_free_list();
@@ -232,7 +238,6 @@
OrderAccess::release_store_ptr(&_table, temp);
}
-
void G1CodeRootSet::purge() {
CodeRootSetTable::purge();
}
@@ -247,12 +252,13 @@
allocate_small_table();
}
added = _table->add(method);
- if (_length == Threshold) {
- move_to_large();
- }
if (added) {
+ if (_length == Threshold) {
+ move_to_large();
+ }
++_length;
}
+ assert(_length == (size_t)_table->number_of_entries(), "sizes should match");
}
bool G1CodeRootSet::remove(nmethod* method) {
@@ -266,11 +272,13 @@
clear();
}
}
+ assert((_length == 0 && _table == NULL) ||
+ (_length == (size_t)_table->number_of_entries()), "sizes should match");
return removed;
}
bool G1CodeRootSet::contains(nmethod* method) {
- CodeRootSetTable* table = load_acquire_table();
+ CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
if (table != NULL) {
return table->contains(method);
}
@@ -284,8 +292,7 @@
}
size_t G1CodeRootSet::mem_size() {
- return sizeof(*this) +
- (_table != NULL ? sizeof(CodeRootSetTable) + _table->entry_size() * _length : 0);
+ return sizeof(*this) + (_table != NULL ? _table->mem_size() : 0);
}
void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const {
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Jan 28 14:58:57 2016 +0300
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Fri Jan 22 06:13:52 2016 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -785,6 +785,9 @@
void HeapRegionRemSet::add_strong_code_root(nmethod* nm) {
assert(nm != NULL, "sanity");
+ assert((!CodeCache_lock->owned_by_self() || SafepointSynchronize::is_at_safepoint()),
+ "should call add_strong_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s",
+ BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()));
// Optimistic unlocked contains-check
if (!_code_roots.contains(nm)) {
MutexLockerEx ml(&_m, Mutex::_no_safepoint_check_flag);
@@ -794,6 +797,12 @@
void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) {
assert(nm != NULL, "sanity");
+ assert((CodeCache_lock->owned_by_self() ||
+ (SafepointSynchronize::is_at_safepoint() &&
+ (_m.owned_by_self() || Thread::current()->is_VM_thread()))),
+ "not safely locked. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s, _m.owned_by_self(): %s, Thread::current()->is_VM_thread(): %s",
+ BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),
+ BOOL_TO_STR(_m.owned_by_self()), BOOL_TO_STR(Thread::current()->is_VM_thread()));
_code_roots.add(nm);
}