src/hotspot/share/gc/shared/oopStorage.hpp
author kbarrett
Tue, 23 Jan 2018 14:27:10 -0500
changeset 48808 2b0b7f222800
parent 48806 51fc22e5fb00
child 48816 3495d6050efe
permissions -rw-r--r--
8195690: JNI GetObjectRefType doesn't handle NULL Summary: Properly handle NULL, add some non-NULL preconditions. Reviewed-by: dholmes, mdoerr
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.
48808
2b0b7f222800 8195690: JNI GetObjectRefType doesn't handle NULL
kbarrett
parents: 48806
diff changeset
   106
  // precondition: ptr != NULL.
48787
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   107
  EntryStatus allocation_status(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   108
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   109
  // 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
   110
  // failed.  Locks _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   111
  // postcondition: *result == NULL.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   112
  oop* allocate();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   113
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   114
  // 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
   115
  // precondition: ptr is a valid allocated entry.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   116
  // precondition: *ptr == NULL.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   117
  void release(const oop* ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   118
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   119
  // Releases all the ptrs.  Possibly faster than individual calls to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   120
  // release(oop*).  Best if ptrs is sorted by address.  Locks
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   121
  // _allocate_mutex.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   122
  // precondition: All elements of ptrs are valid allocated entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   123
  // precondition: *ptrs[i] == NULL, for i in [0,size).
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   124
  void release(const oop* const* ptrs, size_t size);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   125
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   126
  // 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
   127
  // 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
   128
  // 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
   129
  // 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
   130
  // be implicitly convertible to bool.  Iteration terminates and returns
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   131
  // 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
   132
  // iteration is true.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   133
  // precondition: at safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   134
  template<typename F> bool iterate_safepoint(F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   135
  template<typename F> bool iterate_safepoint(F f) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   136
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   137
  // 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
   138
  // 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
   139
  // 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
   140
  // the associated storage is const or non-const, respectively.  Then
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   141
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   142
  // - 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
   143
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   144
  // - 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
   145
  // convertible to bool.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   146
  //
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   147
  // 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
   148
  // 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
   149
  // 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
   150
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   151
  template<typename Closure> void oops_do(Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   152
  template<typename Closure> void oops_do(Closure* closure) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   153
  template<typename Closure> void weak_oops_do(Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   154
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   155
  template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   156
  void weak_oops_do(IsAliveClosure* is_alive, Closure* closure);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   157
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   158
#if INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   159
  // Parallel iteration is for the exclusive use of the GC.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   160
  // Other clients must use serial iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   161
  template<bool concurrent, bool is_const> class ParState;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   162
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   163
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   164
  // 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
   165
  // 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
   166
  // 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
   167
  void delete_empty_blocks_safepoint(size_t retain = 1);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   168
  void delete_empty_blocks_concurrent(size_t retain = 1);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   169
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   170
  // Debugging and logging support.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   171
  const char* name() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   172
  void print_on(outputStream* st) const PRODUCT_RETURN;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   173
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   174
  // Provides access to storage internals, for unit testing.
48806
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   175
  // Declare, but not define, the public class OopStorage::TestAccess.
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   176
  // That class is defined as part of the unit-test. It "exports" the needed
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   177
  // private types by providing public typedefs for them.
48787
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   178
  class TestAccess;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   179
48806
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   180
  // xlC on AIX can't compile test_oopStorage.cpp with following private
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   181
  // classes. C++03 introduced access for nested classes with DR45, but xlC
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   182
  // version 12 rejects it.
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   183
NOT_AIX( private: )
48787
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   184
  class Block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   185
  class BlockList;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   186
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   187
  class BlockEntry VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   188
    friend class BlockList;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   189
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   190
    // Members are mutable, and we deal exclusively with pointers to
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   191
    // 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
   192
    // doesn't prevent modifying its list state.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   193
    mutable const Block* _prev;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   194
    mutable const Block* _next;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   195
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   196
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   197
    BlockEntry(const BlockEntry&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   198
    BlockEntry& operator=(const BlockEntry&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   199
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   200
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   201
    BlockEntry();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   202
    ~BlockEntry();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   203
  };
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   204
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   205
  class BlockList VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   206
    const Block* _head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   207
    const Block* _tail;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   208
    const BlockEntry& (*_get_entry)(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   209
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   210
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   211
    BlockList(const BlockList&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   212
    BlockList& operator=(const BlockList&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   213
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   214
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   215
    BlockList(const BlockEntry& (*get_entry)(const Block& block));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   216
    ~BlockList();
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
    Block* head();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   219
    const Block* chead() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   220
    const Block* ctail() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   221
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   222
    Block* prev(Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   223
    Block* next(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
    const Block* prev(const Block& block) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   226
    const Block* next(const Block& block) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   227
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   228
    void push_front(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   229
    void push_back(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   230
    void unlink(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   231
  };
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   232
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   233
  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
   234
    // _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
   235
    oop _data[BitsPerWord];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   236
    static const unsigned _data_pos = 0; // Position of _data.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   237
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   238
    volatile uintx _allocated_bitmask; // One bit per _data element.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   239
    const OopStorage* _owner;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   240
    void* _memory;              // Unaligned storage containing block.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   241
    BlockEntry _active_entry;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   242
    BlockEntry _allocate_entry;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   243
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   244
    Block(const OopStorage* owner, void* memory);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   245
    ~Block();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   246
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   247
    void check_index(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   248
    unsigned get_index(const oop* ptr) const;
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
    template<typename F, typename BlockPtr>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   251
    static bool iterate_impl(F f, BlockPtr b);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   252
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   253
    // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   254
    Block(const Block&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   255
    Block& operator=(const Block&);
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
  public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   258
    static const BlockEntry& get_active_entry(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   259
    static const BlockEntry& get_allocate_entry(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   260
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   261
    static size_t allocation_size();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   262
    static size_t allocation_alignment_shift();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   263
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   264
    oop* get_pointer(unsigned index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   265
    const oop* get_pointer(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   266
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   267
    uintx bitmask_for_index(unsigned index) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   268
    uintx bitmask_for_entry(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   269
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   270
    // Allocation bitmask accessors are racy.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   271
    bool is_full() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   272
    bool is_empty() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   273
    uintx allocated_bitmask() const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   274
    uintx cmpxchg_allocated_bitmask(uintx new_value, uintx compare_value);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   275
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   276
    bool contains(const oop* ptr) const;
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
    // 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
   279
    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
   280
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   281
    oop* allocate();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   282
    static Block* new_block(const OopStorage* owner);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   283
    static void delete_block(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   284
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   285
    template<typename F> bool iterate(F f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   286
    template<typename F> bool iterate(F f) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   287
  }; // class Block
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   288
48806
51fc22e5fb00 8195691: AIX build broken after 8194312
mdoerr
parents: 48787
diff changeset
   289
private:
48787
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   290
  const char* _name;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   291
  BlockList _active_list;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   292
  BlockList _allocate_list;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   293
  Block* volatile _active_head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   294
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   295
  Mutex* _allocate_mutex;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   296
  Mutex* _active_mutex;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   297
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   298
  // Counts are volatile for racy unlocked accesses.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   299
  volatile size_t _allocation_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   300
  volatile size_t _block_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   301
  volatile size_t _empty_block_count;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   302
  // mutable because this gets set even for const iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   303
  mutable bool _concurrent_iteration_active;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   304
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   305
  Block* find_block_or_null(const oop* ptr) const;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   306
  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
   307
  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
   308
  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
   309
  void release_from_block(Block& block, uintx release_bitmask);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   310
  void delete_empty_block(const Block& block);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   311
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   312
  static void assert_at_safepoint() NOT_DEBUG_RETURN;
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
  template<typename F, typename Storage>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   315
  static bool iterate_impl(F f, Storage* storage);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   316
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   317
#if INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   318
  // Implementation support for parallel iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   319
  class BasicParState;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   320
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   321
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   322
  // 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
   323
  // 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
   324
  // valid expression whose value may be ignored.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   325
  template<typename Closure> class OopFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   326
  template<typename Closure> static OopFn<Closure> oop_fn(Closure* cl);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   327
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   328
  // Wrapper for BoolObjectClosure + iteration handler pair, so they
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   329
  // can be used with iterate.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   330
  template<typename IsAlive, typename F> class IfAliveFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   331
  template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   332
  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
   333
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   334
  // Wrapper for iteration handler, automatically skipping NULL entries.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   335
  template<typename F> class SkipNullFn;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   336
  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
   337
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   338
  // Wrapper for iteration handler; ignore handler result and return true.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   339
  template<typename F> class AlwaysTrueFn;
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 OopStorage::Block* OopStorage::BlockList::head() {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   343
  return const_cast<Block*>(_head);
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 const OopStorage::Block* OopStorage::BlockList::chead() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   347
  return _head;
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 const OopStorage::Block* OopStorage::BlockList::ctail() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   351
  return _tail;
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 OopStorage::Block* OopStorage::BlockList::prev(Block& block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   355
  return const_cast<Block*>(_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 OopStorage::Block* OopStorage::BlockList::next(Block& block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   359
  return const_cast<Block*>(_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
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
   363
  return _get_entry(block)._prev;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   364
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   365
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   366
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
   367
  return _get_entry(block)._next;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   368
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   369
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   370
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   371
class OopStorage::OopFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   372
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   373
  explicit OopFn(Closure* cl) : _cl(cl) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   374
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   375
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   376
  bool operator()(OopPtr ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   377
    _cl->do_oop(ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   378
    return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   379
  }
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
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   382
  Closure* _cl;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   383
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   384
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   385
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   386
inline OopStorage::OopFn<Closure> OopStorage::oop_fn(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   387
  return OopFn<Closure>(cl);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   388
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   389
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   390
template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   391
class OopStorage::IfAliveFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   392
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   393
  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
   394
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   395
  bool operator()(oop* ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   396
    bool result = true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   397
    oop v = *ptr;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   398
    if (v != NULL) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   399
      if (_is_alive->do_object_b(v)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   400
        result = _f(ptr);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   401
      } else {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   402
        *ptr = NULL;            // Clear dead value.
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
    return result;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   406
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   407
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   408
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   409
  IsAlive* _is_alive;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   410
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   411
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   412
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   413
template<typename IsAlive, typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   414
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
   415
  return IfAliveFn<IsAlive, F>(is_alive, f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   416
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   417
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   418
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   419
class OopStorage::SkipNullFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   420
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   421
  SkipNullFn(F f) : _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
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   424
  bool operator()(OopPtr ptr) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   425
    return (*ptr != NULL) ? _f(ptr) : true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   426
  }
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
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   429
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   430
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   431
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   432
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   433
inline OopStorage::SkipNullFn<F> OopStorage::skip_null_fn(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   434
  return SkipNullFn<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
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   437
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   438
class OopStorage::AlwaysTrueFn VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   439
  F _f;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   440
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   441
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   442
  AlwaysTrueFn(F f) : _f(f) {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   443
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   444
  template<typename OopPtr>     // [const] oop*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   445
  bool operator()(OopPtr ptr) const { _f(ptr); return true; }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   446
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   447
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   448
// Inline Block accesses for use in iteration inner loop.
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
inline void OopStorage::Block::check_index(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   451
  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
   452
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   453
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   454
inline oop* OopStorage::Block::get_pointer(unsigned index) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   455
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   456
  return &_data[index];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   457
}
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
inline const oop* OopStorage::Block::get_pointer(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   460
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   461
  return &_data[index];
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   462
}
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
inline uintx OopStorage::Block::allocated_bitmask() const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   465
  return _allocated_bitmask;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   466
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   467
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   468
inline uintx OopStorage::Block::bitmask_for_index(unsigned index) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   469
  check_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   470
  return uintx(1) << index;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   471
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   472
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   473
// Provide const or non-const iteration, depending on whether BlockPtr
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   474
// is const Block* or Block*, respectively.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   475
template<typename F, typename BlockPtr> // BlockPtr := [const] Block*
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   476
inline bool OopStorage::Block::iterate_impl(F f, BlockPtr block) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   477
  uintx bitmask = block->allocated_bitmask();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   478
  while (bitmask != 0) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   479
    unsigned index = count_trailing_zeros(bitmask);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   480
    bitmask ^= block->bitmask_for_index(index);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   481
    if (!f(block->get_pointer(index))) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   482
      return false;
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
  return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   486
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   487
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   488
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   489
inline bool OopStorage::Block::iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   490
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   491
}
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
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   494
inline bool OopStorage::Block::iterate(F f) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   495
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   496
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   497
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   498
//////////////////////////////////////////////////////////////////////////////
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   499
// Support for serial iteration, always at a safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   500
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   501
// 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
   502
// const OopStorage* or OopStorage*, respectively.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   503
template<typename F, typename Storage> // Storage := [const] OopStorage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   504
inline bool OopStorage::iterate_impl(F f, Storage* storage) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   505
  assert_at_safepoint();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   506
  // 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
   507
  // const or non-const blocks as corresponding to Storage.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   508
  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
   509
  for (BlockPtr block = storage->_active_head;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   510
       block != NULL;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   511
       block = storage->_active_list.next(*block)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   512
    if (!block->iterate(f)) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   513
      return false;
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
  return true;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   517
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   518
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   519
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   520
inline bool OopStorage::iterate_safepoint(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   521
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   522
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   523
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   524
template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   525
inline bool OopStorage::iterate_safepoint(F f) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   526
  return iterate_impl(f, this);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   527
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   528
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   529
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   530
inline void OopStorage::oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   531
  iterate_safepoint(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   532
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   533
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   534
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   535
inline void OopStorage::oops_do(Closure* cl) const {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   536
  iterate_safepoint(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   537
}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   538
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   539
template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   540
inline void OopStorage::weak_oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   541
  iterate_safepoint(skip_null_fn(oop_fn(cl)));
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
template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   545
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
   546
  iterate_safepoint(if_alive_fn(is_alive, oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   547
}
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
#if INCLUDE_ALL_GCS
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
//////////////////////////////////////////////////////////////////////////////
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   552
// Support for parallel and optionally concurrent state iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   553
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   554
// 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
   555
// clients must use serial iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   556
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   557
// Concurrent Iteration
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   558
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   559
// 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
   560
// 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
   561
// dedicated fields in the blocks.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   562
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   563
// 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
   564
// object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   565
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   566
// A concurrent ParState sets the associated storage's
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   567
// _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
   568
// 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
   569
// _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
   570
// _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
   571
// 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
   572
// locked.  This prevents concurrent iteration and empty block deletion from
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   573
// interfering with with each other.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   574
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   575
// Both allocate() and delete_empty_blocks_concurrent() lock the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   576
// _allocate_mutex while performing their respective list manipulations,
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   577
// preventing them from interfering with each other.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   578
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   579
// 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
   580
// _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
   581
// 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
   582
// 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
   583
// 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
   584
// block.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   585
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   586
// 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
   587
// 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
   588
// 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
   589
// the list is stable, concurrent allocate() and release() operations may
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   590
// 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
   591
// iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   592
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   593
// 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
   594
// 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
   595
// 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
   596
// 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
   597
// 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
   598
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   599
// 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
   600
// 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
   601
// 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
   602
// scheduling both operations to run at the same time.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   603
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   604
// ParState<concurrent, is_const>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   605
//   concurrent must be true if iteration is concurrent with the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   606
//   mutator, false if iteration is at a safepoint.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   607
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   608
//   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
   609
//   object, false if the iteration may modify the storage object.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   610
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   611
// ParState([const] OopStorage* storage)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   612
//   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
   613
//   concurrent ParState, empty block deletion for the associated storage
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   614
//   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
   615
//   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
   616
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   617
// template<typename F> void iterate(F f)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   618
//   Repeatedly claims a block from the associated storage that has
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   619
//   not been processed by this iteration (possibly by other threads),
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   620
//   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
   621
//   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
   622
//   a valid expression whose value is ignored.  Concurrent uses must
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   623
//   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
   624
//   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
// template<typename Closure> void oops_do(Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   627
//   Wrapper around iterate, providing an adaptation layer allowing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   628
//   the use of OopClosures and similar objects for iteration.  Assume
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   629
//   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
   630
//   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
   631
//   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
   632
//   at any time, due to mutator activity.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   633
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   634
// Optional operations, provided only if !concurrent && !is_const.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   635
// 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
   636
// may be modified by the iteration infrastructure, even if the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   637
// 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
   638
// provided when concurrent because any pre-filtering behavior by the
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   639
// iteration infrastructure is inappropriate for concurrent iteration;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   640
// 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
   641
// pre-filtering being applied (successfully or not) to objects that
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   642
// are unrelated to what the closure finds in the entry.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   643
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   644
// template<typename Closure> void weak_oops_do(Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   645
// template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   646
// void weak_oops_do(IsAliveClosure* is_alive, Closure* cl)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   647
//   Wrappers around iterate, providing an adaptation layer allowing
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   648
//   the use of is-alive closures and OopClosures for iteration.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   649
//   Assume p is of type oop*.  Then
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   650
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   651
//   - 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
   652
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   653
//   - 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
   654
//   is convertible to bool.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   655
//
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   656
//   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
   657
//   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
   658
//   invoked on p.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   659
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   660
class OopStorage::BasicParState VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   661
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   662
  BasicParState(OopStorage* storage, bool concurrent);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   663
  ~BasicParState();
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
  template<bool is_const, typename F> void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   666
    // Wrap f in ATF so we can use Block::iterate.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   667
    AlwaysTrueFn<F> atf_f(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   668
    ensure_iteration_started();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   669
    typename Conditional<is_const, const Block*, Block*>::type block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   670
    while ((block = claim_next_block()) != NULL) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   671
      block->iterate(atf_f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   672
    }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   673
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   674
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   675
private:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   676
  OopStorage* _storage;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   677
  void* volatile _next_block;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   678
  bool _concurrent;
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
  // Noncopyable.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   681
  BasicParState(const BasicParState&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   682
  BasicParState& operator=(const BasicParState&);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   683
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   684
  void update_iteration_state(bool value);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   685
  void ensure_iteration_started();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   686
  Block* claim_next_block();
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   687
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   688
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   689
template<bool concurrent, bool is_const>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   690
class OopStorage::ParState VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   691
  BasicParState _basic_state;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   692
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   693
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   694
  ParState(const OopStorage* storage) :
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   695
    // For simplicity, always recorded as non-const.
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   696
    _basic_state(const_cast<OopStorage*>(storage), concurrent)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   697
  {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   698
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   699
  template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   700
  void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   701
    _basic_state.template iterate<is_const>(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   702
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   703
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   704
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   705
  void oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   706
    this->iterate(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   707
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   708
};
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
template<>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   711
class OopStorage::ParState<false, false> VALUE_OBJ_CLASS_SPEC {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   712
  BasicParState _basic_state;
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   713
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   714
public:
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   715
  ParState(OopStorage* storage) :
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   716
    _basic_state(storage, false)
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   717
  {}
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   718
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   719
  template<typename F>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   720
  void iterate(F f) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   721
    _basic_state.template iterate<false>(f);
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   722
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   723
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   724
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   725
  void oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   726
    this->iterate(oop_fn(cl));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   727
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   728
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   729
  template<typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   730
  void weak_oops_do(Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   731
    this->iterate(skip_null_fn(oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   732
  }
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
  template<typename IsAliveClosure, typename Closure>
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   735
  void weak_oops_do(IsAliveClosure* is_alive, Closure* cl) {
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   736
    this->iterate(if_alive_fn(is_alive, oop_fn(cl)));
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   737
  }
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   738
};
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   739
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   740
#endif // INCLUDE_ALL_GCS
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   741
7638bf98a312 8194312: Support parallel and concurrent JNI global handle processing
kbarrett
parents:
diff changeset
   742
#endif // include guard