src/hotspot/share/gc/shared/oopStorage.hpp
author kbarrett
Tue, 21 Nov 2017 09:47:55 -0500
changeset 48787 7638bf98a312
child 48806 51fc22e5fb00
permissions -rw-r--r--
8194312: Support parallel and concurrent JNI global handle processing Summary: Add OopStorage, change JNI gloabl/weak to use OopStorage. Reviewed-by: coleenp, sspitsyn, eosterlund
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48787
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     1
/*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     4
 *
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     7
 * published by the Free Software Foundation.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     8
 *
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    13
 * accompanied this code).
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    14
 *
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    18
 *
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    21
 * questions.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    22
 *
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    23
 */
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    24
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    25
#ifndef SHARE_GC_SHARED_OOPSTORAGE_HPP
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    26
#define SHARE_GC_SHARED_OOPSTORAGE_HPP
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    27
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    28
#include "memory/allocation.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    29
#include "metaprogramming/conditional.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    30
#include "metaprogramming/isConst.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    31
#include "oops/oop.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    32
#include "utilities/count_trailing_zeros.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    33
#include "utilities/debug.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    34
#include "utilities/globalDefinitions.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    35
#include "utilities/macros.hpp"
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    36
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    37
class Mutex;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    38
class outputStream;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    39
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    40
// OopStorage supports management of off-heap references to objects allocated
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    41
// in the Java heap.  An OopStorage object provides a set of Java object
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    42
// references (oop values), which clients refer to via oop* handles to the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    43
// associated OopStorage entries.  Clients allocate entries to create a
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    44
// (possibly weak) reference to a Java object, use that reference, and release
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    45
// the reference when no longer needed.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    46
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    47
// The garbage collector must know about all OopStorage objects and their
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    48
// reference strength.  OopStorage provides the garbage collector with support
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    49
// for iteration over all the allocated entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    50
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    51
// There are several categories of interaction with an OopStorage object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    52
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    53
// (1) allocation and release of entries, by the mutator or the VM.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    54
// (2) iteration by the garbage collector, possibly concurrent with mutator.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    55
// (3) iteration by other, non-GC, tools (only at safepoints).
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    56
// (4) cleanup of unused internal storage, possibly concurrent with mutator.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    57
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    58
// A goal of OopStorage is to make these interactions thread-safe, while
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    59
// minimizing potential lock contention issues within and between these
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    60
// categories.  In particular, support for concurrent iteration by the garbage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    61
// collector, under certain restrictions, is required.  Further, it must not
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    62
// block nor be blocked by other operations for long periods.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    63
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    64
// Internally, OopStorage is a set of Block objects, from which entries are
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    65
// allocated and released.  A block contains an oop[] and a bitmask indicating
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    66
// which entries are in use (have been allocated and not yet released).  New
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    67
// blocks are constructed and added to the storage object when an entry
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    68
// allocation request is made and there are no blocks with unused entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    69
// Blocks may be removed and deleted when empty.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    70
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    71
// There are two important (and somewhat intertwined) protocols governing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    72
// concurrent access to a storage object.  These are the Concurrent Iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    73
// Protocol and the Allocation Protocol.  See the ParState class for a
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    74
// discussion of concurrent iteration and the management of thread
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    75
// interactions for this protocol.  Similarly, see the allocate() function for
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    76
// a discussion of allocation.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    77
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    78
class OopStorage : public CHeapObj<mtGC> {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    79
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    80
  OopStorage(const char* name, Mutex* allocate_mutex, Mutex* active_mutex);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    81
  ~OopStorage();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    82
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    83
  // These count and usage accessors are racy unless at a safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    84
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    85
  // The number of allocated and not yet released entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    86
  size_t allocation_count() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    87
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    88
  // The number of blocks of entries.  Useful for sizing parallel iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    89
  size_t block_count() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    90
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    91
  // The number of blocks with no allocated entries.  Useful for sizing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    92
  // parallel iteration and scheduling block deletion.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    93
  size_t empty_block_count() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    94
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    95
  // Total number of blocks * memory allocation per block, plus
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    96
  // bookkeeping overhead, including this storage object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    97
  size_t total_memory_usage() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    98
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
    99
  enum EntryStatus {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   100
    INVALID_ENTRY,
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   101
    UNALLOCATED_ENTRY,
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   102
    ALLOCATED_ENTRY
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   103
  };
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   104
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   105
  // Locks _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   106
  EntryStatus allocation_status(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   107
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   108
  // Allocates and returns a new entry.  Returns NULL if memory allocation
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   109
  // failed.  Locks _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   110
  // postcondition: *result == NULL.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   111
  oop* allocate();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   112
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   113
  // Deallocates ptr, after setting its value to NULL. Locks _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   114
  // precondition: ptr is a valid allocated entry.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   115
  // precondition: *ptr == NULL.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   116
  void release(const oop* ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   117
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   118
  // Releases all the ptrs.  Possibly faster than individual calls to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   119
  // release(oop*).  Best if ptrs is sorted by address.  Locks
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   120
  // _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   121
  // precondition: All elements of ptrs are valid allocated entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   122
  // precondition: *ptrs[i] == NULL, for i in [0,size).
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   123
  void release(const oop* const* ptrs, size_t size);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   124
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   125
  // Applies f to each allocated entry's location.  f must be a function or
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   126
  // function object.  Assume p is either a const oop* or an oop*, depending
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   127
  // on whether the associated storage is const or non-const, respectively.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   128
  // Then f(p) must be a valid expression.  The result of invoking f(p) must
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   129
  // be implicitly convertible to bool.  Iteration terminates and returns
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   130
  // false if any invocation of f returns false.  Otherwise, the result of
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   131
  // iteration is true.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   132
  // precondition: at safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   133
  template<typename F> bool iterate_safepoint(F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   134
  template<typename F> bool iterate_safepoint(F f) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   135
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   136
  // oops_do and weak_oops_do are wrappers around iterate_safepoint, providing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   137
  // an adaptation layer allowing the use of existing is-alive closures and
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   138
  // OopClosures.  Assume p is either const oop* or oop*, depending on whether
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   139
  // the associated storage is const or non-const, respectively.  Then
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   140
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   141
  // - closure->do_oop(p) must be a valid expression whose value is ignored.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   142
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   143
  // - is_alive->do_object_b(*p) must be a valid expression whose value is
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   144
  // convertible to bool.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   145
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   146
  // For weak_oops_do, if *p == NULL then neither is_alive nor closure will be
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   147
  // invoked for p.  If is_alive->do_object_b(*p) is false, then closure will
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   148
  // not be invoked on p, and *p will be set to NULL.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   149
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   150
  template<typename Closure> void oops_do(Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   151
  template<typename Closure> void oops_do(Closure* closure) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   152
  template<typename Closure> void weak_oops_do(Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   153
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   154
  template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   155
  void weak_oops_do(IsAliveClosure* is_alive, Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   156
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   157
#if INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   158
  // Parallel iteration is for the exclusive use of the GC.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   159
  // Other clients must use serial iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   160
  template<bool concurrent, bool is_const> class ParState;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   161
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   162
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   163
  // Block cleanup functions are for the exclusive use of the GC.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   164
  // Both stop deleting if there is an in-progress concurrent iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   165
  // Concurrent deletion locks both the allocate_mutex and the active_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   166
  void delete_empty_blocks_safepoint(size_t retain = 1);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   167
  void delete_empty_blocks_concurrent(size_t retain = 1);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   168
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   169
  // Debugging and logging support.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   170
  const char* name() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   171
  void print_on(outputStream* st) const PRODUCT_RETURN;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   172
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   173
  // Provides access to storage internals, for unit testing.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   174
  class TestAccess;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   175
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   176
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   177
  class Block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   178
  class BlockList;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   179
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   180
  class BlockEntry VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   181
    friend class BlockList;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   182
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   183
    // Members are mutable, and we deal exclusively with pointers to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   184
    // const, to make const blocks easier to use; a block being const
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   185
    // doesn't prevent modifying its list state.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   186
    mutable const Block* _prev;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   187
    mutable const Block* _next;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   188
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   189
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   190
    BlockEntry(const BlockEntry&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   191
    BlockEntry& operator=(const BlockEntry&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   192
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   193
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   194
    BlockEntry();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   195
    ~BlockEntry();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   196
  };
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   197
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   198
  class BlockList VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   199
    const Block* _head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   200
    const Block* _tail;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   201
    const BlockEntry& (*_get_entry)(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   202
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   203
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   204
    BlockList(const BlockList&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   205
    BlockList& operator=(const BlockList&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   206
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   207
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   208
    BlockList(const BlockEntry& (*get_entry)(const Block& block));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   209
    ~BlockList();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   210
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   211
    Block* head();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   212
    const Block* chead() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   213
    const Block* ctail() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   214
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   215
    Block* prev(Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   216
    Block* next(Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   217
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   218
    const Block* prev(const Block& block) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   219
    const Block* next(const Block& block) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   220
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   221
    void push_front(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   222
    void push_back(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   223
    void unlink(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   224
  };
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   225
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   226
  class Block /* No base class, to avoid messing up alignment requirements */ {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   227
    // _data must be the first non-static data member, for alignment.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   228
    oop _data[BitsPerWord];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   229
    static const unsigned _data_pos = 0; // Position of _data.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   230
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   231
    volatile uintx _allocated_bitmask; // One bit per _data element.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   232
    const OopStorage* _owner;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   233
    void* _memory;              // Unaligned storage containing block.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   234
    BlockEntry _active_entry;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   235
    BlockEntry _allocate_entry;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   236
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   237
    Block(const OopStorage* owner, void* memory);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   238
    ~Block();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   239
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   240
    void check_index(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   241
    unsigned get_index(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   242
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   243
    template<typename F, typename BlockPtr>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   244
    static bool iterate_impl(F f, BlockPtr b);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   245
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   246
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   247
    Block(const Block&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   248
    Block& operator=(const Block&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   249
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   250
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   251
    static const BlockEntry& get_active_entry(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   252
    static const BlockEntry& get_allocate_entry(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   253
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   254
    static size_t allocation_size();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   255
    static size_t allocation_alignment_shift();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   256
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   257
    oop* get_pointer(unsigned index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   258
    const oop* get_pointer(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   259
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   260
    uintx bitmask_for_index(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   261
    uintx bitmask_for_entry(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   262
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   263
    // Allocation bitmask accessors are racy.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   264
    bool is_full() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   265
    bool is_empty() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   266
    uintx allocated_bitmask() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   267
    uintx cmpxchg_allocated_bitmask(uintx new_value, uintx compare_value);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   268
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   269
    bool contains(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   270
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   271
    // Returns NULL if ptr is not in a block or not allocated in that block.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   272
    static Block* block_for_ptr(const OopStorage* owner, const oop* ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   273
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   274
    oop* allocate();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   275
    static Block* new_block(const OopStorage* owner);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   276
    static void delete_block(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   277
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   278
    template<typename F> bool iterate(F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   279
    template<typename F> bool iterate(F f) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   280
  }; // class Block
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   281
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   282
  const char* _name;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   283
  BlockList _active_list;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   284
  BlockList _allocate_list;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   285
  Block* volatile _active_head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   286
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   287
  Mutex* _allocate_mutex;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   288
  Mutex* _active_mutex;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   289
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   290
  // Counts are volatile for racy unlocked accesses.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   291
  volatile size_t _allocation_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   292
  volatile size_t _block_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   293
  volatile size_t _empty_block_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   294
  // mutable because this gets set even for const iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   295
  mutable bool _concurrent_iteration_active;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   296
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   297
  Block* find_block_or_null(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   298
  bool is_valid_block_locked_or_safepoint(const Block* block) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   299
  EntryStatus allocation_status_validating_block(const Block* block, const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   300
  void check_release(const Block* block, const oop* ptr) const NOT_DEBUG_RETURN;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   301
  void release_from_block(Block& block, uintx release_bitmask);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   302
  void delete_empty_block(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   303
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   304
  static void assert_at_safepoint() NOT_DEBUG_RETURN;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   305
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   306
  template<typename F, typename Storage>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   307
  static bool iterate_impl(F f, Storage* storage);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   308
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   309
#if INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   310
  // Implementation support for parallel iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   311
  class BasicParState;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   312
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   313
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   314
  // Wrapper for OopClosure-style function, so it can be used with
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   315
  // iterate.  Assume p is of type oop*.  Then cl->do_oop(p) must be a
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   316
  // valid expression whose value may be ignored.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   317
  template<typename Closure> class OopFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   318
  template<typename Closure> static OopFn<Closure> oop_fn(Closure* cl);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   319
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   320
  // Wrapper for BoolObjectClosure + iteration handler pair, so they
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   321
  // can be used with iterate.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   322
  template<typename IsAlive, typename F> class IfAliveFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   323
  template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   324
  static IfAliveFn<IsAlive, F> if_alive_fn(IsAlive* is_alive, F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   325
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   326
  // Wrapper for iteration handler, automatically skipping NULL entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   327
  template<typename F> class SkipNullFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   328
  template<typename F> static SkipNullFn<F> skip_null_fn(F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   329
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   330
  // Wrapper for iteration handler; ignore handler result and return true.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   331
  template<typename F> class AlwaysTrueFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   332
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   333
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   334
inline OopStorage::Block* OopStorage::BlockList::head() {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   335
  return const_cast<Block*>(_head);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   336
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   337
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   338
inline const OopStorage::Block* OopStorage::BlockList::chead() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   339
  return _head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   340
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   341
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   342
inline const OopStorage::Block* OopStorage::BlockList::ctail() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   343
  return _tail;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   344
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   345
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   346
inline OopStorage::Block* OopStorage::BlockList::prev(Block& block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   347
  return const_cast<Block*>(_get_entry(block)._prev);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   348
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   349
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   350
inline OopStorage::Block* OopStorage::BlockList::next(Block& block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   351
  return const_cast<Block*>(_get_entry(block)._next);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   352
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   353
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   354
inline const OopStorage::Block* OopStorage::BlockList::prev(const Block& block) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   355
  return _get_entry(block)._prev;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   356
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   357
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   358
inline const OopStorage::Block* OopStorage::BlockList::next(const Block& block) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   359
  return _get_entry(block)._next;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   360
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   361
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   362
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   363
class OopStorage::OopFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   364
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   365
  explicit OopFn(Closure* cl) : _cl(cl) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   366
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   367
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   368
  bool operator()(OopPtr ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   369
    _cl->do_oop(ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   370
    return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   371
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   372
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   373
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   374
  Closure* _cl;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   375
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   376
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   377
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   378
inline OopStorage::OopFn<Closure> OopStorage::oop_fn(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   379
  return OopFn<Closure>(cl);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   380
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   381
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   382
template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   383
class OopStorage::IfAliveFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   384
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   385
  IfAliveFn(IsAlive* is_alive, F f) : _is_alive(is_alive), _f(f) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   386
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   387
  bool operator()(oop* ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   388
    bool result = true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   389
    oop v = *ptr;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   390
    if (v != NULL) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   391
      if (_is_alive->do_object_b(v)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   392
        result = _f(ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   393
      } else {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   394
        *ptr = NULL;            // Clear dead value.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   395
      }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   396
    }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   397
    return result;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   398
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   399
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   400
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   401
  IsAlive* _is_alive;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   402
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   403
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   404
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   405
template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   406
inline OopStorage::IfAliveFn<IsAlive, F> OopStorage::if_alive_fn(IsAlive* is_alive, F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   407
  return IfAliveFn<IsAlive, F>(is_alive, f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   408
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   409
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   410
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   411
class OopStorage::SkipNullFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   412
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   413
  SkipNullFn(F f) : _f(f) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   414
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   415
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   416
  bool operator()(OopPtr ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   417
    return (*ptr != NULL) ? _f(ptr) : true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   418
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   419
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   420
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   421
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   422
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   423
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   424
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   425
inline OopStorage::SkipNullFn<F> OopStorage::skip_null_fn(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   426
  return SkipNullFn<F>(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   427
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   428
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   429
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   430
class OopStorage::AlwaysTrueFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   431
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   432
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   433
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   434
  AlwaysTrueFn(F f) : _f(f) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   435
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   436
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   437
  bool operator()(OopPtr ptr) const { _f(ptr); return true; }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   438
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   439
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   440
// Inline Block accesses for use in iteration inner loop.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   441
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   442
inline void OopStorage::Block::check_index(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   443
  assert(index < ARRAY_SIZE(_data), "Index out of bounds: %u", index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   444
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   445
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   446
inline oop* OopStorage::Block::get_pointer(unsigned index) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   447
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   448
  return &_data[index];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   449
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   450
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   451
inline const oop* OopStorage::Block::get_pointer(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   452
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   453
  return &_data[index];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   454
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   455
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   456
inline uintx OopStorage::Block::allocated_bitmask() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   457
  return _allocated_bitmask;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   458
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   459
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   460
inline uintx OopStorage::Block::bitmask_for_index(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   461
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   462
  return uintx(1) << index;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   463
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   464
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   465
// Provide const or non-const iteration, depending on whether BlockPtr
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   466
// is const Block* or Block*, respectively.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   467
template<typename F, typename BlockPtr> // BlockPtr := [const] Block*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   468
inline bool OopStorage::Block::iterate_impl(F f, BlockPtr block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   469
  uintx bitmask = block->allocated_bitmask();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   470
  while (bitmask != 0) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   471
    unsigned index = count_trailing_zeros(bitmask);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   472
    bitmask ^= block->bitmask_for_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   473
    if (!f(block->get_pointer(index))) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   474
      return false;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   475
    }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   476
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   477
  return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   478
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   479
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   480
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   481
inline bool OopStorage::Block::iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   482
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   483
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   484
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   485
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   486
inline bool OopStorage::Block::iterate(F f) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   487
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   488
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   489
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   490
//////////////////////////////////////////////////////////////////////////////
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   491
// Support for serial iteration, always at a safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   492
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   493
// Provide const or non-const iteration, depending on whether Storage is
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   494
// const OopStorage* or OopStorage*, respectively.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   495
template<typename F, typename Storage> // Storage := [const] OopStorage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   496
inline bool OopStorage::iterate_impl(F f, Storage* storage) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   497
  assert_at_safepoint();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   498
  // Propagate const/non-const iteration to the block layer, by using
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   499
  // const or non-const blocks as corresponding to Storage.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   500
  typedef typename Conditional<IsConst<Storage>::value, const Block*, Block*>::type BlockPtr;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   501
  for (BlockPtr block = storage->_active_head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   502
       block != NULL;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   503
       block = storage->_active_list.next(*block)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   504
    if (!block->iterate(f)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   505
      return false;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   506
    }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   507
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   508
  return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   509
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   510
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   511
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   512
inline bool OopStorage::iterate_safepoint(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   513
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   514
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   515
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   516
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   517
inline bool OopStorage::iterate_safepoint(F f) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   518
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   519
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   520
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   521
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   522
inline void OopStorage::oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   523
  iterate_safepoint(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   524
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   525
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   526
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   527
inline void OopStorage::oops_do(Closure* cl) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   528
  iterate_safepoint(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   529
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   530
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   531
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   532
inline void OopStorage::weak_oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   533
  iterate_safepoint(skip_null_fn(oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   534
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   535
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   536
template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   537
inline void OopStorage::weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   538
  iterate_safepoint(if_alive_fn(is_alive, oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   539
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   540
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   541
#if INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   542
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   543
//////////////////////////////////////////////////////////////////////////////
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   544
// Support for parallel and optionally concurrent state iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   545
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   546
// Parallel iteration is for the exclusive use of the GC.  Other iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   547
// clients must use serial iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   548
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   549
// Concurrent Iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   550
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   551
// Iteration involves the _active_list, which contains all of the blocks owned
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   552
// by a storage object.  This is a doubly-linked list, linked through
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   553
// dedicated fields in the blocks.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   554
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   555
// At most one concurrent ParState can exist at a time for a given storage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   556
// object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   557
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   558
// A concurrent ParState sets the associated storage's
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   559
// _concurrent_iteration_active flag true when the state is constructed, and
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   560
// sets it false when the state is destroyed.  These assignments are made with
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   561
// _active_mutex locked.  Meanwhile, empty block deletion is not done while
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   562
// _concurrent_iteration_active is true.  The flag check and the dependent
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   563
// removal of a block from the _active_list is performed with _active_mutex
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   564
// locked.  This prevents concurrent iteration and empty block deletion from
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   565
// interfering with with each other.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   566
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   567
// Both allocate() and delete_empty_blocks_concurrent() lock the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   568
// _allocate_mutex while performing their respective list manipulations,
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   569
// preventing them from interfering with each other.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   570
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   571
// When allocate() creates a new block, it is added to the front of the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   572
// _active_list.  Then _active_head is set to the new block.  When concurrent
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   573
// iteration is started (by a parallel worker thread calling the state's
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   574
// iterate() function), the current _active_head is used as the initial block
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   575
// for the iteration, with iteration proceeding down the list headed by that
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   576
// block.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   577
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   578
// As a result, the list over which concurrent iteration operates is stable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   579
// However, once the iteration is started, later allocations may add blocks to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   580
// the front of the list that won't be examined by the iteration.  And while
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   581
// the list is stable, concurrent allocate() and release() operations may
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   582
// change the set of allocated entries in a block at any time during the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   583
// iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   584
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   585
// As a result, a concurrent iteration handler must accept that some
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   586
// allocations and releases that occur after the iteration started will not be
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   587
// seen by the iteration.  Further, some may overlap examination by the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   588
// iteration.  To help with this, allocate() and release() have an invariant
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   589
// that an entry's value must be NULL when it is not in use.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   590
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   591
// An in-progress delete_empty_blocks_concurrent() operation can contend with
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   592
// the start of a concurrent iteration over the _active_mutex.  Since both are
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   593
// under GC control, that potential contention can be eliminated by never
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   594
// scheduling both operations to run at the same time.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   595
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   596
// ParState<concurrent, is_const>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   597
//   concurrent must be true if iteration is concurrent with the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   598
//   mutator, false if iteration is at a safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   599
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   600
//   is_const must be true if the iteration is over a constant storage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   601
//   object, false if the iteration may modify the storage object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   602
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   603
// ParState([const] OopStorage* storage)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   604
//   Construct an object for managing an iteration over storage.  For a
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   605
//   concurrent ParState, empty block deletion for the associated storage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   606
//   is inhibited for the life of the ParState.  There can be no more
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   607
//   than one live concurrent ParState at a time for a given storage object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   608
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   609
// template<typename F> void iterate(F f)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   610
//   Repeatedly claims a block from the associated storage that has
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   611
//   not been processed by this iteration (possibly by other threads),
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   612
//   and applies f to each entry in the claimed block. Assume p is of
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   613
//   type const oop* or oop*, according to is_const. Then f(p) must be
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   614
//   a valid expression whose value is ignored.  Concurrent uses must
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   615
//   be prepared for an entry's value to change at any time, due to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   616
//   mutator activity.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   617
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   618
// template<typename Closure> void oops_do(Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   619
//   Wrapper around iterate, providing an adaptation layer allowing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   620
//   the use of OopClosures and similar objects for iteration.  Assume
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   621
//   p is of type const oop* or oop*, according to is_const.  Then
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   622
//   cl->do_oop(p) must be a valid expression whose value is ignored.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   623
//   Concurrent uses must be prepared for the entry's value to change
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   624
//   at any time, due to mutator activity.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   625
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   626
// Optional operations, provided only if !concurrent && !is_const.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   627
// These are not provided when is_const, because the storage object
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   628
// may be modified by the iteration infrastructure, even if the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   629
// provided closure doesn't modify the storage object.  These are not
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   630
// provided when concurrent because any pre-filtering behavior by the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   631
// iteration infrastructure is inappropriate for concurrent iteration;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   632
// modifications of the storage by the mutator could result in the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   633
// pre-filtering being applied (successfully or not) to objects that
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   634
// are unrelated to what the closure finds in the entry.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   635
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   636
// template<typename Closure> void weak_oops_do(Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   637
// template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   638
// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   639
//   Wrappers around iterate, providing an adaptation layer allowing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   640
//   the use of is-alive closures and OopClosures for iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   641
//   Assume p is of type oop*.  Then
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   642
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   643
//   - cl->do_oop(p) must be a valid expression whose value is ignored.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   644
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   645
//   - is_alive->do_object_b(*p) must be a valid expression whose value
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   646
//   is convertible to bool.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   647
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   648
//   If *p == NULL then neither is_alive nor cl will be invoked for p.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   649
//   If is_alive->do_object_b(*p) is false, then cl will not be
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   650
//   invoked on p.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   651
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   652
class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   653
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   654
  BasicParState(OopStorage* storage, bool concurrent);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   655
  ~BasicParState();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   656
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   657
  template<bool is_const, typename F> void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   658
    // Wrap f in ATF so we can use Block::iterate.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   659
    AlwaysTrueFn<F> atf_f(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   660
    ensure_iteration_started();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   661
    typename Conditional<is_const, const Block*, Block*>::type block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   662
    while ((block = claim_next_block()) != NULL) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   663
      block->iterate(atf_f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   664
    }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   665
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   666
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   667
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   668
  OopStorage* _storage;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   669
  void* volatile _next_block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   670
  bool _concurrent;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   671
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   672
  // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   673
  BasicParState(const BasicParState&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   674
  BasicParState& operator=(const BasicParState&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   675
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   676
  void update_iteration_state(bool value);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   677
  void ensure_iteration_started();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   678
  Block* claim_next_block();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   679
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   680
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   681
template<bool concurrent, bool is_const>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   682
class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   683
  BasicParState _basic_state;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   684
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   685
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   686
  ParState(const OopStorage* storage) :
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   687
    // For simplicity, always recorded as non-const.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   688
    _basic_state(const_cast<OopStorage*>(storage), concurrent)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   689
  {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   690
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   691
  template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   692
  void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   693
    _basic_state.template iterate<is_const>(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   694
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   695
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   696
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   697
  void oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   698
    this->iterate(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   699
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   700
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   701
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   702
template<>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   703
class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   704
  BasicParState _basic_state;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   705
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   706
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   707
  ParState(OopStorage* storage) :
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   708
    _basic_state(storage, false)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   709
  {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   710
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   711
  template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   712
  void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   713
    _basic_state.template iterate<false>(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   714
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   715
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   716
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   717
  void oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   718
    this->iterate(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   719
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   720
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   721
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   722
  void weak_oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   723
    this->iterate(skip_null_fn(oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   724
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   725
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   726
  template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   727
  void weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   728
    this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   729
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   730
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   731
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   732
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   733
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   734
#endif // include guard