8220601: ZGC: Delete ZNMethodTableEntry arrays using ZSafeDelete
Reviewed-by: stefank, eosterlund
--- a/src/hotspot/share/gc/z/zNMethodAllocator.cpp Mon Mar 18 11:50:41 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zArray.inline.hpp"
-#include "gc/z/zNMethodAllocator.hpp"
-#include "memory/allocation.hpp"
-
-ZArray<void*> ZNMethodAllocator::_deferred_frees;
-bool ZNMethodAllocator::_defer_frees(false);
-
-void ZNMethodAllocator::immediate_free(void* data) {
- FREE_C_HEAP_ARRAY(uint8_t, data);
-}
-
-void ZNMethodAllocator::deferred_free(void* data) {
- _deferred_frees.add(data);
-}
-
-void* ZNMethodAllocator::allocate(size_t size) {
- return NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
-}
-
-void ZNMethodAllocator::free(void* data) {
- if (data == NULL) {
- return;
- }
-
- if (_defer_frees) {
- deferred_free(data);
- } else {
- immediate_free(data);
- }
-}
-
-void ZNMethodAllocator::activate_deferred_frees() {
- assert(_deferred_frees.is_empty(), "precondition");
- _defer_frees = true;
-}
-
-void ZNMethodAllocator::deactivate_and_process_deferred_frees() {
- _defer_frees = false;
-
- ZArrayIterator<void*> iter(&_deferred_frees);
- for (void* data; iter.next(&data);) {
- immediate_free(data);
- }
- _deferred_frees.clear();
-}
--- a/src/hotspot/share/gc/z/zNMethodAllocator.hpp Mon Mar 18 11:50:41 2019 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2019, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
-#define SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
-
-#include "memory/allocation.hpp"
-#include "gc/z/zArray.hpp"
-
-class ZNMethodAllocator : public AllStatic {
-private:
- static ZArray<void*> _deferred_frees;
- static bool _defer_frees;
-
- static void immediate_free(void* data);
- static void deferred_free(void* data);
-
-public:
- static void* allocate(size_t size);
- static void free(void* data);
-
- static void activate_deferred_frees();
- static void deactivate_and_process_deferred_frees();
-};
-
-#endif // SHARE_GC_Z_ZNMETHODALLOCATOR_HPP
--- a/src/hotspot/share/gc/z/zNMethodTable.cpp Mon Mar 18 11:50:41 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTable.cpp Mon Mar 18 11:50:41 2019 +0100
@@ -30,12 +30,12 @@
#include "gc/z/zGlobals.hpp"
#include "gc/z/zHash.inline.hpp"
#include "gc/z/zLock.inline.hpp"
-#include "gc/z/zNMethodAllocator.hpp"
#include "gc/z/zNMethodData.hpp"
#include "gc/z/zNMethodTable.hpp"
#include "gc/z/zNMethodTableEntry.hpp"
#include "gc/z/zNMethodTableIteration.hpp"
#include "gc/z/zOopClosures.inline.hpp"
+#include "gc/z/zSafeDelete.inline.hpp"
#include "gc/z/zTask.hpp"
#include "gc/z/zWorkers.hpp"
#include "logging/log.hpp"
@@ -51,15 +51,7 @@
size_t ZNMethodTable::_nregistered = 0;
size_t ZNMethodTable::_nunregistered = 0;
ZNMethodTableIteration ZNMethodTable::_iteration;
-
-ZNMethodTableEntry* ZNMethodTable::create(size_t size) {
- void* const mem = ZNMethodAllocator::allocate(size * sizeof(ZNMethodTableEntry));
- return ::new (mem) ZNMethodTableEntry[size];
-}
-
-void ZNMethodTable::destroy(ZNMethodTableEntry* table) {
- ZNMethodAllocator::free(table);
-}
+ZSafeDelete<ZNMethodTableEntry[]> ZNMethodTable::_safe_delete;
size_t ZNMethodTable::first_index(const nmethod* nm, size_t size) {
assert(is_power_of_2(size), "Invalid size");
@@ -128,7 +120,7 @@
_nunregistered, percent_of(_nunregistered, _size), 0.0);
// Allocate new table
- ZNMethodTableEntry* const new_table = ZNMethodTable::create(new_size);
+ ZNMethodTableEntry* const new_table = new ZNMethodTableEntry[new_size];
// Transfer all registered entries
for (size_t i = 0; i < _size; i++) {
@@ -139,7 +131,7 @@
}
// Free old table
- ZNMethodTable::destroy(_table);
+ _safe_delete(_table);
// Install new table
_table = new_table;
@@ -219,8 +211,8 @@
void ZNMethodTable::nmethods_do_begin() {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- // Make sure we don't free data while iterating
- ZNMethodAllocator::activate_deferred_frees();
+ // Do not allow the table to be deleted while iterating
+ _safe_delete.enable_deferred_delete();
// Prepare iteration
_iteration.nmethods_do_begin(_table, _size);
@@ -232,8 +224,8 @@
// Finish iteration
_iteration.nmethods_do_end();
- // Process deferred frees
- ZNMethodAllocator::deactivate_and_process_deferred_frees();
+ // Allow the table to be deleted
+ _safe_delete.disable_deferred_delete();
// Notify iteration done
CodeCache_lock->notify_all();
--- a/src/hotspot/share/gc/z/zNMethodTable.hpp Mon Mar 18 11:50:41 2019 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTable.hpp Mon Mar 18 11:50:41 2019 +0100
@@ -25,6 +25,7 @@
#define SHARE_GC_Z_ZNMETHODTABLE_HPP
#include "gc/z/zNMethodTableIteration.hpp"
+#include "gc/z/zSafeDelete.hpp"
#include "memory/allocation.hpp"
class nmethod;
@@ -34,11 +35,12 @@
class ZNMethodTable : public AllStatic {
private:
- static ZNMethodTableEntry* _table;
- static size_t _size;
- static size_t _nregistered;
- static size_t _nunregistered;
- static ZNMethodTableIteration _iteration;
+ static ZNMethodTableEntry* _table;
+ static size_t _size;
+ static size_t _nregistered;
+ static size_t _nunregistered;
+ static ZNMethodTableIteration _iteration;
+ static ZSafeDelete<ZNMethodTableEntry[]> _safe_delete;
static ZNMethodTableEntry* create(size_t size);
static void destroy(ZNMethodTableEntry* table);