products/sources/formale Sprachen/Coq/doc/sphinx image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: Byte.v   Sprache: Unknown

/*
 * Copyright (c) 2016, 2022, 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_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP
#define SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP

#include "jfr/recorder/storage/jfrMemorySpace.hpp"

#include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::
JfrMemorySpace(size_t min_element_size, size_t free_list_cache_count_limit, Client* client) :
  _free_list(),
  _live_list_epoch_0(),
  _live_list_epoch_1(),
  _client(client),
  _min_element_size(min_element_size),
  _free_list_cache_count_limit(free_list_cache_count_limit),
  _free_list_cache_count(0) {}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::~JfrMemorySpace() {
  while (_live_list_epoch_0.is_nonempty()) {
    deallocate(_live_list_epoch_0.remove());
  }
  while (_live_list_epoch_1.is_nonempty()) {
    deallocate(_live_list_epoch_1.remove());
  }
  while (_free_list.is_nonempty()) {
    deallocate(_free_list.remove());
  }
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::initialize(size_t cache_prealloc_count, bool prealloc_to_free_list) {
  if (!(_free_list.initialize() && _live_list_epoch_0.initialize() && _live_list_epoch_1.initialize())) {
    return false;
  }
  // pre-allocate elements to be cached in the requested list
  for (size_t i = 0; i < cache_prealloc_count; ++i) {
    NodePtr const node = allocate(_min_element_size);
    if (node == NULL) {
      return false;
    }
    if (prealloc_to_free_list) {
      add_to_free_list(node);
    } else {
      add_to_live_list(node);
    }
  }
  return true;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::should_populate_free_list_cache() const {
  return !is_free_list_cache_limited() || _free_list_cache_count < _free_list_cache_count_limit;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::is_free_list_cache_limited() const {
  return _free_list_cache_count_limit != JFR_MSPACE_UNLIMITED_CACHE_SIZE;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline size_t JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::min_element_size() const {
  return _min_element_size;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline FreeListType& JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::free_list() {
  return _free_list;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline const FreeListType& JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::free_list() const {
  return _free_list;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline FullListType& JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::live_list(bool previous_epoch) {
  if (epoch_aware) {
    return previous_epoch ? previous_epoch_list() : current_epoch_list();
  }
  return _live_list_epoch_0;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline const FullListType& JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::live_list(bool previous_epoch) const {
  if (epoch_aware) {
    return previous_epoch ? previous_epoch_list() : current_epoch_list();
  }
  return _live_list_epoch_0;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::free_list_is_empty() const {
  return _free_list.is_empty();
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::free_list_is_nonempty() const {
  return !free_list_is_empty();
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::live_list_is_empty(bool previous_epoch) const {
  return live_list().is_empty();
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::live_list_is_nonempty(bool previous_epoch) const {
  return live_list().is_nonempty();
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::in_free_list(const typename FreeListType::Node* node) const {
  return _free_list.in_list(node);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline const typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::epoch_list_selector(u1 epoch) const {
  assert(epoch_aware, "invariant");
  return epoch == 0 ? _live_list_epoch_0 : _live_list_epoch_1;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::epoch_list_selector(u1 epoch) {
  return const_cast<typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&>(
    const_cast<const JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>*>(this)->epoch_list_selector(epoch));
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline const typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::current_epoch_list() const {
  assert(epoch_aware, "invariant");
  return epoch_list_selector(JfrTraceIdEpoch::current());
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::current_epoch_list() {
  return const_cast<typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&>(
    const_cast<const JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>*>(this)->current_epoch_list());
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline const typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::previous_epoch_list() const {
  assert(epoch_aware, "invariant");
  return epoch_list_selector(JfrTraceIdEpoch::previous());
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&
JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::previous_epoch_list() {
  return const_cast<typename JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::LiveList&>(
    const_cast<const JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>*>(this)->previous_epoch_list());
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::in_live_list(const typename FreeListType::Node* node, bool previous_epoch) const {
  return live_list(previous_epoch).in_list(node);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::in_current_epoch_list(const typename FreeListType::Node* node) const {
  assert(epoch_aware, "invariant");
  return current_epoch_list().in_list(node);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline bool JfrMemorySpace< Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::in_previous_epoch_list(const typename FreeListType::Node* node) const {
  assert(epoch_aware, "invariant");
  return previous_epoch_list().in_list(node);
}

// allocations are even multiples of the mspace min size
static inline size_t align_allocation_size(size_t requested_size, size_t min_element_size) {
  if (requested_size > static_cast<size_t>(min_intx)) {
    assert(false"requested size: " SIZE_FORMAT " is too large", requested_size);
    return 0;
  }
  u8 alloc_size_bytes = min_element_size;
  while (requested_size > alloc_size_bytes) {
    alloc_size_bytes <<= 1;
  }
  assert(alloc_size_bytes <= static_cast<size_t>(min_intx), "invariant");
  return static_cast<size_t>(alloc_size_bytes);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline typename FreeListType::NodePtr JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::allocate(size_t size) {
  const size_t aligned_size_bytes = align_allocation_size(size, _min_element_size);
  if (aligned_size_bytes == 0) {
    return NULL;
  }
  voidconst allocation = JfrCHeapObj::new_array<u1>(aligned_size_bytes + sizeof(Node));
  if (allocation == NULL) {
    return NULL;
  }
  NodePtr node = new (allocation) Node();
  assert(node != NULL, "invariant");
  node->initialize(sizeof(Node), aligned_size_bytes);
  return node;
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::deallocate(typename FreeListType::NodePtr node) {
  assert(node != NULL, "invariant");
  assert(!in_free_list(node), "invariant");
  assert(!_live_list_epoch_0.in_list(node), "invariant");
  assert(!_live_list_epoch_1.in_list(node), "invariant");
  assert(node != NULL, "invariant");
  JfrCHeapObj::free(node, node->total_size());
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline typename FreeListType::NodePtr JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::acquire(size_t size, bool free_list, Thread* thread, bool previous_epoch) {
  return RetrievalPolicy<JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware> >::acquire(this, free_list, thread, size, previous_epoch);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::release(typename FreeListType::NodePtr node) {
  assert(node != NULL, "invariant");
  if (node->transient()) {
    deallocate(node);
    return;
  }
  assert(node->empty(), "invariant");
  assert(!node->retired(), "invariant");
  assert(node->identity() == NULL, "invariant");
  if (should_populate_free_list_cache()) {
    add_to_free_list(node);
  } else {
    deallocate(node);
  }
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::add_to_free_list(typename FreeListType::NodePtr node) {
  assert(node != NULL, "invariant");
  _free_list.add(node);
  if (is_free_list_cache_limited()) {
    Atomic::inc(&_free_list_cache_count);
  }
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::add_to_live_list(typename FreeListType::NodePtr node, bool previous_epoch) {
  assert(node != NULL, "invariant");
  live_list(previous_epoch).add(node);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::decrement_free_list_count() {
  if (is_free_list_cache_limited()) {
    Atomic::dec(&_free_list_cache_count);
  }
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
template <typename Callback>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::iterate_free_list(Callback& callback) {
  return _free_list.iterate(callback);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
template <typename Callback>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::iterate_live_list(Callback& callback, bool previous_epoch) {
  if (epoch_aware) {
    live_list(previous_epoch).iterate(callback);
    return;
  }
  _live_list_epoch_0.iterate(callback);
}

template <typename Client, template <typenameclass RetrievalPolicy, typename FreeListTypetypename FullListType, bool epoch_aware>
inline void JfrMemorySpace<Client, RetrievalPolicy, FreeListType, FullListType, epoch_aware>::register_full(typename FreeListType::NodePtr node, Thread* thread) {
  _client->register_full(node, thread);
}

template <typename Mspace, typename Client>
static inline Mspace* create_mspace(size_t min_element_size, size_t free_list_cache_count_limit, size_t cache_prealloc_count, bool prealloc_to_free_list, Client* cb) {
  Mspace* const mspace = new Mspace(min_element_size, free_list_cache_count_limit, cb);
  if (mspace != NULL) {
    mspace->initialize(cache_prealloc_count, prealloc_to_free_list);
  }
  return mspace;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate(size_t size, Mspace* mspace) {
  return mspace->allocate(size);
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_acquired(size_t size, Mspace* mspace, Thread* thread) {
  typename Mspace::NodePtr node = mspace_allocate(size, mspace);
  if (node == NULL) return NULL;
  node->set_identity(thread);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_transient(size_t size, Mspace* mspace, Thread* thread) {
  typename Mspace::NodePtr node = mspace_allocate_acquired(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->acquired_by_self(), "invariant");
  node->set_transient();
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_transient_lease(size_t size, Mspace* mspace, Thread* thread) {
  typename Mspace::NodePtr node = mspace_allocate_transient(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->transient(), "invariant");
  node->set_lease();
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_transient_lease_to_free(size_t size, Mspace* mspace, Thread* thread) {
  typename Mspace::NodePtr node = mspace_allocate_transient_lease(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->lease(), "invariant");
  mspace->add_to_free_list(node);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_free(size_t size, Mspace* mspace, Thread* thread) {
  return mspace->acquire(size, true, thread);
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_free_with_retry(size_t size, Mspace* mspace, size_t retry_count, Thread* thread) {
  assert(size <= mspace->min_element_size(), "invariant");
  for (size_t i = 0; i < retry_count; ++i) {
    typename Mspace::NodePtr node = mspace_acquire_free(size, mspace, thread);
    if (node != NULL) {
      return node;
    }
  }
  return NULL;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_to_live_list(size_t size, Mspace* mspace, Thread* thread) {
  typename Mspace::NodePtr node = mspace_allocate_acquired(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->acquired_by_self(), "invariant");
  mspace->add_to_live_list(node);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_transient_to_live_list(size_t size, Mspace* mspace, Thread* thread, bool previous_epoch = false) {
  typename Mspace::NodePtr node = mspace_allocate_transient(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->transient(), "invariant");
  mspace->add_to_live_list(node, previous_epoch);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_allocate_transient_lease_to_live_list(size_t size, Mspace* mspace, Thread* thread, bool previous_epoch = false) {
  typename Mspace::NodePtr node = mspace_allocate_transient_lease(size, mspace, thread);
  if (node == NULL) return NULL;
  assert(node->lease(), "invariant");
  mspace->add_to_live_list(node, previous_epoch);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_free_to_live_list(size_t size, Mspace* mspace, Thread* thread, bool previous_epoch = false) {
  assert(size <= mspace->min_element_size(), "invariant");
  typename Mspace::NodePtr node = mspace_acquire_free(size, mspace, thread);
  if (node == NULL) {
    return NULL;
  }
  assert(node->acquired_by_self(), "invariant");
  mspace->add_to_live_list(node, previous_epoch);
  return node;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_to_live_list(size_t size, Mspace* mspace, Thread* thread, bool previous_epoch = false) {
  if (size <= mspace->min_element_size()) {
    typename Mspace::NodePtr node = mspace_acquire_free_to_live_list(size, mspace, thread, previous_epoch);
    if (node != NULL) {
      return node;
    }
  }
  return mspace_allocate_to_live_list(size, mspace, thread);
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_live(size_t size, Mspace* mspace, Thread* thread, bool previous_epoch = false) {
  return mspace->acquire(size, false, thread, previous_epoch);
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_live_with_retry(size_t size, Mspace* mspace, size_t retry_count, Thread* thread, bool previous_epoch = false) {
  assert(size <= mspace->min_element_size(), "invariant");
  for (size_t i = 0; i < retry_count; ++i) {
    typename Mspace::NodePtr const node = mspace_acquire_live(size, mspace, thread, previous_epoch);
    if (node != NULL) {
      return node;
    }
  }
  return NULL;
}

template <typename Mspace>
inline typename Mspace::NodePtr mspace_acquire_lease_with_retry(size_t size, Mspace* mspace, size_t retry_count, Thread* thread, bool previous_epoch = false) {
  typename Mspace::NodePtr node = mspace_acquire_live_with_retry(size, mspace, retry_count, thread, previous_epoch);
  if (node != NULL) {
    node->set_lease();
  }
  return node;
}

template <typename Mspace>
inline void mspace_release(typename Mspace::NodePtr node, Mspace* mspace) {
  assert(node != NULL, "invariant");
  assert(node->unflushed_size() == 0, "invariant");
  assert(mspace != NULL, "invariant");
  mspace->release(node);
}

template <typename Callback, typename Mspace>
inline void process_live_list(Callback& callback, Mspace* mspace, bool previous_epoch = false) {
  assert(mspace != NULL, "invariant");
  mspace->iterate_live_list(callback, previous_epoch);
}

template <typename Callback, typename Mspace>
inline void process_free_list(Callback& callback, Mspace* mspace) {
  assert(mspace != NULL, "invariant");
  assert(mspace->free_list_is_nonempty(), "invariant");
  mspace->iterate_free_list(callback);
}

template <typename Mspace>
class ReleaseOp : public StackObj {
 private:
  Mspace* _mspace;
  bool _previous_epoch;
 public:
  typedef typename Mspace::Node Node;
  ReleaseOp(Mspace* mspace) : _mspace(mspace) {}
  bool process(typename Mspace::NodePtr node);
  size_t processed() const { return 0; }
};

template <typename Mspace>
inline bool ReleaseOp<Mspace>::process(typename Mspace::NodePtr node) {
  assert(node != NULL, "invariant");
  // assumes some means of exclusive access to the node
  if (node->transient()) {
    // make sure the transient node is already detached
    _mspace->release(node);
    return true;
  }
  node->reinitialize();
  if (node->identity() != NULL) {
    assert(node->empty(), "invariant");
    assert(!node->retired(), "invariant");
    node->release(); // publish
  }
  return true;
}

template <typename Mspace, typename List>
class ReleaseWithExcisionOp : public ReleaseOp<Mspace> {
 private:
  List& _list;
  typename List::NodePtr _prev;
  size_t _count;
  size_t _amount;
 public:
  ReleaseWithExcisionOp(Mspace* mspace, List& list) :
    ReleaseOp<Mspace>(mspace), _list(list), _prev(NULL), _count(0), _amount(0) {}
  bool process(typename List::NodePtr node);
  size_t processed() const { return _count; }
  size_t amount() const { return _amount; }
};

template <typename Mspace, typename List>
inline bool ReleaseWithExcisionOp<Mspace, List>::process(typename List::NodePtr node) {
  assert(node != NULL, "invariant");
  if (node->transient()) {
    _prev = _list.excise(_prev, node);
  } else {
    _prev = node;
  }
  return ReleaseOp<Mspace>::process(node);
}

template <typename Mspace, typename List>
class ScavengingReleaseOp : public StackObj {
 protected:
  Mspace* _mspace;
  List& _list;
  typename List::NodePtr _prev;
  size_t _count;
  size_t _amount;
    bool excise_with_release(typename List::NodePtr node);
 public:
  typedef typename List::Node Node;
  ScavengingReleaseOp(Mspace* mspace, List& list) :
    _mspace(mspace), _list(list), _prev(NULL), _count(0), _amount(0) {}
  bool process(typename List::NodePtr node);
  size_t processed() const { return _count; }
  size_t amount() const { return _amount; }
};

template <typename Mspace, typename List>
inline bool ScavengingReleaseOp<Mspace, List>::process(typename List::NodePtr node) {
  assert(node != NULL, "invariant");
  assert(!node->transient(), "invariant");
  if (node->retired()) {
    return excise_with_release(node);
  }
  _prev = node;
  return true;
}

template <typename Mspace, typename List>
inline bool ScavengingReleaseOp<Mspace, List>::excise_with_release(typename List::NodePtr node) {
  assert(node != NULL, "invariant");
  assert(node->retired(), "invariant");
  _prev = _list.excise(_prev, node);
  if (node->transient()) {
    _mspace->deallocate(node);
    return true;
  }
  assert(node->identity() != NULL, "invariant");
  assert(node->empty(), "invariant");
  assert(!node->lease(), "invariant");
  ++_count;
  _amount += node->total_size();
  node->clear_retired();
  node->release();
  mspace_release(node, _mspace);
  return true;
}

template <typename Functor, typename Mspace, typename FromList>
class ReleaseRetiredOp : public StackObj {
private:
  Functor& _functor;
  Mspace* _mspace;
  FromList& _list;
  typename Mspace::NodePtr _prev;
public:
  typedef typename Mspace::Node Node;
  ReleaseRetiredOp(Functor& functor, Mspace* mspace, FromList& list) :
    _functor(functor), _mspace(mspace), _list(list), _prev(NULL) {}
  bool process(Node* node);
};

template <typename Functor, typename Mspace, typename FromList>
inline bool ReleaseRetiredOp<Functor, Mspace, FromList>::process(typename Mspace::Node* node) {
  assert(node != NULL, "invariant");
  const bool is_retired = node->retired();
  const bool result = _functor.process(node);
  if (is_retired) {
    assert(node->unflushed_size() == 0, "invariant");
    _prev = _list.excise(_prev, node);
    node->reinitialize();
    assert(node->empty(), "invariant");
    assert(!node->retired(), "invariant");
    node->release();
    mspace_release(node, _mspace);
  } else {
    _prev = node;
  }
  return result;
}

template <typename Mspace, typename FromList>
class ReinitializeAllReleaseRetiredOp : public StackObj {
private:
  Mspace* _mspace;
  FromList& _list;
  typename Mspace::NodePtr _prev;
 public:
  typedef typename Mspace::Node Node;
  ReinitializeAllReleaseRetiredOp(Mspace* mspace, FromList& list) :
    _mspace(mspace), _list(list), _prev(NULL) {}
  bool process(Node* node);
};

template <typename Mspace, typename FromList>
inline bool ReinitializeAllReleaseRetiredOp<Mspace, FromList>::process(typename Mspace::Node* node) {
  assert(node != NULL, "invariant");
  // assumes some means of exclusive access to node
  const bool retired = node->retired();
  node->reinitialize();
  assert(node->empty(), "invariant");
  assert(!node->retired(), "invariant");
  if (retired) {
    _prev = _list.excise(_prev, node);
    node->release();
    mspace_release(node, _mspace);
  } else {
    _prev = node;
  }
  return true;
}

#ifdef ASSERT
template <typename Node>
inline void assert_migration_state(const Node* old, const Node* new_node, size_t used, size_t requested) {
  assert(old != NULL, "invariant");
  assert(new_node != NULL, "invariant");
  assert(old->pos() >= old->start(), "invariant");
  assert(old->pos() + used <= old->end(), "invariant");
  assert(new_node->free_size() >= (used + requested), "invariant");
}
#endif // ASSERT

template <typename Node>
inline void migrate_outstanding_writes(const Node* old, Node* new_node, size_t used, size_t requested) {
  DEBUG_ONLY(assert_migration_state(old, new_node, used, requested);)
  if (used > 0) {
    memcpy(new_node->pos(), old->pos(), used);
  }
}

#endif // SHARE_JFR_RECORDER_STORAGE_JFRMEMORYSPACE_INLINE_HPP

[ Verzeichnis aufwärts0.22unsichere Verbindung  Übersetzung europäischer Sprachen durch Browser  ]