--- /dev/null 2019-02-14 11:31:37.500399000 +0100 +++ new/src/hotspot/share/gc/z/zNMethodData.cpp 2019-02-21 09:29:27.251019910 +0100 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017, 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/zLock.inline.hpp" +#include "gc/z/zNMethodAllocator.hpp" +#include "gc/z/zNMethodData.hpp" +#include "memory/allocation.hpp" +#include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" +#include "utilities/align.hpp" +#include "utilities/debug.hpp" +#include "utilities/growableArray.hpp" + +size_t ZNMethodDataOops::header_size() { + const size_t size = sizeof(ZNMethodDataOops); + assert(is_aligned(size, sizeof(oop*)), "Header misaligned"); + return size; +} + +ZNMethodDataOops* ZNMethodDataOops::create(const GrowableArray& immediates, bool has_non_immediates) { + // Allocate memory for the ZNMethodDataOops object + // plus the immediate oop* array that follows right after. + const size_t size = ZNMethodDataOops::header_size() + (sizeof(oop*) * immediates.length()); + void* const mem = ZNMethodAllocator::allocate(size); + return ::new (mem) ZNMethodDataOops(immediates, has_non_immediates); +} + +void ZNMethodDataOops::destroy(ZNMethodDataOops* oops) { + ZNMethodAllocator::free(oops); +} + +ZNMethodDataOops::ZNMethodDataOops(const GrowableArray& immediates, bool has_non_immediates) : + _nimmediates(immediates.length()), + _has_non_immediates(has_non_immediates) { + // Save all immediate oops + for (size_t i = 0; i < _nimmediates; i++) { + immediates_begin()[i] = immediates.at(i); + } +} + +size_t ZNMethodDataOops::immediates_count() const { + return _nimmediates; +} + +oop** ZNMethodDataOops::immediates_begin() const { + // The immediate oop* array starts immediately after this object + return (oop**)((uintptr_t)this + header_size()); +} + +oop** ZNMethodDataOops::immediates_end() const { + return immediates_begin() + immediates_count(); +} + +bool ZNMethodDataOops::has_non_immediates() const { + return _has_non_immediates; +} + +ZNMethodData* ZNMethodData::create(nmethod* nm) { + void* const mem = ZNMethodAllocator::allocate(sizeof(ZNMethodData)); + return ::new (mem) ZNMethodData(nm); +} + +void ZNMethodData::destroy(ZNMethodData* data) { + ZNMethodAllocator::free(data->oops()); + ZNMethodAllocator::free(data); +} + +ZNMethodData::ZNMethodData(nmethod* nm) : + _lock(), + _oops(NULL) {} + +ZReentrantLock* ZNMethodData::lock() { + return &_lock; +} + +ZNMethodDataOops* ZNMethodData::oops() const { + return OrderAccess::load_acquire(&_oops); +} + +ZNMethodDataOops* ZNMethodData::swap_oops(ZNMethodDataOops* new_oops) { + return Atomic::xchg(new_oops, &_oops); +}