Path: blob/master/src/hotspot/share/jfr/writers/jfrStorageAdapter.hpp
41152 views
/*1* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_JFR_WRITERS_JFRSTORAGEADAPTER_HPP25#define SHARE_JFR_WRITERS_JFRSTORAGEADAPTER_HPP2627#include "jfr/utilities/jfrAllocation.hpp"2829class Thread;3031//32// The adapters present writers with a uniform interface over storage.33//34// Adapter policy35//36// StorageType* storage();37// const u1* start() const;38// const u1* pos();39// const u1* end() const;40// void commit(u1* position);41// bool flush(size_t used, size_t requested);42// void release();43//4445template <typename Flush>46class Adapter {47public:48typedef typename Flush::Type StorageType;49Adapter(StorageType* storage, Thread* thread) : _storage(storage), _thread(thread) {}50Adapter(Thread* thread) : _storage(NULL), _thread(thread) {}5152void set_storage(StorageType* storage) {53_storage = storage;54}5556StorageType* storage() {57return _storage;58}5960const u1* start() const {61assert(_storage != NULL, "invariant");62return _storage->start();63}6465u1* pos() {66assert(_storage != NULL, "invariant");67return _storage->pos();68}6970const u1* end() const {71assert(_storage != NULL, "invariant");72return _storage->end();73}7475void commit(u1* position) {76assert(_storage != NULL, "invariant");77_storage->set_pos(position);78}7980bool flush(size_t used, size_t requested) {81assert(_thread != NULL, "invariant");82Flush f(_storage, used, requested, _thread);83_storage = f.result();84return _storage != NULL && !_storage->excluded();85}8687void release() {88if (_storage != NULL && _storage->lease()) {89// This flush call will return the lease90// of a temporary storage area.91// Since the requested size is 0,92// the flush implementation will accomodate93// that 'size' request in the94// original thread local storage,95// by implication restoring the original96// in the process of returning a lease.97flush(0, 0);98}99}100101private:102StorageType* _storage;103Thread* _thread;104};105106template <size_t DEFAULT_SIZE = K>107class MallocAdapter {108private:109u1* _start;110u1* _pos;111u1* _end;112size_t _initial_size;113bool _has_ownership;114115bool allocate(size_t size);116void deallocate();117118public:119typedef u1 StorageType;120MallocAdapter(u1* storage, Thread* thread);121MallocAdapter(u1* storage, size_t size);122MallocAdapter(Thread* thread);123~MallocAdapter();124125StorageType* storage() { return _start; }126const u1* start() const { return _start; }127u1* pos() { return _pos; }128void commit(u1* position) { _pos = position; }129const u1* end() const { return _end; }130void release() {}131bool flush(size_t used, size_t requested);132};133134template <size_t DEFAULT_SIZE>135MallocAdapter<DEFAULT_SIZE>::MallocAdapter(u1* storage, size_t size) :136_start(storage),137_pos(storage),138_end(storage + size),139_initial_size(size),140_has_ownership(false) {141}142143template <size_t DEFAULT_SIZE>144MallocAdapter<DEFAULT_SIZE> ::MallocAdapter(u1* storage, Thread* thread) :145_start(storage),146_pos(storage),147_end(storage),148_initial_size(0),149_has_ownership(false) {150}151152template <size_t DEFAULT_SIZE>153MallocAdapter<DEFAULT_SIZE>::MallocAdapter(Thread* thread) :154_start(NULL),155_pos(NULL),156_end(NULL),157_initial_size(DEFAULT_SIZE),158_has_ownership(true) {159allocate(DEFAULT_SIZE);160}161162template <size_t DEFAULT_SIZE>163MallocAdapter<DEFAULT_SIZE>::~MallocAdapter() {164if (_has_ownership) {165deallocate();166}167}168169template <size_t DEFAULT_SIZE>170bool MallocAdapter<DEFAULT_SIZE>::allocate(size_t size) {171if (NULL == _start) {172_start = JfrCHeapObj::new_array<u1>(size);173if (_start) {174_pos = _start;175_end = _start + size;176_initial_size = size;177}178}179return _start != NULL;180}181182template <size_t DEFAULT_SIZE>183void MallocAdapter<DEFAULT_SIZE>::deallocate() {184if (_start != NULL) {185JfrCHeapObj::free(_start, (size_t)(_end - _start));186}187}188189template <size_t DEFAULT_SIZE>190bool MallocAdapter<DEFAULT_SIZE>::flush(size_t used, size_t requested) {191if (!_has_ownership) {192// can't just realloc a storage that we don't own193return false;194}195assert(_start != NULL, "invariant");196assert(used <= (size_t)(_end - _pos), "invariant");197assert(_pos + used <= _end, "invariant");198const size_t previous_storage_size = _end - _start;199const size_t new_storage_size = used + requested + (previous_storage_size * 2);200u1* const new_storage = JfrCHeapObj::new_array<u1>(new_storage_size);201if (!new_storage) {202return false;203}204const size_t previous_pos_offset = _pos - _start;205// migrate in-flight data206memcpy(new_storage, _start, previous_pos_offset + used);207JfrCHeapObj::free(_start, previous_storage_size);208_start = new_storage;209_pos = _start + previous_pos_offset;210_end = _start + new_storage_size;211return true;212}213214class NoOwnershipAdapter {215private:216u1* _start;217u1* _pos;218u1* _end;219size_t _size;220221public:222typedef u1 StorageType;223NoOwnershipAdapter(u1* storage, size_t size) : _start(storage), _pos(storage), _end(storage + size), _size(size) {}224NoOwnershipAdapter(u1* storage, Thread* thread) : _start(storage), _pos(storage), _end(storage), _size(0) {225ShouldNotCallThis();226}227NoOwnershipAdapter(Thread* thread) : _start(NULL), _pos(NULL), _end(NULL), _size(0) {228ShouldNotCallThis();229}230StorageType* storage() { return _start; }231const u1* start() const { return _start; }232u1* pos() { return _pos; }233void commit(u1* position) { _pos = position; }234const u1* end() const { return _end; }235void release() {}236bool flush(size_t used, size_t requested) {237// don't flush/expand a buffer that is not our own238_pos = _start;239return true;240}241};242243#endif // SHARE_JFR_WRITERS_JFRSTORAGEADAPTER_HPP244245246