hotspot/src/share/vm/prims/jvmtiTagMap.cpp
author tschatzl
Wed, 11 Sep 2013 16:25:02 +0200
changeset 19986 33d188c66ed9
parent 17370 59a0620561fa
child 20282 7f9cbdf89af2
permissions -rw-r--r--
8010722: assert: failed: heap size is too big for compressed oops Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation. Reviewed-by: stefank, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
17370
59a0620561fa 8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents: 17087
diff changeset
     2
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4571
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4571
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4571
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "classfile/symbolTable.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "classfile/vmSymbols.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "jvmtifiles/jvmtiEnv.hpp"
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
    30
#include "oops/instanceMirrorKlass.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "oops/objArrayKlass.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "oops/oop.inline2.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "prims/jvmtiEventController.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "prims/jvmtiEventController.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "prims/jvmtiExport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "prims/jvmtiImpl.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "prims/jvmtiTagMap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    38
#include "runtime/biasedLocking.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    39
#include "runtime/javaCalls.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    40
#include "runtime/jniHandles.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    41
#include "runtime/mutex.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    42
#include "runtime/mutexLocker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    43
#include "runtime/reflectionUtils.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    44
#include "runtime/vframe.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    45
#include "runtime/vmThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    46
#include "runtime/vm_operations.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    47
#include "services/serviceUtil.hpp"
15482
470d0b0c09f1 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 14488
diff changeset
    48
#include "utilities/macros.hpp"
470d0b0c09f1 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 14488
diff changeset
    49
#if INCLUDE_ALL_GCS
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    50
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
15482
470d0b0c09f1 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 14488
diff changeset
    51
#endif // INCLUDE_ALL_GCS
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// JvmtiTagHashmapEntry
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
//
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    55
// Each entry encapsulates a reference to the tagged object
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// and the tag value. In addition an entry includes a next pointer which
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// is used to chain entries together.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
    59
class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  friend class JvmtiTagMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    63
  oop _object;                          // tagged object
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  jlong _tag;                           // the tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  JvmtiTagHashmapEntry* _next;          // next on the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    67
  inline void init(oop object, jlong tag) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    _object = object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    _tag = tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    _next = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  // constructor
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    74
  JvmtiTagHashmapEntry(oop object, jlong tag)         { init(object, tag); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  // accessor methods
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    79
  inline oop object() const                           { return _object; }
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    80
  inline oop* object_addr()                           { return &_object; }
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    81
  inline jlong tag() const                            { return _tag; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  inline void set_tag(jlong tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    assert(tag != 0, "can't be zero");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    _tag = tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  inline JvmtiTagHashmapEntry* next() const             { return _next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  inline void set_next(JvmtiTagHashmapEntry* next)      { _next = next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
// JvmtiTagHashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
// A hashmap is essentially a table of pointers to entries. Entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
// are hashed to a location, or position in the table, and then
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
// chained from that location. The "key" for hashing is address of
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
    98
// the object, or oop. The "value" is the tag value.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
// A hashmap maintains a count of the number entries in the hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
// and resizes if the number of entries exceeds a given threshold.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
// The threshold is specified as a percentage of the size - for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
// example a threshold of 0.75 will trigger the hashmap to resize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
// if the number of entries is >75% of table size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
// A hashmap provides functions for adding, removing, and finding
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
// entries. It also provides a function to iterate over all entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
// in the hashmap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   110
class JvmtiTagHashmap : public CHeapObj<mtInternal> {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  friend class JvmtiTagMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    small_trace_threshold  = 10000,                  // threshold for tracing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
    medium_trace_threshold = 100000,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
    large_trace_threshold  = 1000000,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    initial_trace_threshold = small_trace_threshold
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  static int _sizes[];                  // array of possible hashmap sizes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  int _size;                            // actual size of the table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  int _size_index;                      // index into size table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  int _entry_count;                     // number of entries in the hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  float _load_factor;                   // load factor as a % of the size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  int _resize_threshold;                // computed threshold to trigger resizing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  bool _resizing_enabled;               // indicates if hashmap can resize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  int _trace_threshold;                 // threshold for trace messages
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  JvmtiTagHashmapEntry** _table;        // the table of entries.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  // private accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  int resize_threshold() const                  { return _resize_threshold; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  int trace_threshold() const                   { return _trace_threshold; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // initialize the hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  void init(int size_index=0, float load_factor=4.0f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    int initial_size =  _sizes[size_index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    _size_index = size_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    _size = initial_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    _entry_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    if (TraceJVMTIObjectTagging) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      _trace_threshold = initial_trace_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      _trace_threshold = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    _load_factor = load_factor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    _resize_threshold = (int)(_load_factor * _size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    _resizing_enabled = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*);
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   154
    _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    if (_table == NULL) {
17087
f0b76c4c93a0 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 15482
diff changeset
   156
      vm_exit_out_of_memory(s, OOM_MALLOC_ERROR,
f0b76c4c93a0 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 15482
diff changeset
   157
        "unable to allocate initial hashtable for jvmti object tags");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    for (int i=0; i<initial_size; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
      _table[i] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  // hash a given key (oop) with the specified size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  static unsigned int hash(oop key, int size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    // shift right to get better distribution (as these bits will be zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    // with aligned addresses)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    unsigned int addr = (unsigned int)((intptr_t)key);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
#ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    return (addr >> 3) % size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    return (addr >> 2) % size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  // hash a given key (oop)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  unsigned int hash(oop key) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    return hash(key, _size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  // resize the hashmap - allocates a large table and re-hashes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // all entries into the new table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  void resize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    int new_size_index = _size_index+1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    int new_size = _sizes[new_size_index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    if (new_size < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      // hashmap already at maximum capacity
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    // allocate new table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    size_t s = new_size * sizeof(JvmtiTagHashmapEntry*);
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   193
    JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    if (new_table == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
      warning("unable to allocate larger hashtable for jvmti object tags");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
      set_resizing_enabled(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    // initialize new table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    for (i=0; i<new_size; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
      new_table[i] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    // rehash all entries into the new table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    for (i=0; i<_size; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
      JvmtiTagHashmapEntry* entry = _table[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
      while (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
        JvmtiTagHashmapEntry* next = entry->next();
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   211
        oop key = entry->object();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
        assert(key != NULL, "jni weak reference cleared!!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
        unsigned int h = hash(key, new_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
        JvmtiTagHashmapEntry* anchor = new_table[h];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
        if (anchor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
          new_table[h] = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
          entry->set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
          entry->set_next(anchor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
          new_table[h] = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        entry = next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    // free old table and update settings.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    os::free((void*)_table);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    _table = new_table;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    _size_index = new_size_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    _size = new_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    // compute new resize threshold
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
    _resize_threshold = (int)(_load_factor * _size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  // internal remove function - remove an entry at a given position in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  inline void remove(JvmtiTagHashmapEntry* prev, int pos, JvmtiTagHashmapEntry* entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    assert(pos >= 0 && pos < _size, "out of range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
    if (prev == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      _table[pos] = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      prev->set_next(entry->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    assert(_entry_count > 0, "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
    _entry_count--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  // resizing switch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  bool is_resizing_enabled() const          { return _resizing_enabled; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  void set_resizing_enabled(bool enable)    { _resizing_enabled = enable; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  void print_memory_usage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  void compute_next_trace_threshold();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  // create a JvmtiTagHashmap of a preferred size and optionally a load factor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  // The preferred size is rounded down to an actual size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  JvmtiTagHashmap(int size, float load_factor=0.0f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    int i=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    while (_sizes[i] < size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      if (_sizes[i] < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        assert(i > 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        i--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    // if a load factor is specified then use it, otherwise use default
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    if (load_factor > 0.01f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
      init(i, load_factor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
      init(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  // create a JvmtiTagHashmap with default settings
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  JvmtiTagHashmap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // release table when JvmtiTagHashmap destroyed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  ~JvmtiTagHashmap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    if (_table != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
      os::free((void*)_table);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
      _table = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  int size() const                              { return _size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  JvmtiTagHashmapEntry** table() const          { return _table; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  int entry_count() const                       { return _entry_count; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  // find an entry in the hashmap, returns NULL if not found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  inline JvmtiTagHashmapEntry* find(oop key) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    unsigned int h = hash(key);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    JvmtiTagHashmapEntry* entry = _table[h];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    while (entry != NULL) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   304
      if (entry->object() == key) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   305
         return entry;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      entry = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    }
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   309
    return NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  // add a new entry to hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  inline void add(oop key, JvmtiTagHashmapEntry* entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    assert(key != NULL, "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    assert(find(key) == NULL, "duplicate detected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    unsigned int h = hash(key);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    JvmtiTagHashmapEntry* anchor = _table[h];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    if (anchor == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
      _table[h] = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
      entry->set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
      entry->set_next(anchor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
      _table[h] = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    _entry_count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    if (trace_threshold() > 0 && entry_count() >= trace_threshold()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
      assert(TraceJVMTIObjectTagging, "should only get here when tracing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
      print_memory_usage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
      compute_next_trace_threshold();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    // if the number of entries exceed the threshold then resize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    if (entry_count() > resize_threshold() && is_resizing_enabled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      resize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // remove an entry with the given key.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  inline JvmtiTagHashmapEntry* remove(oop key) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    unsigned int h = hash(key);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    JvmtiTagHashmapEntry* entry = _table[h];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
    JvmtiTagHashmapEntry* prev = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    while (entry != NULL) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   346
      if (key == entry->object()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
      prev = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
      entry = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    if (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
      remove(prev, h, entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  // iterate over all entries in the hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  void entry_iterate(JvmtiTagHashmapEntryClosure* closure);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
// possible hashmap sizes - odd primes that roughly double in size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
// To avoid excessive resizing the odd primes from 4801-76831 and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
// 76831-307261 have been removed. The list must be terminated by -1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
int JvmtiTagHashmap::_sizes[] =  { 4801, 76831, 307261, 614563, 1228891,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    2457733, 4915219, 9830479, 19660831, 39321619, 78643219, -1 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
// A supporting class for iterating over all entries in Hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
class JvmtiTagHashmapEntryClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  virtual void do_entry(JvmtiTagHashmapEntry* entry) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
// iterate over all entries in the hashmap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
void JvmtiTagHashmap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  for (int i=0; i<_size; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
    JvmtiTagHashmapEntry* entry = _table[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
    JvmtiTagHashmapEntry* prev = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
    while (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
      // obtain the next entry before invoking do_entry - this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
      // necessary because do_entry may remove the entry from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      // hashmap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      JvmtiTagHashmapEntry* next = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
      closure->do_entry(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      entry = next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
// debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
void JvmtiTagHashmap::print_memory_usage() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  intptr_t p = (intptr_t)this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  tty->print("[JvmtiTagHashmap @ " INTPTR_FORMAT, p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // table + entries in KB
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  int hashmap_usage = (size()*sizeof(JvmtiTagHashmapEntry*) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    entry_count()*sizeof(JvmtiTagHashmapEntry))/K;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  int weak_globals_usage = (int)(JNIHandles::weak_global_handle_memory_usage()/K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  tty->print_cr(", %d entries (%d KB) <JNI weak globals: %d KB>]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
    entry_count(), hashmap_usage, weak_globals_usage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
// compute threshold for the next trace message
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
void JvmtiTagHashmap::compute_next_trace_threshold() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  if (trace_threshold() < medium_trace_threshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    _trace_threshold += small_trace_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    if (trace_threshold() < large_trace_threshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
      _trace_threshold += medium_trace_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
      _trace_threshold += large_trace_threshold;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
// create a JvmtiTagMap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
JvmtiTagMap::JvmtiTagMap(JvmtiEnv* env) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  _env(env),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  _lock(Mutex::nonleaf+2, "JvmtiTagMap._lock", false),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  _free_entries(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  _free_entries_count(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  assert(JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  assert(((JvmtiEnvBase *)env)->tag_map() == NULL, "tag map already exists for environment");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   429
  _hashmap = new JvmtiTagHashmap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // finally add us to the environment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  ((JvmtiEnvBase *)env)->set_tag_map(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
// destroy a JvmtiTagMap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
JvmtiTagMap::~JvmtiTagMap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  // no lock acquired as we assume the enclosing environment is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // also being destroryed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  ((JvmtiEnvBase *)_env)->set_tag_map(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   443
  JvmtiTagHashmapEntry** table = _hashmap->table();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   444
  for (int j = 0; j < _hashmap->size(); j++) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   445
    JvmtiTagHashmapEntry* entry = table[j];
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   446
    while (entry != NULL) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   447
      JvmtiTagHashmapEntry* next = entry->next();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   448
      delete entry;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   449
      entry = next;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   453
  // finally destroy the hashmap
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   454
  delete _hashmap;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   455
  _hashmap = NULL;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   456
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  // remove any entries on the free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  JvmtiTagHashmapEntry* entry = _free_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  while (entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    JvmtiTagHashmapEntry* next = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    delete entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    entry = next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  }
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   464
  _free_entries = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
// create a hashmap entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
// - if there's an entry on the (per-environment) free list then this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
// is returned. Otherwise an new entry is allocated.
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   470
JvmtiTagHashmapEntry* JvmtiTagMap::create_entry(oop ref, jlong tag) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  assert(Thread::current()->is_VM_thread() || is_locked(), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  JvmtiTagHashmapEntry* entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  if (_free_entries == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    entry = new JvmtiTagHashmapEntry(ref, tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    assert(_free_entries_count > 0, "mismatched _free_entries_count");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    _free_entries_count--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    entry = _free_entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
    _free_entries = entry->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    entry->init(ref, tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  return entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
// destroy an entry by returning it to the free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
void JvmtiTagMap::destroy_entry(JvmtiTagHashmapEntry* entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  // limit the size of the free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  if (_free_entries_count >= max_free_entries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
    delete entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    entry->set_next(_free_entries);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
    _free_entries = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    _free_entries_count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
// returns the tag map for the given environments. If the tag map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
// doesn't exist then it is created.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
JvmtiTagMap* JvmtiTagMap::tag_map_for(JvmtiEnv* env) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   501
  JvmtiTagMap* tag_map = ((JvmtiEnvBase*)env)->tag_map();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  if (tag_map == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    MutexLocker mu(JvmtiThreadState_lock);
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   504
    tag_map = ((JvmtiEnvBase*)env)->tag_map();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
    if (tag_map == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
      tag_map = new JvmtiTagMap(env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
    CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  return tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
// iterate over all entries in the tag map.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
void JvmtiTagMap::entry_iterate(JvmtiTagHashmapEntryClosure* closure) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   516
  hashmap()->entry_iterate(closure);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
// returns true if the hashmaps are empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
bool JvmtiTagMap::is_empty() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  assert(SafepointSynchronize::is_at_safepoint() || is_locked(), "checking");
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   522
  return hashmap()->entry_count() == 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
// Return the tag value for an object, or 0 if the object is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
// not tagged
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
static inline jlong tag_for(JvmtiTagMap* tag_map, oop o) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   530
  JvmtiTagHashmapEntry* entry = tag_map->hashmap()->find(o);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  if (entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    return entry->tag();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
// A CallbackWrapper is a support class for querying and tagging an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
// around a callback to a profiler. The constructor does pre-callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
// work to get the tag value, klass tag value, ... and the destructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
// does the post-callback work of tagging or untagging the object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
// {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
//   CallbackWrapper wrapper(tag_map, o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
//   (*callback)(wrapper.klass_tag(), wrapper.obj_size(), wrapper.obj_tag_p(), ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
// } // wrapper goes out of scope here which results in the destructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
//      checking to see if the object has been tagged, untagged, or the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
//      tag value has changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
class CallbackWrapper : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  JvmtiTagMap* _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  JvmtiTagHashmap* _hashmap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  JvmtiTagHashmapEntry* _entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  oop _o;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  jlong _obj_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  jlong _obj_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  jlong _klass_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  JvmtiTagMap* tag_map() const      { return _tag_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  // invoked post-callback to tag, untag, or update the tag of an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  void inline post_callback_tag_update(oop o, JvmtiTagHashmap* hashmap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
                                       JvmtiTagHashmapEntry* entry, jlong obj_tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  CallbackWrapper(JvmtiTagMap* tag_map, oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    assert(Thread::current()->is_VM_thread() || tag_map->is_locked(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
           "MT unsafe or must be VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   574
    // object to tag
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   575
    _o = o;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    // object size
13096
8a01a0702816 7178846: IterateThroughHeap: heap_iteration_callback passes a negative size
sla
parents: 11773
diff changeset
   578
    _obj_size = (jlong)_o->size() * wordSize;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    // record the context
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
    _tag_map = tag_map;
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   582
    _hashmap = tag_map->hashmap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    _entry = _hashmap->find(_o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    // get object tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
    _obj_tag = (_entry == NULL) ? 0 : _entry->tag();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    // get the class and the class's tag value
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   589
    assert(SystemDictionary::Class_klass()->oop_is_instanceMirror(), "Is not?");
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   590
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   591
    _klass_tag = tag_for(tag_map, _o->klass()->java_mirror());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  ~CallbackWrapper() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    post_callback_tag_update(_o, _hashmap, _entry, _obj_tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  inline jlong* obj_tag_p()                     { return &_obj_tag; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  inline jlong obj_size() const                 { return _obj_size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  inline jlong obj_tag() const                  { return _obj_tag; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  inline jlong klass_tag() const                { return _klass_tag; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
// callback post-callback to tag, untag, or update the tag of an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
void inline CallbackWrapper::post_callback_tag_update(oop o,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
                                                      JvmtiTagHashmap* hashmap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
                                                      JvmtiTagHashmapEntry* entry,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
                                                      jlong obj_tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  if (entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
    if (obj_tag != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
      // callback has tagged the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
      assert(Thread::current()->is_VM_thread(), "must be VMThread");
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   615
      entry = tag_map()->create_entry(o, obj_tag);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      hashmap->add(o, entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
    // object was previously tagged - the callback may have untagged
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    // the object or changed the tag value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
    if (obj_tag == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
      JvmtiTagHashmapEntry* entry_removed = hashmap->remove(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
      assert(entry_removed == entry, "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
      tag_map()->destroy_entry(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
      if (obj_tag != entry->tag()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
         entry->set_tag(obj_tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
// An extended CallbackWrapper used when reporting an object reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
// to the agent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
// {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
//   TwoOopCallbackWrapper wrapper(tag_map, referrer, o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
//   (*callback)(wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
//               wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
//               wrapper.obj_tag_p()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
//               wrapper.referrer_tag_p(), ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
// } // wrapper goes out of scope here which results in the destructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
//      checking to see if the referrer object has been tagged, untagged,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
//      or the tag value has changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
class TwoOopCallbackWrapper : public CallbackWrapper {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  bool _is_reference_to_self;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  JvmtiTagHashmap* _referrer_hashmap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  JvmtiTagHashmapEntry* _referrer_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  oop _referrer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  jlong _referrer_obj_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  jlong _referrer_klass_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  jlong* _referrer_tag_p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  bool is_reference_to_self() const             { return _is_reference_to_self; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  TwoOopCallbackWrapper(JvmtiTagMap* tag_map, oop referrer, oop o) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    CallbackWrapper(tag_map, o)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
    // self reference needs to be handled in a special way
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
    _is_reference_to_self = (referrer == o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
    if (_is_reference_to_self) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
      _referrer_klass_tag = klass_tag();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
      _referrer_tag_p = obj_tag_p();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    } else {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   673
      _referrer = referrer;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
      // record the context
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   675
      _referrer_hashmap = tag_map->hashmap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
      _referrer_entry = _referrer_hashmap->find(_referrer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
      // get object tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      _referrer_obj_tag = (_referrer_entry == NULL) ? 0 : _referrer_entry->tag();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      _referrer_tag_p = &_referrer_obj_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
      // get referrer class tag.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   683
      _referrer_klass_tag = tag_for(tag_map, _referrer->klass()->java_mirror());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
  ~TwoOopCallbackWrapper() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    if (!is_reference_to_self()){
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      post_callback_tag_update(_referrer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
                               _referrer_hashmap,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
                               _referrer_entry,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
                               _referrer_obj_tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  // address of referrer tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  // (for a self reference this will return the same thing as obj_tag_p())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  inline jlong* referrer_tag_p()        { return _referrer_tag_p; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  // referrer's class tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  inline jlong referrer_klass_tag()     { return _referrer_klass_tag; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
// tag an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
// This function is performance critical. If many threads attempt to tag objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
// around the same time then it's possible that the Mutex associated with the
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   708
// tag map will be a hot lock.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
void JvmtiTagMap::set_tag(jobject object, jlong tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  MutexLocker ml(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  // resolve the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  oop o = JNIHandles::resolve_non_null(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  // see if the object is already tagged
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   716
  JvmtiTagHashmap* hashmap = _hashmap;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  JvmtiTagHashmapEntry* entry = hashmap->find(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  // if the object is not already tagged then we tag it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  if (entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
    if (tag != 0) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   722
      entry = create_entry(o, tag);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
   723
      hashmap->add(o, entry);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      // no-op
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    // if the object is already tagged then we either update
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    // the tag (if a new tag value has been provided)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    // or remove the object if the new tag value is 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    if (tag == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
      hashmap->remove(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
      destroy_entry(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
      entry->set_tag(tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
// get the tag for an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
jlong JvmtiTagMap::get_tag(jobject object) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  MutexLocker ml(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  // resolve the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  oop o = JNIHandles::resolve_non_null(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   747
  return tag_for(this, o);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
// Helper class used to describe the static or instance fields of a class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
// For each field it holds the field index (as defined by the JVMTI specification),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
// the field type, and the offset.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   755
class ClassFieldDescriptor: public CHeapObj<mtInternal> {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  int _field_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  int _field_offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  char _field_type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  ClassFieldDescriptor(int index, char type, int offset) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
    _field_index(index), _field_type(type), _field_offset(offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  int field_index()  const  { return _field_index; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
  char field_type()  const  { return _field_type; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  int field_offset() const  { return _field_offset; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   769
class ClassFieldMap: public CHeapObj<mtInternal> {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    initial_field_count = 5
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  // list of field descriptors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  GrowableArray<ClassFieldDescriptor*>* _fields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  // constructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  ClassFieldMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  // add a field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  void add(int index, char type, int offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  // returns the field count for the given class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  static int compute_field_count(instanceKlassHandle ikh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  ~ClassFieldMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  // access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  int field_count()                     { return _fields->length(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
  ClassFieldDescriptor* field_at(int i) { return _fields->at(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  // functions to create maps of static or instance fields
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   795
  static ClassFieldMap* create_map_of_static_fields(Klass* k);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
  static ClassFieldMap* create_map_of_instance_fields(oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
ClassFieldMap::ClassFieldMap() {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   800
  _fields = new (ResourceObj::C_HEAP, mtInternal)
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   801
    GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
ClassFieldMap::~ClassFieldMap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
  for (int i=0; i<_fields->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
    delete _fields->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  delete _fields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
void ClassFieldMap::add(int index, char type, int offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  ClassFieldDescriptor* field = new ClassFieldDescriptor(index, type, offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  _fields->append(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
// Returns a heap allocated ClassFieldMap to describe the static fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
// of the given class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
//
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   819
ClassFieldMap* ClassFieldMap::create_map_of_static_fields(Klass* k) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  // create the field map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  ClassFieldMap* field_map = new ClassFieldMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
  FilteredFieldStream f(ikh, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  int max_field_index = f.field_count()-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  for (FilteredFieldStream fld(ikh, true, true); !fld.eos(); fld.next(), index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    // ignore instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    if (!fld.access_flags().is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
    field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  return field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
// Returns a heap allocated ClassFieldMap to describe the instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
// of the given class. All instance fields are included (this means public
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
// and private fields declared in superclasses and superinterfaces too).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
ClassFieldMap* ClassFieldMap::create_map_of_instance_fields(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  instanceKlassHandle ikh = instanceKlassHandle(Thread::current(), obj->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  // create the field map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  ClassFieldMap* field_map = new ClassFieldMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  FilteredFieldStream f(ikh, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  int max_field_index = f.field_count()-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  for (FilteredFieldStream fld(ikh, false, false); !fld.eos(); fld.next(), index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    // ignore static fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    if (fld.access_flags().is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
    field_map->add(max_field_index - index, fld.signature()->byte_at(0), fld.offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
  return field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
// Helper class used to cache a ClassFileMap for the instance fields of
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   868
// a cache. A JvmtiCachedClassFieldMap can be cached by an InstanceKlass during
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
// heap iteration and avoid creating a field map for each object in the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
// (only need to create the map when the first instance of a class is encountered).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
//
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   872
class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
   enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
     initial_class_count = 200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
   };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  ClassFieldMap* _field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  ClassFieldMap* field_map() const          { return _field_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  JvmtiCachedClassFieldMap(ClassFieldMap* field_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  ~JvmtiCachedClassFieldMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   884
  static GrowableArray<InstanceKlass*>* _class_list;
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   885
  static void add_to_class_list(InstanceKlass* ik);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
  // returns the field map for a given object (returning map cached
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   889
  // by InstanceKlass if possible
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  static ClassFieldMap* get_map_of_instance_fields(oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  // removes the field map from all instanceKlasses - should be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  // called before VM operation completes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  static void clear_cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  // returns the number of ClassFieldMap cached by instanceKlasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  static int cached_field_map_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   900
GrowableArray<InstanceKlass*>* JvmtiCachedClassFieldMap::_class_list;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
JvmtiCachedClassFieldMap::JvmtiCachedClassFieldMap(ClassFieldMap* field_map) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  _field_map = field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
JvmtiCachedClassFieldMap::~JvmtiCachedClassFieldMap() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  if (_field_map != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
    delete _field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
// Marker class to ensure that the class file map cache is only used in a defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
// scope.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
class ClassFieldMapCacheMark : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
   static bool _is_active;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
   ClassFieldMapCacheMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
     assert(Thread::current()->is_VM_thread(), "must be VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
     assert(JvmtiCachedClassFieldMap::cached_field_map_count() == 0, "cache not empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
     assert(!_is_active, "ClassFieldMapCacheMark cannot be nested");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
     _is_active = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
   ~ClassFieldMapCacheMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
     JvmtiCachedClassFieldMap::clear_cache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
     _is_active = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
   static bool is_active() { return _is_active; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
bool ClassFieldMapCacheMark::_is_active;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   934
// record that the given InstanceKlass is caching a field map
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   935
void JvmtiCachedClassFieldMap::add_to_class_list(InstanceKlass* ik) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  if (_class_list == NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
   937
    _class_list = new (ResourceObj::C_HEAP, mtInternal)
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   938
      GrowableArray<InstanceKlass*>(initial_class_count, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
  _class_list->push(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
// returns the instance field map for the given object
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   944
// (returns field map cached by the InstanceKlass if possible)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
ClassFieldMap* JvmtiCachedClassFieldMap::get_map_of_instance_fields(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
  assert(Thread::current()->is_VM_thread(), "must be VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  assert(ClassFieldMapCacheMark::is_active(), "ClassFieldMapCacheMark not active");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   949
  Klass* k = obj->klass();
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   950
  InstanceKlass* ik = InstanceKlass::cast(k);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
  // return cached map if possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  if (cached_map != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
    assert(cached_map->field_map() != NULL, "missing field list");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    return cached_map->field_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    ClassFieldMap* field_map = ClassFieldMap::create_map_of_instance_fields(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
    cached_map = new JvmtiCachedClassFieldMap(field_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    ik->set_jvmti_cached_class_field_map(cached_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
    add_to_class_list(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    return field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
// remove the fields maps cached from all instanceKlasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
void JvmtiCachedClassFieldMap::clear_cache() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  assert(Thread::current()->is_VM_thread(), "must be VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  if (_class_list != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
    for (int i = 0; i < _class_list->length(); i++) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
   971
      InstanceKlass* ik = _class_list->at(i);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
      JvmtiCachedClassFieldMap* cached_map = ik->jvmti_cached_class_field_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
      assert(cached_map != NULL, "should not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
      ik->set_jvmti_cached_class_field_map(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      delete cached_map;  // deletes the encapsulated field map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
    delete _class_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
    _class_list = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
// returns the number of ClassFieldMap cached by instanceKlasses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
int JvmtiCachedClassFieldMap::cached_field_map_count() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  return (_class_list == NULL) ? 0 : _class_list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
// helper function to indicate if an object is filtered by its tag or class tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
static inline bool is_filtered_by_heap_filter(jlong obj_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
                                              jlong klass_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
                                              int heap_filter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  // apply the heap filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  if (obj_tag != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    // filter out tagged objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    if (heap_filter & JVMTI_HEAP_FILTER_TAGGED) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    // filter out untagged objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
    if (heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  if (klass_tag != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
    // filter out objects with tagged classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    if (heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    // filter out objects with untagged classes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
    if (heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
// helper function to indicate if an object is filtered by a klass filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
static inline bool is_filtered_by_klass_filter(oop obj, KlassHandle klass_filter) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  if (!klass_filter.is_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    if (obj->klass() != klass_filter()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
// helper function to tell if a field is a primitive field or not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
static inline bool is_primitive_field_type(char type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  return (type != 'L' && type != '[');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
// helper function to copy the value from location addr to jvalue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
static inline void copy_to_jvalue(jvalue *v, address addr, jvmtiPrimitiveType value_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  switch (value_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
    case JVMTI_PRIMITIVE_TYPE_BOOLEAN : { v->z = *(jboolean*)addr; break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    case JVMTI_PRIMITIVE_TYPE_BYTE    : { v->b = *(jbyte*)addr;    break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    case JVMTI_PRIMITIVE_TYPE_CHAR    : { v->c = *(jchar*)addr;    break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    case JVMTI_PRIMITIVE_TYPE_SHORT   : { v->s = *(jshort*)addr;   break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    case JVMTI_PRIMITIVE_TYPE_INT     : { v->i = *(jint*)addr;     break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    case JVMTI_PRIMITIVE_TYPE_LONG    : { v->j = *(jlong*)addr;    break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    case JVMTI_PRIMITIVE_TYPE_FLOAT   : { v->f = *(jfloat*)addr;   break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    case JVMTI_PRIMITIVE_TYPE_DOUBLE  : { v->d = *(jdouble*)addr;  break; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    default: ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
// helper function to invoke string primitive value callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
// returns visit control flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
static jint invoke_string_value_callback(jvmtiStringPrimitiveValueCallback cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
                                         CallbackWrapper* wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
                                         oop str,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
                                         void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
{
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  1046
  assert(str->klass() == SystemDictionary::String_klass(), "not a string");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  // get the string value and length
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  // (string value may be offset from the base)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  int s_len = java_lang_String::length(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  typeArrayOop s_value = java_lang_String::value(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
  int s_offset = java_lang_String::offset(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  jchar* value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  if (s_len > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    value = s_value->char_at_addr(s_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
    value = (jchar*) s_value->base(T_CHAR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
  // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
  return (*cb)(wrapper->klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
               wrapper->obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
               wrapper->obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
               value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
               (jint)s_len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
               user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
// helper function to invoke string primitive value callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
// returns visit control flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
static jint invoke_array_primitive_value_callback(jvmtiArrayPrimitiveValueCallback cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
                                                  CallbackWrapper* wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
                                                  oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
                                                  void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  assert(obj->is_typeArray(), "not a primitive array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  // get base address of first element
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  typeArrayOop array = typeArrayOop(obj);
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13741
diff changeset
  1080
  BasicType type = TypeArrayKlass::cast(array->klass())->element_type();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  void* elements = array->base(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
  // jvmtiPrimitiveType is defined so this mapping is always correct
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  jvmtiPrimitiveType elem_type = (jvmtiPrimitiveType)type2char(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  return (*cb)(wrapper->klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
               wrapper->obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
               wrapper->obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
               (jint)array->length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
               elem_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
               elements,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
               user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
// helper function to invoke the primitive field callback for all static fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
// of a given class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
static jint invoke_primitive_field_callback_for_static_fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  (CallbackWrapper* wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
   oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
   jvmtiPrimitiveFieldCallback cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
   void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
  // for static fields only the index will be set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  static jvmtiHeapReferenceInfo reference_info = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  1106
  assert(obj->klass() == SystemDictionary::Class_klass(), "not a class");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  if (java_lang_Class::is_primitive(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
  }
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1110
  Klass* klass = java_lang_Class::as_Klass(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  // ignore classes for object and type arrays
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  if (!klass->oop_is_instance()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  // ignore classes which aren't linked yet
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1118
  InstanceKlass* ik = InstanceKlass::cast(klass);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  if (!ik->is_linked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
  // get the field map
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1124
  ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
  // invoke the callback for each static primitive field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
  for (int i=0; i<field_map->field_count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    ClassFieldDescriptor* field = field_map->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    // ignore non-primitive fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
    char type = field->field_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
    if (!is_primitive_field_type(type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    // one-to-one mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
    jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
    // get offset and field value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
    int offset = field->field_offset();
14082
7425bbf64ead 7093328: JVMTI: jvmtiPrimitiveFieldCallback always report 0's for static primitives
rbackman
parents: 13977
diff changeset
  1140
    address addr = (address)klass->java_mirror() + offset;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
    jvalue value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
    copy_to_jvalue(&value, addr, value_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
    // field index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
    reference_info.field.index = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
    // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
    jint res = (*cb)(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
                     &reference_info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
                     wrapper->klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
                     wrapper->obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
                     value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
                     value_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
                     user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
    if (res & JVMTI_VISIT_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
      delete field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
      return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  delete field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
// helper function to invoke the primitive field callback for all instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
// of a given object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
static jint invoke_primitive_field_callback_for_instance_fields(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  CallbackWrapper* wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  jvmtiPrimitiveFieldCallback cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
  // for instance fields only the index will be set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  static jvmtiHeapReferenceInfo reference_info = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  // get the map of the instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  ClassFieldMap* fields = JvmtiCachedClassFieldMap::get_map_of_instance_fields(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
  // invoke the callback for each instance primitive field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  for (int i=0; i<fields->field_count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
    ClassFieldDescriptor* field = fields->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    // ignore non-primitive fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    char type = field->field_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    if (!is_primitive_field_type(type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
    // one-to-one mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    // get offset and field value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    int offset = field->field_offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    address addr = (address)obj + offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    jvalue value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
    copy_to_jvalue(&value, addr, value_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    // field index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
    reference_info.field.index = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    jint res = (*cb)(JVMTI_HEAP_REFERENCE_FIELD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
                     &reference_info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
                     wrapper->klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
                     wrapper->obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
                     value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
                     value_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
                     user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
    if (res & JVMTI_VISIT_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
      return res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
// VM operation to iterate over all objects in the heap (both reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
// and unreachable)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
class VM_HeapIterateOperation: public VM_Operation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
  ObjectClosure* _blk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
  VM_HeapIterateOperation(ObjectClosure* blk) { _blk = blk; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  VMOp_Type type() const { return VMOp_HeapIterateOperation; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
  void doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
    // allows class files maps to be cached during iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
    ClassFieldMapCacheMark cm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
    // make sure that heap is parsable (fills TLABs with filler objects)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
    Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
    // Verify heap before iteration - if the heap gets corrupted then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
    // JVMTI's IterateOverHeap will crash.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
    if (VerifyBeforeIteration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      Universe::verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
    // do the iteration
1893
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1388
diff changeset
  1239
    // If this operation encounters a bad object when using CMS,
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1388
diff changeset
  1240
    // consider using safe_object_iterate() which avoids perm gen
c82e388e17c5 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents: 1388
diff changeset
  1241
    // objects that may contain bad references.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
    Universe::heap()->object_iterate(_blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
// An ObjectClosure used to support the deprecated IterateOverHeap and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
// IterateOverInstancesOfClass functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
class IterateOverHeapObjectClosure: public ObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
  JvmtiTagMap* _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  KlassHandle _klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  jvmtiHeapObjectFilter _object_filter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
  jvmtiHeapObjectCallback _heap_object_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  const void* _user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  JvmtiTagMap* tag_map() const                    { return _tag_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  jvmtiHeapObjectFilter object_filter() const     { return _object_filter; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  jvmtiHeapObjectCallback object_callback() const { return _heap_object_callback; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
  KlassHandle klass() const                       { return _klass; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
  const void* user_data() const                   { return _user_data; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
  // indicates if iteration has been aborted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  bool _iteration_aborted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  bool is_iteration_aborted() const               { return _iteration_aborted; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  void set_iteration_aborted(bool aborted)        { _iteration_aborted = aborted; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  IterateOverHeapObjectClosure(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
                               KlassHandle klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
                               jvmtiHeapObjectFilter object_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
                               jvmtiHeapObjectCallback heap_object_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
                               const void* user_data) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
    _tag_map(tag_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
    _klass(klass),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
    _object_filter(object_filter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
    _heap_object_callback(heap_object_callback),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
    _user_data(user_data),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
    _iteration_aborted(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
  void do_object(oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
// invoked for each object in the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
void IterateOverHeapObjectClosure::do_object(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  // check if iteration has been halted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  if (is_iteration_aborted()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // ignore any objects that aren't visible to profiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  if (!ServiceUtil::visible_oop(o)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  // instanceof check when filtering by klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  if (!klass().is_null() && !o->is_a(klass()())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  // prepare for the calllback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  CallbackWrapper wrapper(tag_map(), o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
  // if the object is tagged and we're only interested in untagged objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
  // then don't invoke the callback. Similiarly, if the object is untagged
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  // and we're only interested in tagged objects we skip the callback.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
  if (wrapper.obj_tag() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
    if (object_filter() == JVMTI_HEAP_OBJECT_UNTAGGED) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    if (object_filter() == JVMTI_HEAP_OBJECT_TAGGED) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  // invoke the agent's callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  jvmtiIterationControl control = (*object_callback())(wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
                                                       wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
                                                       wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
                                                       (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
  if (control == JVMTI_ITERATION_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
    set_iteration_aborted(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
// An ObjectClosure used to support the IterateThroughHeap function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
class IterateThroughHeapObjectClosure: public ObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  JvmtiTagMap* _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  KlassHandle _klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
  int _heap_filter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
  const jvmtiHeapCallbacks* _callbacks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
  const void* _user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
  // accessor functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
  JvmtiTagMap* tag_map() const                     { return _tag_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
  int heap_filter() const                          { return _heap_filter; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  const jvmtiHeapCallbacks* callbacks() const      { return _callbacks; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  KlassHandle klass() const                        { return _klass; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  const void* user_data() const                    { return _user_data; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
  // indicates if the iteration has been aborted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
  bool _iteration_aborted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  bool is_iteration_aborted() const                { return _iteration_aborted; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  // used to check the visit control flags. If the abort flag is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
  // then we set the iteration aborted flag so that the iteration completes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
  // without processing any further objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  bool check_flags_for_abort(jint flags) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
    bool is_abort = (flags & JVMTI_VISIT_ABORT) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
    if (is_abort) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
      _iteration_aborted = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
    return is_abort;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  IterateThroughHeapObjectClosure(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
                                  KlassHandle klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
                                  int heap_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
                                  const jvmtiHeapCallbacks* heap_callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
                                  const void* user_data) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
    _tag_map(tag_map),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
    _klass(klass),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
    _heap_filter(heap_filter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
    _callbacks(heap_callbacks),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
    _user_data(user_data),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
    _iteration_aborted(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  void do_object(oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
// invoked for each object in the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
void IterateThroughHeapObjectClosure::do_object(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  // check if iteration has been halted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  if (is_iteration_aborted()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  // ignore any objects that aren't visible to profiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  if (!ServiceUtil::visible_oop(obj)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  if (is_filtered_by_klass_filter(obj, klass())) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  // prepare for callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  // check if filtered by the heap filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  if (is_filtered_by_heap_filter(wrapper.obj_tag(), wrapper.klass_tag(), heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  // for arrays we need the length, otherwise -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  bool is_array = obj->is_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  int len = is_array ? arrayOop(obj)->length() : -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  // invoke the object callback (if callback is provided)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  if (callbacks()->heap_iteration_callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
    jvmtiHeapIterationCallback cb = callbacks()->heap_iteration_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
    jint res = (*cb)(wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
                     wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
                     wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
                     (jint)len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
                     (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
    if (check_flags_for_abort(res)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  // for objects and classes we report primitive fields if callback provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  if (callbacks()->primitive_field_callback != NULL && obj->is_instance()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
    jint res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
    jvmtiPrimitiveFieldCallback cb = callbacks()->primitive_field_callback;
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  1409
    if (obj->klass() == SystemDictionary::Class_klass()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
      res = invoke_primitive_field_callback_for_static_fields(&wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
                                                                    obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
                                                                    cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
                                                                    (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
      res = invoke_primitive_field_callback_for_instance_fields(&wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
                                                                      obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
                                                                      cb,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
                                                                      (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
    if (check_flags_for_abort(res)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
  // string callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
  if (!is_array &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      callbacks()->string_primitive_value_callback != NULL &&
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  1426
      obj->klass() == SystemDictionary::String_klass()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
    jint res = invoke_string_value_callback(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
                callbacks()->string_primitive_value_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
                &wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
                obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
                (void*)user_data() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
    if (check_flags_for_abort(res)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
  // array callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  if (is_array &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
      callbacks()->array_primitive_value_callback != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
      obj->is_typeArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
    jint res = invoke_array_primitive_value_callback(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
               callbacks()->array_primitive_value_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
               &wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
               obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
               (void*)user_data() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
    if (check_flags_for_abort(res)) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
// Deprecated function to iterate over all objects in the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
                                    KlassHandle klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
                                    jvmtiHeapObjectCallback heap_object_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
                                    const void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
  MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
  IterateOverHeapObjectClosure blk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
                                   klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
                                   object_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
                                   heap_object_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
                                   user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
  VM_HeapIterateOperation op(&blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
// Iterates over all objects in the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
void JvmtiTagMap::iterate_through_heap(jint heap_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
                                       KlassHandle klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
                                       const jvmtiHeapCallbacks* callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
                                       const void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
  IterateThroughHeapObjectClosure blk(this,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
                                      klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
                                      heap_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
                                      callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
                                      user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  VM_HeapIterateOperation op(&blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
  VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
// support class for get_objects_with_tags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
  JvmtiEnv* _env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
  jlong* _tags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
  jint _tag_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
  GrowableArray<jobject>* _object_results;  // collected objects (JNI weak refs)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
  GrowableArray<uint64_t>* _tag_results;    // collected tags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
  TagObjectCollector(JvmtiEnv* env, const jlong* tags, jint tag_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    _env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
    _tags = (jlong*)tags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
    _tag_count = tag_count;
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
  1498
    _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true);
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
  1499
    _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
  ~TagObjectCollector() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
    delete _object_results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
    delete _tag_results;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
  // for each tagged object check if the tag value matches
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
  // - if it matches then we create a JNI local reference to the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
  // and record the reference and tag value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
  void do_entry(JvmtiTagHashmapEntry* entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
    for (int i=0; i<_tag_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
      if (_tags[i] == entry->tag()) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  1514
        oop o = entry->object();
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  1515
        assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
        jobject ref = JNIHandles::make_local(JavaThread::current(), o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
        _object_results->append(ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
        _tag_results->append((uint64_t)entry->tag());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
  // return the results from the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
  jvmtiError result(jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
    jvmtiError error;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
    int count = _object_results->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
    assert(count >= 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
    // if object_result_ptr is not NULL then allocate the result and copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
    // in the object references.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
    if (object_result_ptr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
      error = _env->Allocate(count * sizeof(jobject), (unsigned char**)object_result_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
      if (error != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
        return error;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
      for (int i=0; i<count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
        (*object_result_ptr)[i] = _object_results->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    // if tag_result_ptr is not NULL then allocate the result and copy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
    // in the tag values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
    if (tag_result_ptr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
      error = _env->Allocate(count * sizeof(jlong), (unsigned char**)tag_result_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
      if (error != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
        if (object_result_ptr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
          _env->Deallocate((unsigned char*)object_result_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
        return error;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
      for (int i=0; i<count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
        (*tag_result_ptr)[i] = (jlong)_tag_results->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    *count_ptr = count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
// return the list of objects with the specified tags
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
jvmtiError JvmtiTagMap::get_objects_with_tags(const jlong* tags,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
  jint count, jint* count_ptr, jobject** object_result_ptr, jlong** tag_result_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
  TagObjectCollector collector(env(), tags, count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
    // iterate over all tagged objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
    MutexLocker ml(lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
    entry_iterate(&collector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  return collector.result(count_ptr, object_result_ptr, tag_result_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
// ObjectMarker is used to support the marking objects when walking the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
// heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
// This implementation uses the existing mark bits in an object for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
// marking. Objects that are marked must later have their headers restored.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
// As most objects are unlocked and don't have their identity hash computed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
// we don't have to save their headers. Instead we save the headers that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
// are "interesting". Later when the headers are restored this implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
// restores all headers to their initial value and then restores the few
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
// objects that had interesting headers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
// Future work: This implementation currently uses growable arrays to save
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
// the oop and header of interesting objects. As an optimization we could
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
// use the same technique as the GC and make use of the unused area
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
// between top() and end().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
// An ObjectClosure used to restore the mark bits of an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
class RestoreMarksClosure : public ObjectClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
  void do_object(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
    if (o != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
      markOop mark = o->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
      if (mark->is_marked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
        o->init_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
// ObjectMarker provides the mark and visited functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
class ObjectMarker : AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  // saved headers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  static GrowableArray<oop>* _saved_oop_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  static GrowableArray<markOop>* _saved_mark_stack;
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1612
  static bool _needs_reset;                  // do we need to reset mark bits?
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
  static void init();                       // initialize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
  static void done();                       // clean-up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
  static inline void mark(oop o);           // mark an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
  static inline bool visited(oop o);        // check if object has been visited
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1620
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1621
  static inline bool needs_reset()            { return _needs_reset; }
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1622
  static inline void set_needs_reset(bool v)  { _needs_reset = v; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL;
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1627
bool ObjectMarker::_needs_reset = true;  // need to reset mark bits by default
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
// initialize ObjectMarker - prepares for object marking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
void ObjectMarker::init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
  assert(Thread::current()->is_VM_thread(), "must be VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
  // prepare heap for iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
  Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
  // create stacks for interesting headers
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
  1637
  _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true);
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
  1638
  _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
  if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
    BiasedLocking::preserve_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
// Object marking is done so restore object headers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
void ObjectMarker::done() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
  // iterate over all objects and restore the mark bits to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
  // their initial value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
  RestoreMarksClosure blk;
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1650
  if (needs_reset()) {
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1651
    Universe::heap()->object_iterate(&blk);
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1652
  } else {
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1653
    // We don't need to reset mark bits on this call, but reset the
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1654
    // flag to the default for the next call.
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1655
    set_needs_reset(true);
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  1656
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  // now restore the interesting headers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
  for (int i = 0; i < _saved_oop_stack->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
    oop o = _saved_oop_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
    markOop mark = _saved_mark_stack->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
    o->set_mark(mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
  if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
    BiasedLocking::restore_marks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
  // free the stacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
  delete _saved_oop_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
  delete _saved_mark_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
// mark an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
inline void ObjectMarker::mark(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  assert(Universe::heap()->is_in(o), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
  assert(!o->mark()->is_marked(), "should only mark an object once");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
  // object's mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
  markOop mark = o->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  if (mark->must_be_preserved(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
    _saved_mark_stack->push(mark);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
    _saved_oop_stack->push(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
  // mark the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  o->set_mark(markOopDesc::prototype()->set_marked());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
// return true if object is marked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
inline bool ObjectMarker::visited(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  return o->mark()->is_marked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
// Stack allocated class to help ensure that ObjectMarker is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
// correctly. Constructor initializes ObjectMarker, destructor calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
// ObjectMarker's done() function to restore object headers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
class ObjectMarkerController : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  ObjectMarkerController() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
    ObjectMarker::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  ~ObjectMarkerController() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
    ObjectMarker::done();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
// helper to map a jvmtiHeapReferenceKind to an old style jvmtiHeapRootKind
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
// (not performance critical as only used for roots)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
static jvmtiHeapRootKind toJvmtiHeapRootKind(jvmtiHeapReferenceKind kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
  switch (kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
    case JVMTI_HEAP_REFERENCE_JNI_GLOBAL:   return JVMTI_HEAP_ROOT_JNI_GLOBAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
    case JVMTI_HEAP_REFERENCE_SYSTEM_CLASS: return JVMTI_HEAP_ROOT_SYSTEM_CLASS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
    case JVMTI_HEAP_REFERENCE_MONITOR:      return JVMTI_HEAP_ROOT_MONITOR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
    case JVMTI_HEAP_REFERENCE_STACK_LOCAL:  return JVMTI_HEAP_ROOT_STACK_LOCAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
    case JVMTI_HEAP_REFERENCE_JNI_LOCAL:    return JVMTI_HEAP_ROOT_JNI_LOCAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
    case JVMTI_HEAP_REFERENCE_THREAD:       return JVMTI_HEAP_ROOT_THREAD;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
    case JVMTI_HEAP_REFERENCE_OTHER:        return JVMTI_HEAP_ROOT_OTHER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
    default: ShouldNotReachHere();          return JVMTI_HEAP_ROOT_OTHER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
// Base class for all heap walk contexts. The base class maintains a flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
// to indicate if the context is valid or not.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
class HeapWalkContext VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  bool _valid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  HeapWalkContext(bool valid)                   { _valid = valid; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  void invalidate()                             { _valid = false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
  bool is_valid() const                         { return _valid; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
// A basic heap walk context for the deprecated heap walking functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
// The context for a basic heap walk are the callbacks and fields used by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
// the referrer caching scheme.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
class BasicHeapWalkContext: public HeapWalkContext {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
  jvmtiHeapRootCallback _heap_root_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  jvmtiStackReferenceCallback _stack_ref_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  jvmtiObjectReferenceCallback _object_ref_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
  // used for caching
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
  oop _last_referrer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
  jlong _last_referrer_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
  BasicHeapWalkContext() : HeapWalkContext(false) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
  BasicHeapWalkContext(jvmtiHeapRootCallback heap_root_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
                       jvmtiStackReferenceCallback stack_ref_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
                       jvmtiObjectReferenceCallback object_ref_callback) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
    HeapWalkContext(true),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
    _heap_root_callback(heap_root_callback),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
    _stack_ref_callback(stack_ref_callback),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
    _object_ref_callback(object_ref_callback),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
    _last_referrer(NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
    _last_referrer_tag(0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
  jvmtiHeapRootCallback heap_root_callback() const         { return _heap_root_callback; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
  jvmtiStackReferenceCallback stack_ref_callback() const   { return _stack_ref_callback; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
  jvmtiObjectReferenceCallback object_ref_callback() const { return _object_ref_callback;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
  oop last_referrer() const               { return _last_referrer; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
  void set_last_referrer(oop referrer)    { _last_referrer = referrer; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
  jlong last_referrer_tag() const         { return _last_referrer_tag; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
  void set_last_referrer_tag(jlong value) { _last_referrer_tag = value; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
// The advanced heap walk context for the FollowReferences functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
// The context is the callbacks, and the fields used for filtering.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
class AdvancedHeapWalkContext: public HeapWalkContext {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  jint _heap_filter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
  KlassHandle _klass_filter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  const jvmtiHeapCallbacks* _heap_callbacks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  AdvancedHeapWalkContext() : HeapWalkContext(false) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
  AdvancedHeapWalkContext(jint heap_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
                           KlassHandle klass_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
                           const jvmtiHeapCallbacks* heap_callbacks) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
    HeapWalkContext(true),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
    _heap_filter(heap_filter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
    _klass_filter(klass_filter),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
    _heap_callbacks(heap_callbacks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  jint heap_filter() const         { return _heap_filter; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
  KlassHandle klass_filter() const { return _klass_filter; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  const jvmtiHeapReferenceCallback heap_reference_callback() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    return _heap_callbacks->heap_reference_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  const jvmtiPrimitiveFieldCallback primitive_field_callback() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
    return _heap_callbacks->primitive_field_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  const jvmtiArrayPrimitiveValueCallback array_primitive_value_callback() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
    return _heap_callbacks->array_primitive_value_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
  const jvmtiStringPrimitiveValueCallback string_primitive_value_callback() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
    return _heap_callbacks->string_primitive_value_callback;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
// The CallbackInvoker is a class with static functions that the heap walk can call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
// into to invoke callbacks. It works in one of two modes. The "basic" mode is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
// used for the deprecated IterateOverReachableObjects functions. The "advanced"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
// mode is for the newer FollowReferences function which supports a lot of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
// additional callbacks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
class CallbackInvoker : AllStatic {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
  // heap walk styles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
  enum { basic, advanced };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
  static int _heap_walk_type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  static bool is_basic_heap_walk()           { return _heap_walk_type == basic; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  static bool is_advanced_heap_walk()        { return _heap_walk_type == advanced; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  // context for basic style heap walk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  static BasicHeapWalkContext _basic_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  static BasicHeapWalkContext* basic_context() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
    assert(_basic_context.is_valid(), "invalid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
    return &_basic_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
  // context for advanced style heap walk
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
  static AdvancedHeapWalkContext _advanced_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  static AdvancedHeapWalkContext* advanced_context() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
    assert(_advanced_context.is_valid(), "invalid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
    return &_advanced_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  // context needed for all heap walks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
  static JvmtiTagMap* _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  static const void* _user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
  static GrowableArray<oop>* _visit_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
  static JvmtiTagMap* tag_map()                        { return _tag_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  static const void* user_data()                       { return _user_data; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  static GrowableArray<oop>* visit_stack()             { return _visit_stack; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  // if the object hasn't been visited then push it onto the visit stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
  // so that it will be visited later
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  static inline bool check_for_visit(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
    if (!ObjectMarker::visited(obj)) visit_stack()->push(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
  // invoke basic style callbacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
  static inline bool invoke_basic_heap_root_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
    (jvmtiHeapRootKind root_kind, oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
  static inline bool invoke_basic_stack_ref_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
    (jvmtiHeapRootKind root_kind, jlong thread_tag, jint depth, jmethodID method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
     int slot, oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
  static inline bool invoke_basic_object_reference_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
    (jvmtiObjectReferenceKind ref_kind, oop referrer, oop referree, jint index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
  // invoke advanced style callbacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  static inline bool invoke_advanced_heap_root_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
    (jvmtiHeapReferenceKind ref_kind, oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
  static inline bool invoke_advanced_stack_ref_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    (jvmtiHeapReferenceKind ref_kind, jlong thread_tag, jlong tid, int depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
     jmethodID method, jlocation bci, jint slot, oop obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
  static inline bool invoke_advanced_object_reference_callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
    (jvmtiHeapReferenceKind ref_kind, oop referrer, oop referree, jint index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  // used to report the value of primitive fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
  static inline bool report_primitive_field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
    (jvmtiHeapReferenceKind ref_kind, oop obj, jint index, address addr, char type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  // initialize for basic mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
  static void initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
                                             GrowableArray<oop>* visit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
                                             const void* user_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
                                             BasicHeapWalkContext context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
  // initialize for advanced mode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
  static void initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
                                                GrowableArray<oop>* visit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
                                                const void* user_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
                                                AdvancedHeapWalkContext context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
   // functions to report roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
  static inline bool report_simple_root(jvmtiHeapReferenceKind kind, oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
  static inline bool report_jni_local_root(jlong thread_tag, jlong tid, jint depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
    jmethodID m, oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
  static inline bool report_stack_ref_root(jlong thread_tag, jlong tid, jint depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
    jmethodID method, jlocation bci, jint slot, oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
  // functions to report references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
  static inline bool report_array_element_reference(oop referrer, oop referree, jint index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  static inline bool report_class_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
  static inline bool report_class_loader_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  static inline bool report_signers_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
  static inline bool report_protection_domain_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  static inline bool report_superclass_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  static inline bool report_interface_reference(oop referrer, oop referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
  static inline bool report_static_field_reference(oop referrer, oop referree, jint slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  static inline bool report_field_reference(oop referrer, oop referree, jint slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  static inline bool report_constant_pool_reference(oop referrer, oop referree, jint index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  static inline bool report_primitive_array_values(oop array);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  static inline bool report_string_value(oop str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  static inline bool report_primitive_instance_field(oop o, jint index, address value, char type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  static inline bool report_primitive_static_field(oop o, jint index, address value, char type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
// statics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
int CallbackInvoker::_heap_walk_type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
BasicHeapWalkContext CallbackInvoker::_basic_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
AdvancedHeapWalkContext CallbackInvoker::_advanced_context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
JvmtiTagMap* CallbackInvoker::_tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
const void* CallbackInvoker::_user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
GrowableArray<oop>* CallbackInvoker::_visit_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
// initialize for basic heap walk (IterateOverReachableObjects et al)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
void CallbackInvoker::initialize_for_basic_heap_walk(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
                                                     GrowableArray<oop>* visit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
                                                     const void* user_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
                                                     BasicHeapWalkContext context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
  _tag_map = tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  _visit_stack = visit_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  _user_data = user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  _basic_context = context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  _advanced_context.invalidate();       // will trigger assertion if used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  _heap_walk_type = basic;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
// initialize for advanced heap walk (FollowReferences)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
void CallbackInvoker::initialize_for_advanced_heap_walk(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
                                                        GrowableArray<oop>* visit_stack,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
                                                        const void* user_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
                                                        AdvancedHeapWalkContext context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
  _tag_map = tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  _visit_stack = visit_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
  _user_data = user_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  _advanced_context = context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  _basic_context.invalidate();      // will trigger assertion if used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  _heap_walk_type = advanced;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
// invoke basic style heap root callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
inline bool CallbackInvoker::invoke_basic_heap_root_callback(jvmtiHeapRootKind root_kind, oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  // if we heap roots should be reported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  jvmtiHeapRootCallback cb = basic_context()->heap_root_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
  if (cb == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
  jvmtiIterationControl control = (*cb)(root_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
                                        wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
                                        wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
                                        wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
                                        (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
  // push root to visit stack when following references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  if (control == JVMTI_ITERATION_CONTINUE &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
      basic_context()->object_ref_callback() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
    visit_stack()->push(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  return control != JVMTI_ITERATION_ABORT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
// invoke basic style stack ref callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
inline bool CallbackInvoker::invoke_basic_stack_ref_callback(jvmtiHeapRootKind root_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
                                                             jlong thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
                                                             jint depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
                                                             jmethodID method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
                                                             jint slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
                                                             oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
  // if we stack refs should be reported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
  jvmtiStackReferenceCallback cb = basic_context()->stack_ref_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  if (cb == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
  jvmtiIterationControl control = (*cb)(root_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
                                        wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
                                        wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
                                        wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
                                        thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
                                        depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
                                        method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
                                        slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
                                        (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
  // push root to visit stack when following references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  if (control == JVMTI_ITERATION_CONTINUE &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
      basic_context()->object_ref_callback() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
    visit_stack()->push(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
  return control != JVMTI_ITERATION_ABORT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
// invoke basic style object reference callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
inline bool CallbackInvoker::invoke_basic_object_reference_callback(jvmtiObjectReferenceKind ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
                                                                    oop referrer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
                                                                    oop referree,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
                                                                    jint index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
  assert(ServiceUtil::visible_oop(referrer), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  assert(ServiceUtil::visible_oop(referree), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  BasicHeapWalkContext* context = basic_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  // callback requires the referrer's tag. If it's the same referrer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  // as the last call then we use the cached value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
  jlong referrer_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
  if (referrer == context->last_referrer()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
    referrer_tag = context->last_referrer_tag();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
  } else {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2024
    referrer_tag = tag_for(tag_map(), referrer);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
  // do the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
  CallbackWrapper wrapper(tag_map(), referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
  jvmtiObjectReferenceCallback cb = context->object_ref_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
  jvmtiIterationControl control = (*cb)(ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
                                        wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
                                        wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
                                        wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
                                        referrer_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
                                        index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
                                        (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
  // record referrer and referrer tag. For self-references record the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
  // tag value from the callback as this might differ from referrer_tag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
  context->set_last_referrer(referrer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
  if (referrer == referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
    context->set_last_referrer_tag(*wrapper.obj_tag_p());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
    context->set_last_referrer_tag(referrer_tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
  if (control == JVMTI_ITERATION_CONTINUE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
    return check_for_visit(referree);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
    return control != JVMTI_ITERATION_ABORT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
// invoke advanced style heap root callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
inline bool CallbackInvoker::invoke_advanced_heap_root_callback(jvmtiHeapReferenceKind ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
                                                                oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
  // check that callback is provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
  if (cb == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
  if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
  // setup the callback wrapper
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  // for arrays we need the length, otherwise -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
  // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  jint res  = (*cb)(ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
                    NULL, // referrer info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
                    wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
                    0,    // referrer_class_tag is 0 for heap root
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
                    wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
                    wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
                    NULL, // referrer_tag_p
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
                    len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
                    (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
  if (res & JVMTI_VISIT_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
    return false;// referrer class tag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
  if (res & JVMTI_VISIT_OBJECTS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
    check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
// report a reference from a thread stack to an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
inline bool CallbackInvoker::invoke_advanced_stack_ref_callback(jvmtiHeapReferenceKind ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
                                                                jlong thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
                                                                jlong tid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
                                                                int depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
                                                                jmethodID method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
                                                                jlocation bci,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
                                                                jint slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
                                                                oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
  // check that callback is provider
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
  jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
  if (cb == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
  if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
  // setup the callback wrapper
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
  // setup the referrer info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
  jvmtiHeapReferenceInfo reference_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
  reference_info.stack_local.thread_tag = thread_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
  reference_info.stack_local.thread_id = tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
  reference_info.stack_local.depth = depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
  reference_info.stack_local.method = method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
  reference_info.stack_local.location = bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
  reference_info.stack_local.slot = slot;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
  // for arrays we need the length, otherwise -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
  jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
  // call into the agent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
  int res = (*cb)(ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
                  &reference_info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
                  wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
                  0,    // referrer_class_tag is 0 for heap root (stack)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
                  wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
                  wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
                  NULL, // referrer_tag is 0 for root
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
                  len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
                  (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
  if (res & JVMTI_VISIT_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
  if (res & JVMTI_VISIT_OBJECTS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
    check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
// This mask is used to pass reference_info to a jvmtiHeapReferenceCallback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
// only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
#define REF_INFO_MASK  ((1 << JVMTI_HEAP_REFERENCE_FIELD)         \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
                      | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD)  \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
                      | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
                      | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
                      | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL)   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
                      | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
// invoke the object reference callback to report a reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
                                                                       oop referrer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
                                                                       oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
                                                                       jint index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
  // field index is only valid field in reference_info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
  static jvmtiHeapReferenceInfo reference_info = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  assert(ServiceUtil::visible_oop(referrer), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
  // check that callback is provider
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
  jvmtiHeapReferenceCallback cb = context->heap_reference_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
  if (cb == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
  if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
  // setup the callback wrapper
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
  TwoOopCallbackWrapper wrapper(tag_map(), referrer, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
    return check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
  // field index is only valid field in reference_info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  reference_info.field.index = index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  // for arrays we need the length, otherwise -1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
  jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
  // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
  int res = (*cb)(ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
                  (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
                  wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
                  wrapper.referrer_klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
                  wrapper.obj_size(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
                  wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
                  wrapper.referrer_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
                  len,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
                  (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
  if (res & JVMTI_VISIT_ABORT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
  if (res & JVMTI_VISIT_OBJECTS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
    check_for_visit(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
// report a "simple root"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
inline bool CallbackInvoker::report_simple_root(jvmtiHeapReferenceKind kind, oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
  assert(kind != JVMTI_HEAP_REFERENCE_STACK_LOCAL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
         kind != JVMTI_HEAP_REFERENCE_JNI_LOCAL, "not a simple root");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
  assert(ServiceUtil::visible_oop(obj), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
    // map to old style root kind
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
    jvmtiHeapRootKind root_kind = toJvmtiHeapRootKind(kind);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
    return invoke_basic_heap_root_callback(root_kind, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
    assert(is_advanced_heap_walk(), "wrong heap walk type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
    return invoke_advanced_heap_root_callback(kind, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
// invoke the primitive array values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
inline bool CallbackInvoker::report_primitive_array_values(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
  assert(obj->is_typeArray(), "not a primitive array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  assert(context->array_primitive_value_callback() != NULL, "no callback");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
  if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
  int res = invoke_array_primitive_value_callback(context->array_primitive_value_callback(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
                                                  &wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
                                                  obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
                                                  (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  return (!(res & JVMTI_VISIT_ABORT));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
// invoke the string value callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
inline bool CallbackInvoker::report_string_value(oop str) {
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  2288
  assert(str->klass() == SystemDictionary::String_klass(), "not a string");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
  assert(context->string_primitive_value_callback() != NULL, "no callback");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
  if (is_filtered_by_klass_filter(str, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
  CallbackWrapper wrapper(tag_map(), str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  int res = invoke_string_value_callback(context->string_primitive_value_callback(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
                                         &wrapper,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
                                         str,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
                                         (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  return (!(res & JVMTI_VISIT_ABORT));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
// invoke the primitive field callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
inline bool CallbackInvoker::report_primitive_field(jvmtiHeapReferenceKind ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
                                                    oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
                                                    jint index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
                                                    address addr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
                                                    char type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
  // for primitive fields only the index will be set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
  static jvmtiHeapReferenceInfo reference_info = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  AdvancedHeapWalkContext* context = advanced_context();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
  assert(context->primitive_field_callback() != NULL, "no callback");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
  // apply class filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
  if (is_filtered_by_klass_filter(obj, context->klass_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
  CallbackWrapper wrapper(tag_map(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
  // apply tag filter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
  if (is_filtered_by_heap_filter(wrapper.obj_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
                                 wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
                                 context->heap_filter())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  // the field index in the referrer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
  reference_info.field.index = index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
  // map the type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
  jvmtiPrimitiveType value_type = (jvmtiPrimitiveType)type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
  // setup the jvalue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
  jvalue value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
  copy_to_jvalue(&value, addr, value_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
  jvmtiPrimitiveFieldCallback cb = context->primitive_field_callback();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
  int res = (*cb)(ref_kind,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
                  &reference_info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
                  wrapper.klass_tag(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
                  wrapper.obj_tag_p(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
                  value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
                  value_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
                  (void*)user_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
  return (!(res & JVMTI_VISIT_ABORT));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
// instance field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
inline bool CallbackInvoker::report_primitive_instance_field(oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
                                                             jint index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
                                                             address value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
                                                             char type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
  return report_primitive_field(JVMTI_HEAP_REFERENCE_FIELD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
                                obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
                                index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
                                value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
                                type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
// static field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
inline bool CallbackInvoker::report_primitive_static_field(oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
                                                           jint index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
                                                           address value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
                                                           char type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
  return report_primitive_field(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
                                obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
                                index,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
                                value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
                                type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
// report a JNI local (root object) to the profiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
inline bool CallbackInvoker::report_jni_local_root(jlong thread_tag, jlong tid, jint depth, jmethodID m, oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
    return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_JNI_LOCAL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
                                           thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
                                           depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
                                           m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
                                           -1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
                                           obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
    return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_JNI_LOCAL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
                                              thread_tag, tid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
                                              depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
                                              m,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
                                              (jlocation)-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
                                              -1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
                                              obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
// report a local (stack reference, root object)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
inline bool CallbackInvoker::report_stack_ref_root(jlong thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
                                                   jlong tid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
                                                   jint depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
                                                   jmethodID method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
                                                   jlocation bci,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
                                                   jint slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
                                                   oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
    return invoke_basic_stack_ref_callback(JVMTI_HEAP_ROOT_STACK_LOCAL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
                                           thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
                                           depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
                                           method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
                                           slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
                                           obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
    return invoke_advanced_stack_ref_callback(JVMTI_HEAP_REFERENCE_STACK_LOCAL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
                                              thread_tag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
                                              tid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
                                              depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
                                              method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
                                              bci,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
                                              slot,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
                                              obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
// report an object referencing a class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
inline bool CallbackInvoker::report_class_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
// report a class referencing its class loader.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
inline bool CallbackInvoker::report_class_loader_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS_LOADER, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CLASS_LOADER, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
// report a class referencing its signers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
inline bool CallbackInvoker::report_signers_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_SIGNERS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SIGNERS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
// report a class referencing its protection domain..
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
inline bool CallbackInvoker::report_protection_domain_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
// report a class referencing its superclass.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
inline bool CallbackInvoker::report_superclass_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
    // Send this to be consistent with past implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CLASS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_SUPERCLASS, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
// report a class referencing one of its interfaces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
inline bool CallbackInvoker::report_interface_reference(oop referrer, oop referree) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_INTERFACE, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_INTERFACE, referrer, referree, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
// report a class referencing one of its static fields.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
inline bool CallbackInvoker::report_static_field_reference(oop referrer, oop referree, jint slot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_STATIC_FIELD, referrer, referree, slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_STATIC_FIELD, referrer, referree, slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
// report an array referencing an element object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
inline bool CallbackInvoker::report_array_element_reference(oop referrer, oop referree, jint index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, referrer, referree, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
// report an object referencing an instance field object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
inline bool CallbackInvoker::report_field_reference(oop referrer, oop referree, jint slot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_FIELD, referrer, referree, slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_FIELD, referrer, referree, slot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
// report an array referencing an element object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
inline bool CallbackInvoker::report_constant_pool_reference(oop referrer, oop referree, jint index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
  if (is_basic_heap_walk()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
    return invoke_basic_object_reference_callback(JVMTI_REFERENCE_CONSTANT_POOL, referrer, referree, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
    return invoke_advanced_object_reference_callback(JVMTI_HEAP_REFERENCE_CONSTANT_POOL, referrer, referree, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
// A supporting closure used to process simple roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
class SimpleRootsClosure : public OopClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
  jvmtiHeapReferenceKind _kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
  bool _continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  jvmtiHeapReferenceKind root_kind()    { return _kind; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
  void set_kind(jvmtiHeapReferenceKind kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
    _kind = kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
    _continue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  inline bool stopped() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
    return !_continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  void do_oop(oop* obj_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
    // iteration has terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
    if (stopped()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
    // ignore null or deleted handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    oop o = *obj_p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
    if (o == NULL || o == JNIHandles::deleted_handle()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
13741
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2557
    assert(Universe::heap()->is_in_reserved(o), "should be impossible");
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2558
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    jvmtiHeapReferenceKind kind = root_kind();
13741
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2560
    if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
      // SystemDictionary::always_strong_oops_do reports the application
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
      // class loader as a root. We want this root to be reported as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
      // a root kind of "OTHER" rather than "SYSTEM_CLASS".
13741
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2564
      if (!o->is_instanceMirror()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
        kind = JVMTI_HEAP_REFERENCE_OTHER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
      }
13741
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2567
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
    // some objects are ignored - in the case of simple
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 7916
diff changeset
  2570
    // roots it's mostly Symbol*s that we are skipping
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
    // here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
    if (!ServiceUtil::visible_oop(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
    // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
    _continue = CallbackInvoker::report_simple_root(kind, o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
  }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
  2580
  virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
// A supporting closure used to process JNI locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
class JNILocalRootsClosure : public OopClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  jlong _thread_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  jlong _tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  jint _depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
  jmethodID _method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
  bool _continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
  void set_context(jlong thread_tag, jlong tid, jint depth, jmethodID method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
    _thread_tag = thread_tag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
    _tid = tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
    _depth = depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
    _method = method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
    _continue = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
  inline bool stopped() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
    return !_continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  void do_oop(oop* obj_p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
    // iteration has terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
    if (stopped()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
    // ignore null or deleted handles
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
    oop o = *obj_p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
    if (o == NULL || o == JNIHandles::deleted_handle()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
    if (!ServiceUtil::visible_oop(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
    // invoke the callback
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
    _continue = CallbackInvoker::report_jni_local_root(_thread_tag, _tid, _depth, _method, o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
  }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
  2623
  virtual void do_oop(narrowOop* obj_p) { ShouldNotReachHere(); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
// A VM operation to iterate over objects that are reachable from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
// a set of roots or an initial object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
// For VM_HeapWalkOperation the set of roots used is :-
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
// - All JNI global references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
// - All inflated monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
// - All classes loaded by the boot class loader (or all classes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
//     in the event that class unloading is disabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
// - All java threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
// - For each java thread then all locals and JNI local references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
//      on the thread's execution stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
// - All visible/explainable objects from Universes::oops_do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
class VM_HeapWalkOperation: public VM_Operation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
  enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
    initial_visit_stack_size = 4000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
  bool _is_advanced_heap_walk;                      // indicates FollowReferences
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
  JvmtiTagMap* _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  Handle _initial_object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
  GrowableArray<oop>* _visit_stack;                 // the visit stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
  bool _collecting_heap_roots;                      // are we collecting roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
  bool _following_object_refs;                      // are we following object references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
  bool _reporting_primitive_fields;                 // optional reporting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
  bool _reporting_primitive_array_values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
  bool _reporting_string_values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
  GrowableArray<oop>* create_visit_stack() {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 13096
diff changeset
  2660
    return new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(initial_visit_stack_size, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
  bool is_advanced_heap_walk() const               { return _is_advanced_heap_walk; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
  JvmtiTagMap* tag_map() const                     { return _tag_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
  Handle initial_object() const                    { return _initial_object; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
  bool is_following_references() const             { return _following_object_refs; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
  bool is_reporting_primitive_fields()  const      { return _reporting_primitive_fields; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  bool is_reporting_primitive_array_values() const { return _reporting_primitive_array_values; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  bool is_reporting_string_values() const          { return _reporting_string_values; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
  GrowableArray<oop>* visit_stack() const          { return _visit_stack; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
  // iterate over the various object types
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  inline bool iterate_over_array(oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
  inline bool iterate_over_type_array(oop o);
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2679
  inline bool iterate_over_class(oop o);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
  inline bool iterate_over_object(oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  // root collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  inline bool collect_simple_roots();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
  inline bool collect_stack_roots();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  inline bool collect_stack_roots(JavaThread* java_thread, JNILocalRootsClosure* blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  // visit an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
  inline bool visit(oop o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  VM_HeapWalkOperation(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
                       Handle initial_object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
                       BasicHeapWalkContext callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
                       const void* user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
  VM_HeapWalkOperation(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
                       Handle initial_object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
                       AdvancedHeapWalkContext callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
                       const void* user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
  ~VM_HeapWalkOperation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
  VMOp_Type type() const { return VMOp_HeapWalkOperation; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  void doit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
                                           Handle initial_object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
                                           BasicHeapWalkContext callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
                                           const void* user_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
  _is_advanced_heap_walk = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
  _tag_map = tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  _initial_object = initial_object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  _following_object_refs = (callbacks.object_ref_callback() != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
  _reporting_primitive_fields = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  _reporting_primitive_array_values = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
  _reporting_string_values = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
  _visit_stack = create_visit_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
  CallbackInvoker::initialize_for_basic_heap_walk(tag_map, _visit_stack, user_data, callbacks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
VM_HeapWalkOperation::VM_HeapWalkOperation(JvmtiTagMap* tag_map,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
                                           Handle initial_object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
                                           AdvancedHeapWalkContext callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
                                           const void* user_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
  _is_advanced_heap_walk = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
  _tag_map = tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  _initial_object = initial_object;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  _following_object_refs = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
  _reporting_primitive_fields = (callbacks.primitive_field_callback() != NULL);;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  _reporting_primitive_array_values = (callbacks.array_primitive_value_callback() != NULL);;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  _reporting_string_values = (callbacks.string_primitive_value_callback() != NULL);;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  _visit_stack = create_visit_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
  CallbackInvoker::initialize_for_advanced_heap_walk(tag_map, _visit_stack, user_data, callbacks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
VM_HeapWalkOperation::~VM_HeapWalkOperation() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
  if (_following_object_refs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
    assert(_visit_stack != NULL, "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
    delete _visit_stack;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
    _visit_stack = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
// an array references its class and has a reference to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
// each element in the array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
inline bool VM_HeapWalkOperation::iterate_over_array(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  objArrayOop array = objArrayOop(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
  // array reference to its class
13952
e3cf184080bc 8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents: 13741
diff changeset
  2755
  oop mirror = ObjArrayKlass::cast(array->klass())->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  if (!CallbackInvoker::report_class_reference(o, mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
  // iterate over the array and report each reference to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
  // non-null element
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
  for (int index=0; index<array->length(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
    oop elem = array->obj_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
    if (elem == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
    // report the array reference o[index] = elem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
    if (!CallbackInvoker::report_array_element_reference(o, elem, index)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
// a type array references its class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
inline bool VM_HeapWalkOperation::iterate_over_type_array(oop o) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2778
  Klass* k = o->klass();
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14082
diff changeset
  2779
  oop mirror = k->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
  if (!CallbackInvoker::report_class_reference(o, mirror)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  // report the array contents if required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  if (is_reporting_primitive_array_values()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
    if (!CallbackInvoker::report_primitive_array_values(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
// verify that a static oop field is in range
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2794
static inline bool verify_static_oop(InstanceKlass* ik,
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
  2795
                                     oop mirror, int offset) {
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
  2796
  address obj_p = (address)mirror + offset;
13738
d67be49a5beb 7195833: NPG: Rename instanceClassLoaderKlass, instanceRefKlass and instanceMirrorKlass
coleenp
parents: 13728
diff changeset
  2797
  address start = (address)InstanceMirrorKlass::start_of_static_fields(mirror);
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
  2798
  address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
  assert(end >= start, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  if (obj_p >= start && obj_p < end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
// a class references its super class, interfaces, class loader, ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
// and finally its static fields
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2810
inline bool VM_HeapWalkOperation::iterate_over_class(oop java_class) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  int i;
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2812
  Klass* klass = java_lang_Class::as_Klass(java_class);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
  if (klass->oop_is_instance()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2815
    InstanceKlass* ik = InstanceKlass::cast(klass);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
    // ignore the class if it's has been initialized yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
    if (!ik->is_linked()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
    // get the java mirror
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
    oop mirror = klass->java_mirror();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
    // super (only if something more interesting than java.lang.Object)
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2826
    Klass* java_super = ik->java_super();
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  2827
    if (java_super != NULL && java_super != SystemDictionary::Object_klass()) {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14082
diff changeset
  2828
      oop super = java_super->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
      if (!CallbackInvoker::report_superclass_reference(mirror, super)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
    // class loader
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
    oop cl = ik->class_loader();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
    if (cl != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
      if (!CallbackInvoker::report_class_loader_reference(mirror, cl)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
    // protection domain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
    oop pd = ik->protection_domain();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
    if (pd != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
      if (!CallbackInvoker::report_protection_domain_reference(mirror, pd)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
    // signers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
    oop signers = ik->signers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
    if (signers != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
      if (!CallbackInvoker::report_signers_reference(mirror, signers)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
    // references from the constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
    {
17370
59a0620561fa 8003557: NPG: Klass* const k should be const Klass* k.
minqi
parents: 17087
diff changeset
  2860
      ConstantPool* pool = ik->constants();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
      for (int i = 1; i < pool->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
        constantTag tag = pool->tag_at(i).value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
        if (tag.is_string() || tag.is_klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
          oop entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
          if (tag.is_string()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
            entry = pool->resolved_string_at(i);
13976
93a075193661 8000459: assert(java_lang_String::is_instance(entry)) failure with various mlvm tests.
jiangli
parents: 13741
diff changeset
  2867
            // If the entry is non-null it is resolved.
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2868
            if (entry == NULL) continue;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
          } else {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14082
diff changeset
  2870
            entry = pool->resolved_klass_at(i)->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
          if (!CallbackInvoker::report_constant_pool_reference(mirror, entry, (jint)i)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
            return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
    // interfaces
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
    // (These will already have been reported as references from the constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
    //  but are specified by IterateOverReachableObjects and must be reported).
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2882
    Array<Klass*>* interfaces = ik->local_interfaces();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
    for (i = 0; i < interfaces->length(); i++) {
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14082
diff changeset
  2884
      oop interf = ((Klass*)interfaces->at(i))->java_mirror();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
      if (interf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
      if (!CallbackInvoker::report_interface_reference(mirror, interf)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
    // iterate over the static fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2895
    ClassFieldMap* field_map = ClassFieldMap::create_map_of_static_fields(klass);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
    for (i=0; i<field_map->field_count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
      ClassFieldDescriptor* field = field_map->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
      char type = field->field_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
      if (!is_primitive_field_type(type)) {
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
  2900
        oop fld_o = mirror->obj_field(field->field_offset());
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8076
diff changeset
  2901
        assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
        if (fld_o != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
          int slot = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
          if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
            delete field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
            return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
         if (is_reporting_primitive_fields()) {
8726
7bafcf0e5bfb 7029509: nightly failures after static fields in Class
never
parents: 8725
diff changeset
  2911
           address addr = (address)mirror + field->field_offset();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
           int slot = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
           if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
             delete field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
             return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
    delete field_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
// an object references a class and its instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
// (static fields are ignored here as we report these as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
// references from the class).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
inline bool VM_HeapWalkOperation::iterate_over_object(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
  // reference to the class
14488
ab48109f7d1b 8001471: Klass::cast() does nothing
hseigel
parents: 14082
diff changeset
  2933
  if (!CallbackInvoker::report_class_reference(o, o->klass()->java_mirror())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
  // iterate over instance fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
  ClassFieldMap* field_map = JvmtiCachedClassFieldMap::get_map_of_instance_fields(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
  for (int i=0; i<field_map->field_count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
    ClassFieldDescriptor* field = field_map->field_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
    char type = field->field_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
    if (!is_primitive_field_type(type)) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
  2943
      oop fld_o = o->obj_field(field->field_offset());
11773
7c8ab49996da 7130993: nsk/jdi/ReferenceType/instances/instances004 fails with JFR: assert(ServiceUtil::visible_oop(obj))
sspitsyn
parents: 10229
diff changeset
  2944
      // ignore any objects that aren't visible to profiler
7c8ab49996da 7130993: nsk/jdi/ReferenceType/instances/instances004 fails with JFR: assert(ServiceUtil::visible_oop(obj))
sspitsyn
parents: 10229
diff changeset
  2945
      if (fld_o != NULL && ServiceUtil::visible_oop(fld_o)) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2946
        assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not "
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  2947
               "have references to Klass* anymore");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
        int slot = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
        if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
      if (is_reporting_primitive_fields()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
        // primitive instance field
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
        address addr = (address)o + field->field_offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
        int slot = field->field_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
        if (!CallbackInvoker::report_primitive_instance_field(o, slot, addr, type)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
          return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
  // if the object is a java.lang.String
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  if (is_reporting_string_values() &&
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  2967
      o->klass() == SystemDictionary::String_klass()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
    if (!CallbackInvoker::report_string_value(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
10229
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  2976
// Collects all simple (non-stack) roots except for threads;
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  2977
// threads are handled in collect_stack_roots() as an optimization.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
// if there's a heap root callback provided then the callback is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
// invoked for each simple root.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
// if an object reference callback is provided then all simple
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
// roots are pushed onto the marking stack so that they can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
// processed later
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
inline bool VM_HeapWalkOperation::collect_simple_roots() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  SimpleRootsClosure blk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  // JNI globals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
  blk.set_kind(JVMTI_HEAP_REFERENCE_JNI_GLOBAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
  JNIHandles::oops_do(&blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
  if (blk.stopped()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  // Preloaded classes and loader from the system dictionary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
  blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
  SystemDictionary::always_strong_oops_do(&blk);
13741
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2997
  KlassToOopClosure klass_blk(&blk);
e4395deb8597 7197350: NPG: jvmtiHeapReferenceCallback receives incorrect reference_kind for system class roots
stefank
parents: 13738
diff changeset
  2998
  ClassLoaderDataGraph::always_strong_oops_do(&blk, &klass_blk, false);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
  if (blk.stopped()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
  // Inflated monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
  blk.set_kind(JVMTI_HEAP_REFERENCE_MONITOR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
  ObjectSynchronizer::oops_do(&blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
  if (blk.stopped()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
10229
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3010
  // threads are now handled in collect_stack_roots()
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
  // Other kinds of roots maintained by HotSpot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
  // Many of these won't be visible but others (such as instances of important
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
  // exceptions) will be visible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
  Universe::oops_do(&blk);
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3017
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3018
  // If there are any non-perm roots in the code cache, visit them.
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3019
  blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3020
  CodeBlobToOopClosure look_in_blobs(&blk, false);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3021
  CodeCache::scavenge_root_nmethods_do(&look_in_blobs);
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 2105
diff changeset
  3022
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
// Walk the stack of a given thread and find all references (locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
// and JNI calls) and report these as stack references
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
inline bool VM_HeapWalkOperation::collect_stack_roots(JavaThread* java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
                                                      JNILocalRootsClosure* blk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
  oop threadObj = java_thread->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
  assert(threadObj != NULL, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
  // only need to get the thread's tag once per thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
  jlong thread_tag = tag_for(_tag_map, threadObj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
  // also need the thread id
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
  jlong tid = java_lang_Thread::thread_id(threadObj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
  if (java_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
    // vframes are resource allocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
    Thread* current_thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
    ResourceMark rm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
    HandleMark hm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
    RegisterMap reg_map(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
    frame f = java_thread->last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
    vframe* vf = vframe::new_vframe(&f, &reg_map, java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
    bool is_top_frame = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
    int depth = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
    frame* last_entry_frame = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
    while (vf != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
      if (vf->is_java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
        // java frame (interpreted, compiled, ...)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
        javaVFrame *jvf = javaVFrame::cast(vf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
        // the jmethodID
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
        jmethodID method = jvf->method()->jmethod_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
        if (!(jvf->method()->is_native())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
          jlocation bci = (jlocation)jvf->bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
          StackValueCollection* locals = jvf->locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
          for (int slot=0; slot<locals->size(); slot++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
            if (locals->at(slot)->type() == T_OBJECT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
              oop o = locals->obj_at(slot)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
              if (o == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
                continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
              // stack reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
              if (!CallbackInvoker::report_stack_ref_root(thread_tag, tid, depth, method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
                                                   bci, slot, o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
                return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
          blk->set_context(thread_tag, tid, depth, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
          if (is_top_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
            // JNI locals for the top frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
            java_thread->active_handles()->oops_do(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
            if (last_entry_frame != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
              // JNI locals for the entry frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
              assert(last_entry_frame->is_entry_frame(), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
              last_entry_frame->entry_frame_call_wrapper()->handles()->oops_do(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
        last_entry_frame = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
        depth++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
        // externalVFrame - for an entry frame then we report the JNI locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
        // when we find the corresponding javaVFrame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
        frame* fr = vf->frame_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
        assert(fr != NULL, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
        if (fr->is_entry_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
          last_entry_frame = fr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
      vf = vf->sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
      is_top_frame = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
    // no last java frame but there may be JNI locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
    blk->set_context(thread_tag, tid, 0, (jmethodID)NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
    java_thread->active_handles()->oops_do(blk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
10229
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3119
// Collects the simple roots for all threads and collects all
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3120
// stack roots - for each thread it walks the execution
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
// stack to find all references and local JNI refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
inline bool VM_HeapWalkOperation::collect_stack_roots() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
  JNILocalRootsClosure blk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
  for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
    oop threadObj = thread->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
    if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
10229
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3127
      // Collect the simple root for this thread before we
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3128
      // collect its stack roots
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3129
      if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3130
                                               threadObj)) {
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3131
        return false;
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3132
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
      if (!collect_stack_roots(thread, &blk)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
// visit an object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
// first mark the object as visited
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
// second get all the outbound references from this object (in other words, all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
// the objects referenced by this object).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
bool VM_HeapWalkOperation::visit(oop o) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
  // mark object as visited
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
  assert(!ObjectMarker::visited(o), "can't visit same object more than once");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
  ObjectMarker::mark(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
  // instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
  if (o->is_instance()) {
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 3908
diff changeset
  3153
    if (o->klass() == SystemDictionary::Class_klass()) {
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  3154
      if (!java_lang_Class::is_primitive(o)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
        // a java.lang.Class
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 13391
diff changeset
  3156
        return iterate_over_class(o);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
      return iterate_over_object(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
  // object array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
  if (o->is_objArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
    return iterate_over_array(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
  // type array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
  if (o->is_typeArray()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
    return iterate_over_type_array(o);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
void VM_HeapWalkOperation::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
  ObjectMarkerController marker;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
  ClassFieldMapCacheMark cm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
  assert(visit_stack()->is_empty(), "visit stack must be empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
  // the heap walk starts with an initial object or the heap roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
  if (initial_object().is_null()) {
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3185
    // If either collect_stack_roots() or collect_simple_roots()
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3186
    // returns false at this point, then there are no mark bits
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3187
    // to reset.
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3188
    ObjectMarker::set_needs_reset(false);
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3189
10229
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3190
    // Calling collect_stack_roots() before collect_simple_roots()
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3191
    // can result in a big performance boost for an agent that is
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3192
    // focused on analyzing references in the thread stacks.
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3193
    if (!collect_stack_roots()) return;
7b358d5def21 6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
dcubed
parents: 10228
diff changeset
  3194
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
    if (!collect_simple_roots()) return;
10228
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3196
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3197
    // no early return so enable heap traversal to reset the mark bits
e5e1539de725 7043987: 3/3 JVMTI FollowReferences is slow
dcubed
parents: 9630
diff changeset
  3198
    ObjectMarker::set_needs_reset(true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
    visit_stack()->push(initial_object()());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  // object references required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
  if (is_following_references()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
    // visit each object until all reachable objects have been
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
    // visited or the callback asked to terminate the iteration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
    while (!visit_stack()->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
      oop o = visit_stack()->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
      if (!ObjectMarker::visited(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
        if (!visit(o)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
// iterate over all objects that are reachable from a set of roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
                                                 jvmtiStackReferenceCallback stack_ref_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
                                                 jvmtiObjectReferenceCallback object_ref_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
                                                 const void* user_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
  MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
  BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
  VM_HeapWalkOperation op(this, Handle(), context, user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
  VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
// iterate over all objects that are reachable from a given object
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
                                                             jvmtiObjectReferenceCallback object_ref_callback,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
                                                             const void* user_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
  oop obj = JNIHandles::resolve(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
  Handle initial_object(Thread::current(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
  MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
  BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
  VM_HeapWalkOperation op(this, initial_object, context, user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
  VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
// follow references from an initial object or the GC roots
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
void JvmtiTagMap::follow_references(jint heap_filter,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
                                    KlassHandle klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
                                    jobject object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
                                    const jvmtiHeapCallbacks* callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
                                    const void* user_data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
  oop obj = JNIHandles::resolve(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
  Handle initial_object(Thread::current(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
  MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
  AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
  VM_HeapWalkOperation op(this, initial_object, context, user_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
  VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3260
void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
7916
84e5b29decb0 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 7896
diff changeset
  3261
  // No locks during VM bring-up (0 threads) and no safepoints after main
84e5b29decb0 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 7896
diff changeset
  3262
  // thread creation and before VMThread creation (1 thread); initial GC
84e5b29decb0 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 7896
diff changeset
  3263
  // verification can happen in that window which gets to here.
84e5b29decb0 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 7896
diff changeset
  3264
  assert(Threads::number_of_threads() <= 1 ||
84e5b29decb0 7012493: 2/2 6849574/Test.java fails with Internal Error (src/share/vm/prims/jvmtiTagMap.cpp:3294)
dcubed
parents: 7896
diff changeset
  3265
         SafepointSynchronize::is_at_safepoint(),
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3266
         "must be executed at a safepoint");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  if (JvmtiEnv::environments_might_exist()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
    for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
      JvmtiTagMap* tag_map = env->tag_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
      if (tag_map != NULL && !tag_map->is_empty()) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3272
        tag_map->do_weak_oops(is_alive, f);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3278
void JvmtiTagMap::do_weak_oops(BoolObjectClosure* is_alive, OopClosure* f) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
  // does this environment have the OBJECT_FREE event enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
  bool post_object_free = env()->is_enabled(JVMTI_EVENT_OBJECT_FREE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
  // counters used for trace message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  int freed = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
  int moved = 0;
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3286
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3287
  JvmtiTagHashmap* hashmap = this->hashmap();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  // reenable sizing (if disabled)
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3290
  hashmap->set_resizing_enabled(true);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3291
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3292
  // if the hashmap is empty then we can skip it
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3293
  if (hashmap->_entry_count == 0) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3294
    return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3297
  // now iterate through each entry in the table
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3298
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3299
  JvmtiTagHashmapEntry** table = hashmap->table();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3300
  int size = hashmap->size();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3301
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3302
  JvmtiTagHashmapEntry* delayed_add = NULL;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3303
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3304
  for (int pos = 0; pos < size; ++pos) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3305
    JvmtiTagHashmapEntry* entry = table[pos];
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3306
    JvmtiTagHashmapEntry* prev = NULL;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3307
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3308
    while (entry != NULL) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3309
      JvmtiTagHashmapEntry* next = entry->next();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3310
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3311
      oop* obj = entry->object_addr();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3312
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3313
      // has object been GC'ed
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3314
      if (!is_alive->do_object_b(entry->object())) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3315
        // grab the tag
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3316
        jlong tag = entry->tag();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3317
        guarantee(tag != 0, "checking");
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3318
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3319
        // remove GC'ed entry from hashmap and return the
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3320
        // entry to the free list
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3321
        hashmap->remove(prev, pos, entry);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3322
        destroy_entry(entry);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3323
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3324
        // post the event to the profiler
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3325
        if (post_object_free) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3326
          JvmtiExport::post_object_free(env(), tag);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3327
        }
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3328
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3329
        ++freed;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3330
      } else {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3331
        f->do_oop(entry->object_addr());
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3332
        oop new_oop = entry->object();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3333
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3334
        // if the object has moved then re-hash it and move its
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3335
        // entry to its new location.
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3336
        unsigned int new_pos = JvmtiTagHashmap::hash(new_oop, size);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3337
        if (new_pos != (unsigned int)pos) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3338
          if (prev == NULL) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3339
            table[pos] = next;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3340
          } else {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3341
            prev->set_next(next);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
          }
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3343
          if (new_pos < (unsigned int)pos) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
            entry->set_next(table[new_pos]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
            table[new_pos] = entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
          } else {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3347
            // Delay adding this entry to it's new position as we'd end up
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3348
            // hitting it again during this iteration.
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3349
            entry->set_next(delayed_add);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3350
            delayed_add = entry;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
          }
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3352
          moved++;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
        } else {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3354
          // object didn't move
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3355
          prev = entry;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
      }
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3358
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3359
      entry = next;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3363
  // Re-add all the entries which were kept aside
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3364
  while (delayed_add != NULL) {
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3365
    JvmtiTagHashmapEntry* next = delayed_add->next();
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3366
    unsigned int pos = JvmtiTagHashmap::hash(delayed_add->object(), size);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3367
    delayed_add->set_next(table[pos]);
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3368
    table[pos] = delayed_add;
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3369
    delayed_add = next;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  // stats
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
  if (TraceJVMTIObjectTagging) {
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3374
    int post_total = hashmap->_entry_count;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    int pre_total = post_total + freed;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
7896
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3377
    tty->print_cr("(%d->%d, %d freed, %d total moves)",
08aadd7aa3ee 6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents: 7397
diff changeset
  3378
        pre_total, post_total, freed, moved);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
}