src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp
author stefank
Tue, 26 Nov 2019 10:47:46 +0100
changeset 59290 97d13893ec3c
parent 58967 3c2e49d43ba3
permissions -rw-r--r--
8234748: Clean up atomic and orderAccess includes Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     1
/*
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 50429
diff changeset
     2
 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     4
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     7
 * published by the Free Software Foundation.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     8
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    13
 * accompanied this code).
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    14
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    18
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    21
 * questions.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    22
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    23
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    24
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    25
#include "precompiled.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    26
#include "jfr/jfrEvents.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    27
#include "jfr/jni/jfrJavaSupport.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    28
#include "jfr/recorder/jfrRecorder.hpp"
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
    29
#include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    30
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    31
#include "jfr/recorder/service/jfrOptionSet.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    32
#include "jfr/recorder/service/jfrPostBox.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    33
#include "jfr/recorder/storage/jfrMemorySpace.inline.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    34
#include "jfr/recorder/storage/jfrStorage.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    35
#include "jfr/recorder/storage/jfrStorageControl.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    36
#include "jfr/recorder/storage/jfrStorageUtils.inline.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    37
#include "jfr/utilities/jfrIterator.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    38
#include "jfr/utilities/jfrTime.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    39
#include "jfr/writers/jfrNativeEventWriter.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    40
#include "logging/log.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    41
#include "runtime/mutexLocker.hpp"
50117
fb66b2959eaf 8203251: Non-PCH build failed after JDK-8199712 (Flight Recorder)
shade
parents: 50113
diff changeset
    42
#include "runtime/os.inline.hpp"
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    43
#include "runtime/safepoint.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    44
#include "runtime/thread.hpp"
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    45
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    46
typedef JfrStorage::Buffer* BufferPtr;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    47
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    48
static JfrStorage* _instance = NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    49
static JfrStorageControl* _control;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    50
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    51
JfrStorage& JfrStorage::instance() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    52
  return *_instance;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    53
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    54
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    55
JfrStorage* JfrStorage::create(JfrChunkWriter& chunkwriter, JfrPostBox& post_box) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    56
  assert(_instance == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    57
  _instance = new JfrStorage(chunkwriter, post_box);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    58
  return _instance;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    59
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    60
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    61
void JfrStorage::destroy() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    62
  if (_instance != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    63
    delete _instance;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    64
    _instance = NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    65
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    66
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    67
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    68
JfrStorage::JfrStorage(JfrChunkWriter& chunkwriter, JfrPostBox& post_box) :
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    69
  _control(NULL),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    70
  _global_mspace(NULL),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    71
  _thread_local_mspace(NULL),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    72
  _transient_mspace(NULL),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    73
  _age_mspace(NULL),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    74
  _chunkwriter(chunkwriter),
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    75
  _post_box(post_box) {}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    76
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    77
JfrStorage::~JfrStorage() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    78
  if (_control != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    79
    delete _control;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    80
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    81
  if (_global_mspace != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    82
    delete _global_mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    83
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    84
  if (_thread_local_mspace != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    85
    delete _thread_local_mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    86
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    87
  if (_transient_mspace != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    88
    delete _transient_mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    89
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    90
  if (_age_mspace != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    91
    delete _age_mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    92
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    93
  _instance = NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    94
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    95
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    96
static const size_t in_memory_discard_threshold_delta = 2; // start to discard data when the only this number of free buffers are left
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    97
static const size_t unlimited_mspace_size = 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    98
static const size_t thread_local_cache_count = 8;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    99
static const size_t thread_local_scavenge_threshold = thread_local_cache_count / 2;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   100
static const size_t transient_buffer_size_multiplier = 8; // against thread local buffer size
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   101
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   102
template <typename Mspace>
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   103
static Mspace* create_mspace(size_t buffer_size, size_t limit, size_t cache_count, JfrStorage* storage_instance) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   104
  Mspace* mspace = new Mspace(buffer_size, limit, cache_count, storage_instance);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   105
  if (mspace != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   106
    mspace->initialize();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   107
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   108
  return mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   109
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   110
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   111
bool JfrStorage::initialize() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   112
  assert(_control == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   113
  assert(_global_mspace == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   114
  assert(_thread_local_mspace == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   115
  assert(_transient_mspace == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   116
  assert(_age_mspace == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   117
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   118
  const size_t num_global_buffers = (size_t)JfrOptionSet::num_global_buffers();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   119
  assert(num_global_buffers >= in_memory_discard_threshold_delta, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   120
  const size_t memory_size = (size_t)JfrOptionSet::memory_size();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   121
  const size_t global_buffer_size = (size_t)JfrOptionSet::global_buffer_size();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   122
  const size_t thread_buffer_size = (size_t)JfrOptionSet::thread_buffer_size();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   123
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   124
  _control = new JfrStorageControl(num_global_buffers, num_global_buffers - in_memory_discard_threshold_delta);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   125
  if (_control == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   126
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   127
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   128
  _global_mspace = create_mspace<JfrStorageMspace>(global_buffer_size, memory_size, num_global_buffers, this);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   129
  if (_global_mspace == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   130
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   131
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   132
  _thread_local_mspace = create_mspace<JfrThreadLocalMspace>(thread_buffer_size, unlimited_mspace_size, thread_local_cache_count, this);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   133
  if (_thread_local_mspace == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   134
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   135
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   136
  _transient_mspace = create_mspace<JfrStorageMspace>(thread_buffer_size * transient_buffer_size_multiplier, unlimited_mspace_size, 0, this);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   137
  if (_transient_mspace == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   138
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   139
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   140
  _age_mspace = create_mspace<JfrStorageAgeMspace>(0 /* no extra size except header */, unlimited_mspace_size, num_global_buffers, this);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   141
  if (_age_mspace == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   142
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   143
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   144
  control().set_scavenge_threshold(thread_local_scavenge_threshold);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   145
  return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   146
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   147
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   148
JfrStorageControl& JfrStorage::control() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   149
  return *instance()._control;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   150
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   151
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   152
static void log_allocation_failure(const char* msg, size_t size) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   153
  log_warning(jfr)("Unable to allocate " SIZE_FORMAT " bytes of %s.", size, msg);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   154
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   155
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   156
BufferPtr JfrStorage::acquire_thread_local(Thread* thread, size_t size /* 0 */) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   157
  BufferPtr buffer = mspace_get_to_full(size, instance()._thread_local_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   158
  if (buffer == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   159
    log_allocation_failure("thread local_memory", size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   160
    return NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   161
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   162
  assert(buffer->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   163
  return buffer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   164
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   165
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   166
BufferPtr JfrStorage::acquire_transient(size_t size, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   167
  BufferPtr buffer = mspace_allocate_transient_lease_to_full(size, instance()._transient_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   168
  if (buffer == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   169
    log_allocation_failure("transient memory", size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   170
    return NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   171
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   172
  assert(buffer->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   173
  assert(buffer->transient(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   174
  assert(buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   175
  return buffer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   176
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   177
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   178
static BufferPtr get_lease(size_t size, JfrStorageMspace* mspace, JfrStorage& storage_instance, size_t retry_count, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   179
  assert(size <= mspace->min_elem_size(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   180
  while (true) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   181
    BufferPtr t = mspace_get_free_lease_with_retry(size, mspace, retry_count, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   182
    if (t == NULL && storage_instance.control().should_discard()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   183
      storage_instance.discard_oldest(thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   184
      continue;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   185
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   186
    return t;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   187
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   188
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   189
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   190
static BufferPtr get_promotion_buffer(size_t size, JfrStorageMspace* mspace, JfrStorage& storage_instance, size_t retry_count, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   191
  assert(size <= mspace->min_elem_size(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   192
  while (true) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   193
    BufferPtr t = mspace_get_free_with_retry(size, mspace, retry_count, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   194
    if (t == NULL && storage_instance.control().should_discard()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   195
      storage_instance.discard_oldest(thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   196
      continue;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   197
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   198
    return t;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   199
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   200
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   201
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   202
static const size_t lease_retry = 10;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   203
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   204
BufferPtr JfrStorage::acquire_large(size_t size, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   205
  JfrStorage& storage_instance = instance();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   206
  const size_t max_elem_size = storage_instance._global_mspace->min_elem_size(); // min is also max
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   207
  // if not too large and capacity is still available, ask for a lease from the global system
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   208
  if (size < max_elem_size && storage_instance.control().is_global_lease_allowed()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   209
    BufferPtr const buffer = get_lease(size, storage_instance._global_mspace, storage_instance, lease_retry, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   210
    if (buffer != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   211
      assert(buffer->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   212
      assert(!buffer->transient(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   213
      assert(buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   214
      storage_instance.control().increment_leased();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   215
      return buffer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   216
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   217
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   218
  return acquire_transient(size, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   219
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   220
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   221
static void write_data_loss_event(JfrBuffer* buffer, u8 unflushed_size, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   222
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   223
  assert(buffer->empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   224
  const u8 total_data_loss = thread->jfr_thread_local()->add_data_lost(unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   225
  if (EventDataLoss::is_enabled()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   226
    JfrNativeEventWriter writer(buffer, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   227
    writer.write<u8>(EventDataLoss::eventId);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   228
    writer.write(JfrTicks::now());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   229
    writer.write(unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   230
    writer.write(total_data_loss);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   231
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   232
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   233
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   234
static void write_data_loss(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   235
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   236
  const size_t unflushed_size = buffer->unflushed_size();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   237
  buffer->concurrent_reinitialization();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   238
  if (unflushed_size == 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   239
    return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   240
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   241
  write_data_loss_event(buffer, unflushed_size, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   242
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   243
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   244
static const size_t promotion_retry = 100;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   245
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   246
bool JfrStorage::flush_regular_buffer(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   247
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   248
  assert(!buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   249
  assert(!buffer->transient(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   250
  const size_t unflushed_size = buffer->unflushed_size();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   251
  if (unflushed_size == 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   252
    buffer->concurrent_reinitialization();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   253
    assert(buffer->empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   254
    return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   255
  }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   256
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   257
  if (buffer->excluded()) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   258
    const bool thread_is_excluded = thread->jfr_thread_local()->is_excluded();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   259
    buffer->reinitialize(thread_is_excluded);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   260
    assert(buffer->empty(), "invariant");
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   261
    if (!thread_is_excluded) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   262
      // state change from exclusion to inclusion requires a thread checkpoint
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   263
      JfrCheckpointManager::write_thread_checkpoint(thread);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   264
    }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   265
    return true;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   266
  }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   267
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   268
  BufferPtr const promotion_buffer = get_promotion_buffer(unflushed_size, _global_mspace, *this, promotion_retry, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   269
  if (promotion_buffer == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   270
    write_data_loss(buffer, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   271
    return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   272
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   273
  assert(promotion_buffer->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   274
  assert(promotion_buffer->free_size() >= unflushed_size, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   275
  buffer->concurrent_move_and_reinitialize(promotion_buffer, unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   276
  assert(buffer->empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   277
  return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   278
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   279
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   280
/*
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   281
* 1. If the buffer was a "lease" from the global system, release back.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   282
* 2. If the buffer is transient (temporal dynamically allocated), retire and register full.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   283
*
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   284
* The buffer is effectively invalidated for the thread post-return,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   285
* and the caller should take means to ensure that it is not referenced any longer.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   286
*/
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   287
void JfrStorage::release_large(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   288
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   289
  assert(buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   290
  assert(buffer->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   291
  buffer->clear_lease();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   292
  if (buffer->transient()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   293
    buffer->set_retired();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   294
    register_full(buffer, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   295
  } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   296
    buffer->release();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   297
    control().decrement_leased();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   298
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   299
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   300
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   301
static JfrAgeNode* new_age_node(BufferPtr buffer, JfrStorageAgeMspace* age_mspace, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   302
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   303
  assert(age_mspace != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   304
  return mspace_allocate_transient(0, age_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   305
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   306
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   307
static void log_registration_failure(size_t unflushed_size) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   308
  log_warning(jfr)("Unable to register a full buffer of " SIZE_FORMAT " bytes.", unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   309
  log_debug(jfr, system)("Cleared 1 full buffer of " SIZE_FORMAT " bytes.", unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   310
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   311
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   312
static void handle_registration_failure(BufferPtr buffer) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   313
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   314
  assert(buffer->retired(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   315
  const size_t unflushed_size = buffer->unflushed_size();
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   316
  buffer->concurrent_reinitialization();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   317
  log_registration_failure(unflushed_size);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   318
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   319
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   320
static JfrAgeNode* get_free_age_node(JfrStorageAgeMspace* age_mspace, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   321
  assert(JfrBuffer_lock->owned_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   322
  return mspace_get_free_with_detach(0, age_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   323
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   324
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   325
static bool insert_full_age_node(JfrAgeNode* age_node, JfrStorageAgeMspace* age_mspace, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   326
  assert(JfrBuffer_lock->owned_by_self(), "invariant");
55053
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   327
  assert(age_node != NULL, "invariant");
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   328
  assert(age_node->acquired_by_self(), "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   329
  assert(age_node->retired_buffer()->retired(), "invariant");
55053
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   330
  age_node->release(); // drop identity claim on age node when inserting to full list
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   331
  assert(age_node->identity() == NULL, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   332
  age_mspace->insert_full_head(age_node);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   333
  return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   334
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   335
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   336
static bool full_buffer_registration(BufferPtr buffer, JfrStorageAgeMspace* age_mspace, JfrStorageControl& control, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   337
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   338
  assert(buffer->retired(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   339
  assert(age_mspace != NULL, "invariant");
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 50429
diff changeset
   340
  MutexLocker lock(JfrBuffer_lock, Mutex::_no_safepoint_check_flag);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   341
  JfrAgeNode* age_node = get_free_age_node(age_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   342
  if (age_node == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   343
    age_node = new_age_node(buffer, age_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   344
    if (age_node == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   345
      return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   346
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   347
  }
55053
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   348
  assert(age_node != NULL, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   349
  assert(age_node->acquired_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   350
  age_node->set_retired_buffer(buffer);
50234
6ba3e32a9882 8203457: Add back missing full buffer notification
mgronlun
parents: 50117
diff changeset
   351
  control.increment_full();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   352
  return insert_full_age_node(age_node, age_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   353
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   354
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   355
void JfrStorage::register_full(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   356
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   357
  assert(buffer->retired(), "invariant");
54964
ec7d6d8effc7 8220293: Deadlock in JFR string pool
mgronlun
parents: 54623
diff changeset
   358
  assert(buffer->acquired_by(thread), "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   359
  if (!full_buffer_registration(buffer, _age_mspace, control(), thread)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   360
    handle_registration_failure(buffer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   361
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   362
  if (control().should_post_buffer_full_message()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   363
    _post_box.post(MSG_FULLBUFFER);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   364
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   365
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   366
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   367
void JfrStorage::lock() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   368
  assert(!JfrBuffer_lock->owned_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   369
  JfrBuffer_lock->lock_without_safepoint_check();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   370
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   371
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   372
void JfrStorage::unlock() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   373
  assert(JfrBuffer_lock->owned_by_self(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   374
  JfrBuffer_lock->unlock();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   375
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   376
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   377
#ifdef ASSERT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   378
bool JfrStorage::is_locked() const {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   379
  return JfrBuffer_lock->owned_by_self();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   380
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   381
#endif
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   382
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   383
// don't use buffer on return, it is gone
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   384
void JfrStorage::release(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   385
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   386
  assert(!buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   387
  assert(!buffer->transient(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   388
  assert(!buffer->retired(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   389
  if (!buffer->empty()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   390
    if (!flush_regular_buffer(buffer, thread)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   391
      buffer->concurrent_reinitialization();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   392
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   393
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   394
  assert(buffer->empty(), "invariant");
54964
ec7d6d8effc7 8220293: Deadlock in JFR string pool
mgronlun
parents: 54623
diff changeset
   395
  assert(buffer->identity() != NULL, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   396
  control().increment_dead();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   397
  buffer->set_retired();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   398
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   399
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   400
void JfrStorage::release_thread_local(BufferPtr buffer, Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   401
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   402
  JfrStorage& storage_instance = instance();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   403
  storage_instance.release(buffer, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   404
  if (storage_instance.control().should_scavenge()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   405
    storage_instance._post_box.post(MSG_DEADBUFFER);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   406
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   407
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   408
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   409
static void log_discard(size_t count, size_t amount, size_t current) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   410
  if (log_is_enabled(Debug, jfr, system)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   411
    assert(count > 0, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   412
    log_debug(jfr, system)("Cleared " SIZE_FORMAT " full buffer(s) of " SIZE_FORMAT" bytes.", count, amount);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   413
    log_debug(jfr, system)("Current number of full buffers " SIZE_FORMAT "", current);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   414
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   415
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   416
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   417
void JfrStorage::discard_oldest(Thread* thread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   418
  if (JfrBuffer_lock->try_lock()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   419
    if (!control().should_discard()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   420
      // another thread handled it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   421
      return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   422
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   423
    const size_t num_full_pre_discard = control().full_count();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   424
    size_t num_full_post_discard = 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   425
    size_t discarded_size = 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   426
    while (true) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   427
      JfrAgeNode* const oldest_age_node = _age_mspace->full_tail();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   428
      if (oldest_age_node == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   429
        break;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   430
      }
55053
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   431
      assert(oldest_age_node->identity() == NULL, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   432
      BufferPtr const buffer = oldest_age_node->retired_buffer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   433
      assert(buffer->retired(), "invariant");
58967
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   434
      discarded_size += buffer->discard();
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   435
      assert(buffer->unflushed_size() == 0, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   436
      num_full_post_discard = control().decrement_full();
58967
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   437
      mspace_release_full(oldest_age_node, _age_mspace);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   438
      if (buffer->transient()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   439
        mspace_release_full(buffer, _transient_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   440
        continue;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   441
      }
58967
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   442
      buffer->reinitialize();
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   443
      buffer->release(); // publish
3c2e49d43ba3 8232905: JFR fails with assertion: assert(t->unflushed_size() == 0) failed: invariant
mgronlun
parents: 58863
diff changeset
   444
      break;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   445
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   446
    JfrBuffer_lock->unlock();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   447
    const size_t number_of_discards = num_full_pre_discard - num_full_post_discard;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   448
    if (number_of_discards > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   449
      log_discard(number_of_discards, discarded_size, num_full_post_discard);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   450
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   451
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   452
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   453
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   454
#ifdef ASSERT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   455
typedef const BufferPtr ConstBufferPtr;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   456
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   457
static void assert_flush_precondition(ConstBufferPtr cur, size_t used, bool native, const Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   458
  assert(t != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   459
  assert(cur != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   460
  assert(cur->pos() + used <= cur->end(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   461
  assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   462
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   463
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   464
static void assert_flush_regular_precondition(ConstBufferPtr cur, const u1* const cur_pos, size_t used, size_t req, const Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   465
  assert(t != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   466
  assert(t->jfr_thread_local()->shelved_buffer() == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   467
  assert(cur != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   468
  assert(!cur->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   469
  assert(cur_pos != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   470
  assert(req >= used, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   471
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   472
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   473
static void assert_provision_large_precondition(ConstBufferPtr cur, size_t used, size_t req, const Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   474
  assert(cur != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   475
  assert(t != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   476
  assert(t->jfr_thread_local()->shelved_buffer() != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   477
  assert(req >= used, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   478
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   479
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   480
static void assert_flush_large_precondition(ConstBufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   481
  assert(t != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   482
  assert(cur != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   483
  assert(cur->lease(), "invariant");
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   484
  assert(!cur->excluded(), "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   485
  assert(cur_pos != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   486
  assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   487
  assert(t->jfr_thread_local()->shelved_buffer() != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   488
  assert(req >= used, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   489
  assert(cur != t->jfr_thread_local()->shelved_buffer(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   490
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   491
#endif // ASSERT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   492
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   493
BufferPtr JfrStorage::flush(BufferPtr cur, size_t used, size_t req, bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   494
  debug_only(assert_flush_precondition(cur, used, native, t);)
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   495
  const u1* const cur_pos = cur->pos();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   496
  req += used;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   497
  // requested size now encompass the outstanding used size
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   498
  return cur->lease() ? instance().flush_large(cur, cur_pos, used, req, native, t) :
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   499
                          instance().flush_regular(cur, cur_pos, used, req, native, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   500
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   501
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   502
BufferPtr JfrStorage::flush_regular(BufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   503
  debug_only(assert_flush_regular_precondition(cur, cur_pos, used, req, t);)
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   504
  // A flush is needed before memcpy since a non-large buffer is thread stable
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   505
  // (thread local). The flush will not modify memory in addresses above pos()
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   506
  // which is where the "used / uncommitted" data resides. It is therefore both
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   507
  // possible and valid to migrate data after the flush. This is however only
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   508
  // the case for stable thread local buffers; it is not the case for large buffers.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   509
  if (!cur->empty()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   510
    flush_regular_buffer(cur, t);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   511
    if (cur->excluded()) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   512
      return cur;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   513
    }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   514
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   515
  assert(t->jfr_thread_local()->shelved_buffer() == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   516
  if (cur->free_size() >= req) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   517
    // simplest case, no switching of buffers
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   518
    if (used > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   519
      memcpy(cur->pos(), (void*)cur_pos, used);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   520
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   521
    assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   522
    return cur;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   523
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   524
  // Going for a "larger-than-regular" buffer.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   525
  // Shelve the current buffer to make room for a temporary lease.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   526
  t->jfr_thread_local()->shelve_buffer(cur);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   527
  return provision_large(cur, cur_pos, used, req, native, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   528
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   529
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   530
static BufferPtr store_buffer_to_thread_local(BufferPtr buffer, JfrThreadLocal* jfr_thread_local, bool native) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   531
  assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   532
  if (native) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   533
    jfr_thread_local->set_native_buffer(buffer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   534
  } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   535
    jfr_thread_local->set_java_buffer(buffer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   536
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   537
  return buffer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   538
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   539
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   540
static BufferPtr restore_shelved_buffer(bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   541
  JfrThreadLocal* const tl = t->jfr_thread_local();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   542
  BufferPtr shelved = tl->shelved_buffer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   543
  assert(shelved != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   544
  tl->shelve_buffer(NULL);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   545
  // restore shelved buffer back as primary
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   546
  return store_buffer_to_thread_local(shelved, tl, native);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   547
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   548
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   549
BufferPtr JfrStorage::flush_large(BufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   550
  debug_only(assert_flush_large_precondition(cur, cur_pos, used, req, native, t);)
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   551
  // Can the "regular" buffer (now shelved) accommodate the requested size?
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   552
  BufferPtr shelved = t->jfr_thread_local()->shelved_buffer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   553
  assert(shelved != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   554
  if (shelved->free_size() >= req) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   555
    if (req > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   556
      memcpy(shelved->pos(), (void*)cur_pos, (size_t)used);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   557
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   558
    // release and invalidate
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   559
    release_large(cur, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   560
    return restore_shelved_buffer(native, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   561
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   562
  // regular too small
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   563
  return provision_large(cur, cur_pos,  used, req, native, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   564
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   565
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   566
static BufferPtr large_fail(BufferPtr cur, bool native, JfrStorage& storage_instance, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   567
  assert(cur != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   568
  assert(t != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   569
  if (cur->lease()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   570
    storage_instance.release_large(cur, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   571
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   572
  return restore_shelved_buffer(native, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   573
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   574
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   575
// Always returns a non-null buffer.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   576
// If accommodating the large request fails, the shelved buffer is returned
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   577
// even though it might be smaller than the requested size.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   578
// Caller needs to ensure if the size was successfully accommodated.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   579
BufferPtr JfrStorage::provision_large(BufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   580
  debug_only(assert_provision_large_precondition(cur, used, req, t);)
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   581
  assert(t->jfr_thread_local()->shelved_buffer() != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   582
  BufferPtr const buffer = acquire_large(req, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   583
  if (buffer == NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   584
    // unable to allocate and serve the request
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   585
    return large_fail(cur, native, *this, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   586
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   587
  // ok managed to acquire a "large" buffer for the requested size
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   588
  assert(buffer->free_size() >= req, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   589
  assert(buffer->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   590
  // transfer outstanding data
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   591
  memcpy(buffer->pos(), (void*)cur_pos, used);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   592
  if (cur->lease()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   593
    release_large(cur, t);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   594
    // don't use current anymore, it is gone
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   595
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   596
  return store_buffer_to_thread_local(buffer, t->jfr_thread_local(), native);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   597
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   598
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   599
typedef UnBufferedWriteToChunk<JfrBuffer> WriteOperation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   600
typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   601
typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation;
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   602
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   603
typedef Retired<JfrBuffer, true> NonRetired;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   604
typedef Excluded<JfrBuffer, true> NonExcluded;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   605
typedef CompositeOperation<NonRetired, NonExcluded> BufferPredicate;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   606
typedef PredicatedMutexedWriteOp<WriteOperation, BufferPredicate> ThreadLocalMutexedWriteOperation;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   607
typedef PredicatedConcurrentWriteOp<WriteOperation, BufferPredicate> ThreadLocalConcurrentWriteOperation;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   608
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   609
size_t JfrStorage::write() {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   610
  const size_t full_elements = write_full();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   611
  WriteOperation wo(_chunkwriter);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   612
  NonRetired nr;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   613
  NonExcluded ne;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   614
  BufferPredicate bp(&nr, &ne);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   615
  ThreadLocalConcurrentWriteOperation tlwo(wo, bp);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   616
  process_full_list(tlwo, _thread_local_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   617
  ConcurrentWriteOperation cwo(wo);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   618
  process_free_list(cwo, _global_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   619
  return full_elements + wo.elements();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   620
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   621
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   622
size_t JfrStorage::write_at_safepoint() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   623
  assert(SafepointSynchronize::is_at_safepoint(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   624
  WriteOperation wo(_chunkwriter);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   625
  MutexedWriteOperation writer(wo); // mutexed write mode
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   626
  NonRetired nr;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   627
  NonExcluded ne;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   628
  BufferPredicate bp(&nr, &ne);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   629
  ThreadLocalMutexedWriteOperation tlmwo(wo, bp);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   630
  process_full_list(tlmwo, _thread_local_mspace);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   631
  assert(_transient_mspace->is_free_empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   632
  process_full_list(writer, _transient_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   633
  assert(_global_mspace->is_full_empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   634
  process_free_list(writer, _global_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   635
  return wo.elements();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   636
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   637
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   638
typedef DiscardOp<DefaultDiscarder<JfrStorage::Buffer> > DiscardOperation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   639
typedef ReleaseOp<JfrStorageMspace> ReleaseOperation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   640
typedef CompositeOperation<MutexedWriteOperation, ReleaseOperation> FullOperation;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   641
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   642
size_t JfrStorage::clear() {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   643
  const size_t full_elements = clear_full();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   644
  DiscardOperation discarder(concurrent); // concurrent discard mode
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   645
  process_full_list(discarder, _thread_local_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   646
  assert(_transient_mspace->is_free_empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   647
  process_full_list(discarder, _transient_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   648
  assert(_global_mspace->is_full_empty(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   649
  process_free_list(discarder, _global_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   650
  return full_elements + discarder.elements();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   651
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   652
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   653
static void insert_free_age_nodes(JfrStorageAgeMspace* age_mspace, JfrAgeNode* head, JfrAgeNode* tail, size_t count) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   654
  if (tail != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   655
    assert(tail->next() == NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   656
    assert(head != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   657
    assert(head->prev() == NULL, "invariant");
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 50429
diff changeset
   658
    MutexLocker buffer_lock(JfrBuffer_lock, Mutex::_no_safepoint_check_flag);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   659
    age_mspace->insert_free_tail(head, tail, count);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   660
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   661
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   662
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   663
template <typename Processor>
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   664
static void process_age_list(Processor& processor, JfrStorageAgeMspace* age_mspace, JfrAgeNode* head, size_t count) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   665
  assert(age_mspace != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   666
  assert(head != NULL, "invariant");
50234
6ba3e32a9882 8203457: Add back missing full buffer notification
mgronlun
parents: 50117
diff changeset
   667
  assert(count > 0, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   668
  JfrAgeNode* node = head;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   669
  JfrAgeNode* last = NULL;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   670
  while (node != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   671
    last = node;
55053
d58e1a447d2b 8221121: applications/microbenchmarks are encountering crashes in tier5
mgronlun
parents: 54964
diff changeset
   672
    assert(node->identity() == NULL, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   673
    BufferPtr const buffer = node->retired_buffer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   674
    assert(buffer != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   675
    assert(buffer->retired(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   676
    processor.process(buffer);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   677
    // at this point, buffer is already live or destroyed
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   678
    JfrAgeNode* const next = (JfrAgeNode*)node->next();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   679
    if (node->transient()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   680
      // detach
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   681
      last = (JfrAgeNode*)last->prev();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   682
      if (last != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   683
        last->set_next(next);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   684
      } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   685
        head = next;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   686
      }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   687
      if (next != NULL) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   688
        next->set_prev(last);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   689
      }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   690
      --count;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   691
      age_mspace->deallocate(node);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   692
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   693
    node = next;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   694
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   695
  insert_free_age_nodes(age_mspace, head, last, count);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   696
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   697
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   698
template <typename Processor>
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   699
static size_t process_full(Processor& processor, JfrStorageControl& control, JfrStorageAgeMspace* age_mspace) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   700
  assert(age_mspace != NULL, "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   701
  if (age_mspace->is_full_empty()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   702
    // nothing to do
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   703
    return 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   704
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   705
  size_t count;
50234
6ba3e32a9882 8203457: Add back missing full buffer notification
mgronlun
parents: 50117
diff changeset
   706
  JfrAgeNode* head;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   707
  {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   708
    // fetch age list
54623
1126f0607c70 8222811: Consolidate MutexLockerEx and MutexLocker
coleenp
parents: 50429
diff changeset
   709
    MutexLocker buffer_lock(JfrBuffer_lock, Mutex::_no_safepoint_check_flag);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   710
    count = age_mspace->full_count();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   711
    head = age_mspace->clear_full();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   712
    control.reset_full();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   713
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   714
  assert(head != NULL, "invariant");
50234
6ba3e32a9882 8203457: Add back missing full buffer notification
mgronlun
parents: 50117
diff changeset
   715
  assert(count > 0, "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   716
  process_age_list(processor, age_mspace, head, count);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   717
  return count;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   718
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   719
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   720
static void log(size_t count, size_t amount, bool clear = false) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   721
  if (log_is_enabled(Debug, jfr, system)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   722
    if (count > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   723
      log_debug(jfr, system)("%s " SIZE_FORMAT " full buffer(s) of " SIZE_FORMAT" B of data%s",
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   724
        clear ? "Discarded" : "Wrote", count, amount, clear ? "." : " to chunk.");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   725
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   726
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   727
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   728
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   729
// full writer
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   730
// Assumption is retired only; exclusive access
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   731
// MutexedWriter -> ReleaseOp
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   732
//
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   733
size_t JfrStorage::write_full() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   734
  assert(_chunkwriter.is_valid(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   735
  Thread* const thread = Thread::current();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   736
  WriteOperation wo(_chunkwriter);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   737
  MutexedWriteOperation writer(wo); // a retired buffer implies mutexed access
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   738
  ReleaseOperation ro(_transient_mspace, thread);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   739
  FullOperation cmd(&writer, &ro);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   740
  const size_t count = process_full(cmd, control(), _age_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   741
  if (0 == count) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   742
    assert(0 == writer.elements(), "invariant");
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   743
    return 0;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   744
  }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   745
  const size_t size = writer.size();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   746
  log(count, size);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   747
  return count;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   748
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   749
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   750
size_t JfrStorage::clear_full() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   751
  DiscardOperation discarder(mutexed); // a retired buffer implies mutexed access
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   752
  const size_t count = process_full(discarder, control(), _age_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   753
  if (0 == count) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   754
    assert(0 == discarder.elements(), "invariant");
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   755
    return 0;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   756
  }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   757
  const size_t size = discarder.size();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   758
  log(count, size, true);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   759
  return count;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   760
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   761
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   762
static void scavenge_log(size_t count, size_t amount, size_t current) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   763
  if (count > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   764
    if (log_is_enabled(Debug, jfr, system)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   765
      log_debug(jfr, system)("Released " SIZE_FORMAT " dead buffer(s) of " SIZE_FORMAT" B of data.", count, amount);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   766
      log_debug(jfr, system)("Current number of dead buffers " SIZE_FORMAT "", current);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   767
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   768
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   769
}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   770
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   771
template <typename Mspace>
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   772
class Scavenger {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   773
private:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   774
  JfrStorageControl& _control;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   775
  Mspace* _mspace;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   776
  size_t _count;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   777
  size_t _amount;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   778
public:
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   779
  typedef typename Mspace::Type Type;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   780
  Scavenger(JfrStorageControl& control, Mspace* mspace) : _control(control), _mspace(mspace), _count(0), _amount(0) {}
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   781
  bool process(Type* t) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   782
    if (t->retired()) {
54964
ec7d6d8effc7 8220293: Deadlock in JFR string pool
mgronlun
parents: 54623
diff changeset
   783
      assert(t->identity() != NULL, "invariant");
ec7d6d8effc7 8220293: Deadlock in JFR string pool
mgronlun
parents: 54623
diff changeset
   784
      assert(t->empty(), "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   785
      assert(!t->transient(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   786
      assert(!t->lease(), "invariant");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   787
      ++_count;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   788
      _amount += t->total_size();
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   789
      if (t->excluded()) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   790
        t->clear_excluded();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   791
      }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   792
      assert(!t->excluded(), "invariant");
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   793
      t->clear_retired();
54964
ec7d6d8effc7 8220293: Deadlock in JFR string pool
mgronlun
parents: 54623
diff changeset
   794
      t->release();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   795
      _control.decrement_dead();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   796
      mspace_release_full_critical(t, _mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   797
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   798
    return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   799
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   800
  size_t processed() const { return _count; }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   801
  size_t amount() const { return _amount; }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   802
};
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   803
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   804
size_t JfrStorage::scavenge() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   805
  JfrStorageControl& ctrl = control();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   806
  if (ctrl.dead_count() == 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   807
    return 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   808
  }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   809
  Scavenger<JfrThreadLocalMspace> scavenger(ctrl, _thread_local_mspace);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   810
  process_full_list(scavenger, _thread_local_mspace);
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   811
  const size_t count = scavenger.processed();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   812
  if (0 == count) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   813
    assert(0 == scavenger.amount(), "invariant");
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   814
    return 0;
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   815
  }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   816
  scavenge_log(count, scavenger.amount(), ctrl.dead_count());
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55053
diff changeset
   817
  return count;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   818
}