hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 3261 c7d5aae8d3f7
child 4571 80b553bddc26
child 4492 63c49e60fc25
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
3261
c7d5aae8d3f7 6862919: Update copyright year
xdono
parents: 3171
diff changeset
     2
 * Copyright 2003-2009 Sun Microsystems, Inc.  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
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_jvmtiEnvBase.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
// JvmtiEnvBase
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
JvmtiEnvBase* JvmtiEnvBase::_head_environment = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
bool JvmtiEnvBase::_globally_initialized = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
volatile bool JvmtiEnvBase::_needs_clean_up = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
jvmtiPhase JvmtiEnvBase::_phase = JVMTI_PHASE_PRIMORDIAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
volatile int JvmtiEnvBase::_dying_thread_env_iteration_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
extern jvmtiInterface_1_ jvmti_Interface;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
extern jvmtiInterface_1_ jvmtiTrace_Interface;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// perform initializations that must occur before any JVMTI environments
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// are released but which should only be initialized once (no matter
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// how many environments are created).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
JvmtiEnvBase::globally_initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  assert(_globally_initialized == false, "bad call");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  JvmtiManageCapabilities::initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  // register extension functions and events
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  JvmtiExtensions::register_extensions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
#endif // !JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
#ifdef JVMTI_TRACE
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  JvmtiTrace::initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  _globally_initialized = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
JvmtiEnvBase::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  // Add this environment to the end of the environment list (order is important)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    // This block of code must not contain any safepoints, as list deallocation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    // (which occurs at a safepoint) cannot occur simultaneously with this list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    // addition.  Note: No_Safepoint_Verifier cannot, currently, be used before
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    // threads exist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
    JvmtiEnvBase *previous_env = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
    for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
      previous_env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    if (previous_env == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
      _head_environment = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
      previous_env->set_next_environment(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  if (_globally_initialized == false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    globally_initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
2137
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
    97
bool
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
    98
JvmtiEnvBase::is_valid() {
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
    99
  jint value = 0;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   100
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   101
  // This object might not be a JvmtiEnvBase so we can't assume
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   102
  // the _magic field is properly aligned. Get the value in a safe
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   103
  // way and then check against JVMTI_MAGIC.
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   104
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   105
  switch (sizeof(_magic)) {
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   106
  case 2:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   107
    value = Bytes::get_native_u2((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   108
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   109
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   110
  case 4:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   111
    value = Bytes::get_native_u4((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   112
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   113
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   114
  case 8:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   115
    value = Bytes::get_native_u8((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   116
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   117
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   118
  default:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   119
    guarantee(false, "_magic field is an unexpected size");
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   120
  }
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   121
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   122
  return value == JVMTI_MAGIC;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   123
}
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   124
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 2135
diff changeset
   125
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
JvmtiEnvBase::JvmtiEnvBase() : _env_event_enable() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  _env_local_storage = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  _tag_map = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  _native_method_prefix_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  _native_method_prefixes = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  _next = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  _class_file_load_hook_ever_enabled = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // Moot since ClassFileLoadHook not yet enabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  // But "true" will give a more predictable ClassFileLoadHook behavior
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  // for environment creation during ClassFileLoadHook.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  _is_retransformable = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // all callbacks initially NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  // all capabilities initially off
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  memset(&_current_capabilities, 0, sizeof(_current_capabilities));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // all prohibited capabilities initially off
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  memset(&_prohibited_capabilities, 0, sizeof(_prohibited_capabilities));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  _magic = JVMTI_MAGIC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  JvmtiEventController::env_initialize((JvmtiEnv*)this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
#ifdef JVMTI_TRACE
1403
3be05c51cf44 6753795: HotSpot crash in strlen() when JVMTI is used
never
parents: 1
diff changeset
   153
  _jvmti_external.functions = TraceJVMTI != NULL ? &jvmtiTrace_Interface : &jvmti_Interface;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  _jvmti_external.functions = &jvmti_Interface;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
JvmtiEnvBase::dispose() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
#ifdef JVMTI_TRACE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  JvmtiTrace::shutdown();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  // Dispose of event info and let the event controller call us back
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  // in a locked state (env_dispose, below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  JvmtiEventController::env_dispose(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
JvmtiEnvBase::env_dispose() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  // We have been entered with all events disabled on this environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // A race to re-enable events (by setting callbacks) is prevented by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // checking for a valid environment when setting callbacks (while
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  // holding the JvmtiThreadState_lock).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  // Mark as invalid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  _magic = DISPOSED_MAGIC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // Relinquish all capabilities.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  jvmtiCapabilities *caps = get_capabilities();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  JvmtiManageCapabilities::relinquish_capabilities(caps, caps, caps);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // Same situation as with events (see above)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  set_native_method_prefixes(0, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  set_tag_map(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  // A tag map can be big, deallocate it now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  if (tag_map_to_deallocate != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    delete tag_map_to_deallocate;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
#endif // !JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  _needs_clean_up = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
JvmtiEnvBase::~JvmtiEnvBase() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  // There is a small window of time during which the tag map of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  // disposed environment could have been reallocated.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  // Make sure it is gone.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  JvmtiTagMap* tag_map_to_deallocate = _tag_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  set_tag_map(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  // A tag map can be big, deallocate it now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  if (tag_map_to_deallocate != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    delete tag_map_to_deallocate;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
#endif // !JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  _magic = BAD_MAGIC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
JvmtiEnvBase::periodic_clean_up() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  // JvmtiEnvBase reference is saved in JvmtiEnvThreadState. So
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  // clean up JvmtiThreadState before deleting JvmtiEnv pointer.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  JvmtiThreadState::periodic_clean_up();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // Unlink all invalid environments from the list of environments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  // and deallocate them
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  JvmtiEnvBase* previous_env = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  JvmtiEnvBase* env = it.first();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  while (env != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
    if (env->is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
      previous_env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
      env = it.next(env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
      // This one isn't valid, remove it from the list and deallocate it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      JvmtiEnvBase* defunct_env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      env = it.next(env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      if (previous_env == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
        _head_environment = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
        previous_env->set_next_environment(env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      delete defunct_env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
JvmtiEnvBase::check_for_periodic_clean_up() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  class ThreadInsideIterationClosure: public ThreadClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
   private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    bool _inside;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
   public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    ThreadInsideIterationClosure() : _inside(false) {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    void do_thread(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      _inside |= thread->is_inside_jvmti_env_iteration();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    bool is_inside_jvmti_env_iteration() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
      return _inside;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  if (_needs_clean_up) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    // Check if we are currently iterating environment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    // deallocation should not occur if we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
    ThreadInsideIterationClosure tiic;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    Threads::threads_do(&tiic);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    if (!tiic.is_inside_jvmti_env_iteration() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
             !is_inside_dying_thread_env_iteration()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      _needs_clean_up = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      JvmtiEnvBase::periodic_clean_up();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
JvmtiEnvBase::record_first_time_class_file_load_hook_enabled() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
         "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  if (!_class_file_load_hook_ever_enabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    _class_file_load_hook_ever_enabled = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    if (get_capabilities()->can_retransform_classes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
      _is_retransformable = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      _is_retransformable = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      // cannot add retransform capability after ClassFileLoadHook has been enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      get_prohibited_capabilities()->can_retransform_classes = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
JvmtiEnvBase::record_class_file_load_hook_enabled() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  if (!_class_file_load_hook_ever_enabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    if (Threads::number_of_threads() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
      record_first_time_class_file_load_hook_enabled();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
      MutexLocker mu(JvmtiThreadState_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
      record_first_time_class_file_load_hook_enabled();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
JvmtiEnvBase::set_native_method_prefixes(jint prefix_count, char** prefixes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
         "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  int old_prefix_count = get_native_method_prefix_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  char **old_prefixes = get_native_method_prefixes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  // allocate and install the new prefixex
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  if (prefix_count == 0 || !is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    _native_method_prefix_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    _native_method_prefixes = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    // there are prefixes, allocate an array to hold them, and fill it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    if (new_prefixes == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
      return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    for (int i = 0; i < prefix_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
      char* prefix = prefixes[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
      if (prefix == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
        for (int j = 0; j < (i-1); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
          os::free(new_prefixes[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
        os::free(new_prefixes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
        return JVMTI_ERROR_NULL_POINTER;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
      prefix = os::strdup(prefixes[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
      if (prefix == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
        for (int j = 0; j < (i-1); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
          os::free(new_prefixes[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
        os::free(new_prefixes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
        return JVMTI_ERROR_OUT_OF_MEMORY;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
      new_prefixes[i] = prefix;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    _native_method_prefix_count = prefix_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    _native_method_prefixes = new_prefixes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  // now that we know the new prefixes have been successfully installed we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  // safely remove the old ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  if (old_prefix_count != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    for (int i = 0; i < old_prefix_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
      os::free(old_prefixes[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    os::free(old_prefixes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  return JVMTI_ERROR_NONE;
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
// Collect all the prefixes which have been set in any JVM TI environments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// by the SetNativeMethodPrefix(es) functions.  Be sure to maintain the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
// order of environments and the order of prefixes within each environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
// Return in a resource allocated array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
char**
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
JvmtiEnvBase::get_all_native_method_prefixes(int* count_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  assert(Threads::number_of_threads() == 0 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
         SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
         JvmtiThreadState_lock->is_locked(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
         "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  int total_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  GrowableArray<char*>* prefix_array =new GrowableArray<char*>(5);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    int prefix_count = env->get_native_method_prefix_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
    char** prefixes = env->get_native_method_prefixes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    for (int j = 0; j < prefix_count; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
      // retrieve a prefix and so that it is safe against asynchronous changes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
      // copy it into the resource area
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
      char* prefix = prefixes[j];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
      char* prefix_copy = NEW_RESOURCE_ARRAY(char, strlen(prefix)+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
      strcpy(prefix_copy, prefix);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
      prefix_array->at_put_grow(total_count++, prefix_copy);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  char** all_prefixes = NEW_RESOURCE_ARRAY(char*, total_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  char** p = all_prefixes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  for (int i = 0; i < total_count; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
    *p++ = prefix_array->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  *count_ptr = total_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  return all_prefixes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
JvmtiEnvBase::set_event_callbacks(const jvmtiEventCallbacks* callbacks,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
                                               jint size_of_callbacks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  size_t byte_cnt = sizeof(jvmtiEventCallbacks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  // clear in either case to be sure we got any gap between sizes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  memset(&_event_callbacks, 0, byte_cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  // Now that JvmtiThreadState_lock is held, prevent a possible race condition where events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  // are re-enabled by a call to set event callbacks where the DisposeEnvironment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  // occurs after the boiler-plate environment check and before the lock is acquired.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  if (callbacks != NULL && is_valid()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
    if (size_of_callbacks < (jint)byte_cnt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      byte_cnt = size_of_callbacks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
    memcpy(&_event_callbacks, callbacks, byte_cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
// Called from JVMTI entry points which perform stack walking. If the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
// associated JavaThread is the current thread, then wait_for_suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
// is not used. Otherwise, it determines if we should wait for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
// "other" thread to complete external suspension. (NOTE: in future
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
// releases the suspension mechanism should be reimplemented so this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
// is not necessary.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
JvmtiEnvBase::is_thread_fully_suspended(JavaThread* thr, bool wait_for_suspend, uint32_t *bits) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
  // "other" threads require special handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  if (thr != JavaThread::current()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    if (wait_for_suspend) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      // We are allowed to wait for the external suspend to complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
      // so give the other thread a chance to get suspended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
      if (!thr->wait_for_ext_suspend_completion(SuspendRetryCount,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
          SuspendRetryDelay, bits)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
        // didn't make it so let the caller know
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
        return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    // We aren't allowed to wait for the external suspend to complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    // so if the other thread isn't externally suspended we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    // let the caller know.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    else if (!thr->is_ext_suspend_completed_with_lock(bits)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
// In the fullness of time, all users of the method should instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
// directly use allocate, besides being cleaner and faster, this will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
// mean much better out of memory handling
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
unsigned char *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
JvmtiEnvBase::jvmtiMalloc(jlong size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  unsigned char* mem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  jvmtiError result = allocate(size, &mem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  assert(result == JVMTI_ERROR_NONE, "Allocate failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  return mem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
// Threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
jobject *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
JvmtiEnvBase::new_jobjectArray(int length, Handle *handles) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  if (length == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  jobject *objArray = (jobject *) jvmtiMalloc(sizeof(jobject) * length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  NULL_CHECK(objArray, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  for (int i=0; i<length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    objArray[i] = jni_reference(handles[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  return objArray;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
jthread *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
JvmtiEnvBase::new_jthreadArray(int length, Handle *handles) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  return (jthread *) new_jobjectArray(length,handles);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
jthreadGroup *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
JvmtiEnvBase::new_jthreadGroupArray(int length, Handle *handles) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  return (jthreadGroup *) new_jobjectArray(length,handles);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
JavaThread *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
JvmtiEnvBase::get_JavaThread(jthread jni_thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  oop t = JNIHandles::resolve_external_guard(jni_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  if (t == NULL || !t->is_a(SystemDictionary::thread_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // The following returns NULL if the thread has not yet run or is in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  // process of exiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  return java_lang_Thread::thread(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
// update the access_flags for the field in the klass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
JvmtiEnvBase::update_klass_field_access_flag(fieldDescriptor *fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  instanceKlass* ik = instanceKlass::cast(fd->field_holder());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  typeArrayOop fields = ik->fields();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  fields->ushort_at_put(fd->index(), (jushort)fd->access_flags().as_short());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
// return the vframe on the specified thread and depth, NULL if no such frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
vframe*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
JvmtiEnvBase::vframeFor(JavaThread* java_thread, jint depth) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  if (!java_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  RegisterMap reg_map(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  vframe *vf = java_thread->last_java_vframe(&reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  int d = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  while ((vf != NULL) && (d < depth)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    vf = vf->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    d++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  return vf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
// utilities: JNI objects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
jclass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
JvmtiEnvBase::get_jni_class_non_null(klassOop k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  assert(k != NULL, "k != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  return (jclass)jni_reference(Klass::cast(k)->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
// Field Information
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
JvmtiEnvBase::get_field_descriptor(klassOop k, jfieldID field, fieldDescriptor* fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  if (!jfieldIDWorkaround::is_valid_jfieldID(k, field)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  if (jfieldIDWorkaround::is_static_jfieldID(field)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    int offset = id->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
    klassOop holder = id->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    found = instanceKlass::cast(holder)->find_local_field_from_offset(offset, true, fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
    // Non-static field. The fieldID is really the offset of the field within the object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
    int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    found = instanceKlass::cast(k)->find_field_from_offset(offset, false, fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  return found;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
// Object Monitor Information
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
// Count the number of objects for a lightweight monitor. The hobj
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
// parameter is object that owns the monitor so this routine will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
// count the number of times the same object was locked by frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
// in java_thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
jint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  jint ret = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  if (!java_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    return ret;  // no Java frames so no monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  RegisterMap  reg_map(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
                                                 jvf = jvf->java_sender()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    GrowableArray<MonitorInfo*>* mons = jvf->monitors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    if (!mons->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      for (int i = 0; i < mons->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        MonitorInfo *mi = mons->at(i);
3171
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 2137
diff changeset
   609
        if (mi->owner_is_scalar_replaced()) continue;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
        // see if owner of the monitor is our object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
        if (mi->owner() != NULL && mi->owner() == hobj()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
          ret++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThread *java_thread, jobject *monitor_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  assert((SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
         "at safepoint or target thread is suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  oop obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  ObjectMonitor *mon = java_thread->current_waiting_monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  if (mon == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    // thread is not doing an Object.wait() call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    mon = java_thread->current_pending_monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    if (mon != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
      // The thread is trying to enter() or raw_enter() an ObjectMonitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
      obj = (oop)mon->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      // If obj == NULL, then ObjectMonitor is raw which doesn't count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
      // as contended for this API
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    // implied else: no contended ObjectMonitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
    // thread is doing an Object.wait() call
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    obj = (oop)mon->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
    assert(obj != NULL, "Object.wait() should have an object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  if (obj == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    *monitor_ptr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    Handle     hobj(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    *monitor_ptr = jni_reference(calling_thread, hobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
JvmtiEnvBase::get_owned_monitors(JavaThread *calling_thread, JavaThread* java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
                                 GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  jvmtiError err = JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  assert((SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
         "at safepoint or target thread is suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  if (java_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
    HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
    RegisterMap  reg_map(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
    int depth = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    for (javaVFrame *jvf = java_thread->last_java_vframe(&reg_map); jvf != NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
         jvf = jvf->java_sender()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      if (depth++ < MaxJavaStackTraceDepth) {  // check for stack too deep
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
        // add locked objects for this frame into list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
        err = get_locked_objects_in_frame(calling_thread, java_thread, jvf, owned_monitors_list, depth-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
        if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
          return err;
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
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  // Get off stack monitors. (e.g. acquired via jni MonitorEnter).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  JvmtiMonitorClosure jmc(java_thread, calling_thread, owned_monitors_list, this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  ObjectSynchronizer::monitors_iterate(&jmc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  err = jmc.error();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
// Save JNI local handles for any objects that this frame owns.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread* java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
                                 javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, int stack_depth) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  jvmtiError err = JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  GrowableArray<MonitorInfo*>* mons = jvf->monitors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  if (mons->is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
    return err;  // this javaVFrame holds no monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  oop wait_obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
    // save object of current wait() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    ObjectMonitor *mon = java_thread->current_waiting_monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    if (mon != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
      wait_obj = (oop)mon->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  oop pending_obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
    // save object of current enter() call (if any) for later comparison
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
    ObjectMonitor *mon = java_thread->current_pending_monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
    if (mon != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
      pending_obj = (oop)mon->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  for (int i = 0; i < mons->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
    MonitorInfo *mi = mons->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
3171
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 2137
diff changeset
   730
    if (mi->owner_is_scalar_replaced()) continue;
aa289b22b577 6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents: 2137
diff changeset
   731
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
    oop obj = mi->owner();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
    if (obj == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
      // this monitor doesn't have an owning object so skip it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    if (wait_obj == obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
      // the thread is waiting on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
    if (pending_obj == obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
      // the thread is pending on this monitor so it isn't really owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
    if (owned_monitors_list->length() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
      // Our list has at least one object on it so we have to check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
      // for recursive object locking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
      bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
      for (int j = 0; j < owned_monitors_list->length(); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
        jobject jobj = ((jvmtiMonitorStackDepthInfo*)owned_monitors_list->at(j))->monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
        oop check = JNIHandles::resolve(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
        if (check == obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
          found = true;  // we found the object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
      if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
        // already have this object so don't include it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
        continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
    // add the owning object to our list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
    jvmtiMonitorStackDepthInfo *jmsdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    err = allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
        return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    Handle hobj(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    jmsdi->monitor = jni_reference(calling_thread, hobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    jmsdi->stack_depth = stack_depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    owned_monitors_list->append(jmsdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
JvmtiEnvBase::get_stack_trace(JavaThread *java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
                              jint start_depth, jint max_count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
                              jvmtiFrameInfo* frame_buffer, jint* count_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  assert((SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
         "at safepoint or target thread is suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
  int count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  if (java_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    RegisterMap reg_map(java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    Thread* current_thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    ResourceMark rm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    javaVFrame *jvf = java_thread->last_java_vframe(&reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    HandleMark hm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
    if (start_depth != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
      if (start_depth > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
        for (int j = 0; j < start_depth && jvf != NULL; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
          jvf = jvf->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
        if (jvf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
          // start_depth is deeper than the stack depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
          return JVMTI_ERROR_ILLEGAL_ARGUMENT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
      } else { // start_depth < 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
        // we are referencing the starting depth based on the oldest
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
        // part of the stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
        // optimize to limit the number of times that java_sender() is called
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
        javaVFrame *jvf_cursor = jvf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
        javaVFrame *jvf_prev = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
        javaVFrame *jvf_prev_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
        int j = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
        while (jvf_cursor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
          jvf_prev_prev = jvf_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
          jvf_prev = jvf_cursor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
          for (j = 0; j > start_depth && jvf_cursor != NULL; j--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
            jvf_cursor = jvf_cursor->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
        if (j == start_depth) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
          // previous pointer is exactly where we want to start
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
          jvf = jvf_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
          // we need to back up further to get to the right place
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
          if (jvf_prev_prev == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
            // the -start_depth is greater than the stack depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
            return JVMTI_ERROR_ILLEGAL_ARGUMENT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
          // j now is the number of frames on the stack starting with
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
          // jvf_prev, we start from jvf_prev_prev and move older on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
          // the stack that many, the result is -start_depth frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
          // remaining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
          jvf = jvf_prev_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
          for (; j < 0; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
            jvf = jvf->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    for (; count < max_count && jvf != NULL; count++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
      frame_buffer[count].method = jvf->method()->jmethod_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
      frame_buffer[count].location = (jvf->method()->is_native() ? -1 : jvf->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
      jvf = jvf->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    if (start_depth != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
      // no frames and there is a starting depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
      return JVMTI_ERROR_ILLEGAL_ARGUMENT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
  *count_ptr = count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
JvmtiEnvBase::get_frame_count(JvmtiThreadState *state, jint *count_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
  assert((state != NULL),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
         "JavaThread should create JvmtiThreadState before calling this method");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  *count_ptr = state->count_frames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
JvmtiEnvBase::get_frame_location(JavaThread *java_thread, jint depth,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
                                 jmethodID* method_ptr, jlocation* location_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  assert((SafepointSynchronize::is_at_safepoint() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
          is_thread_fully_suspended(java_thread, false, &debug_bits)),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
         "at safepoint or target thread is suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  Thread* current_thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  ResourceMark rm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  vframe *vf = vframeFor(java_thread, depth);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  if (vf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
    return JVMTI_ERROR_NO_MORE_FRAMES;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  // vframeFor should return a java frame. If it doesn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  // it means we've got an internal error and we return the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  // error in product mode. In debug mode we will instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  // attempt to cast the vframe to a javaVFrame and will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  // cause an assertion/crash to allow further diagnosis.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
#ifdef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  if (!vf->is_java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
    return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  HandleMark hm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  javaVFrame *jvf = javaVFrame::cast(vf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  methodOop method = jvf->method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  if (method->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    *location_ptr = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
    *location_ptr = jvf->bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  *method_ptr = method->jmethod_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject object, jvmtiMonitorUsage* info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  Handle hobj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
  bool at_safepoint = SafepointSynchronize::is_at_safepoint();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  // Check arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
    oop mirror = JNIHandles::resolve_external_guard(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    NULL_CHECK(info_ptr, JVMTI_ERROR_NULL_POINTER);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    hobj = Handle(mirror);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  JavaThread *owning_thread = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  ObjectMonitor *mon = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  jvmtiMonitorUsage ret = {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
      NULL, 0, 0, NULL, 0, NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  // first derive the object's owner and entry_count (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    // Revoke any biases before querying the mark word
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    if (SafepointSynchronize::is_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
      BiasedLocking::revoke_at_safepoint(hobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
      BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    address owner = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
      markOop mark = hobj()->mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      if (!mark->has_monitor()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
        // this object has a lightweight monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
        if (mark->has_locker()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
          owner = (address)mark->locker(); // save the address of the Lock word
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
        // implied else: no owner
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
        // this object has a heavyweight monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
        mon = mark->monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
        // The owner field of a heavyweight monitor may be NULL for no
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
        // owner, a JavaThread * or it may still be the address of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
        // Lock word in a JavaThread's stack. A monitor can be inflated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
        // by a non-owning JavaThread, but only the owning JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
        // can change the owner field from the Lock word to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
        // JavaThread * and it may not have done that yet.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
        owner = (address)mon->owner();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
    if (owner != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
      // This monitor is owned so we have to find the owning JavaThread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      // Since owning_thread_from_monitor_owner() grabs a lock, GC can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      // move our object at this point. However, our owner value is safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      // since it is either the Lock word on a stack or a JavaThread *.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
      owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
      assert(owning_thread != NULL, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
      if (owning_thread != NULL) {  // robustness
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
        // The monitor's owner either has to be the current thread, at safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        // or it has to be suspended. Any of these conditions will prevent both
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
        // contending and waiting threads from modifying the state of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
        // the monitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
        if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
          return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
        HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
        Handle     th(owning_thread->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
        ret.owner = (jthread)jni_reference(calling_thread, th);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
      // implied else: no owner
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
    if (owning_thread != NULL) {  // monitor is owned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
      if ((address)owning_thread == owner) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
        // the owner field is the JavaThread *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
        assert(mon != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
          "must have heavyweight monitor with JavaThread * owner");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
        ret.entry_count = mon->recursions() + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
        // The owner field is the Lock word on the JavaThread's stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
        // so the recursions field is not valid. We have to count the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
        // number of recursive monitor entries the hard way. We pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
        // a handle to survive any GCs along the way.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
        ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
        ret.entry_count = count_locked_objects(owning_thread, hobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
    // implied else: entry_count == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  int nWant,nWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  if (mon != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
    // this object has a heavyweight monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    nWant = mon->contentions(); // # of threads contending for monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
    nWait = mon->waiters();     // # of threads in Object.wait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
    ret.waiter_count = nWant + nWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
    ret.notify_waiter_count = nWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    // this object has a lightweight monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    ret.waiter_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
    ret.notify_waiter_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  // Allocate memory for heavyweight and lightweight monitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  jvmtiError err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  err = allocate(ret.waiter_count * sizeof(jthread *), (unsigned char**)&ret.waiters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  err = allocate(ret.notify_waiter_count * sizeof(jthread *),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
                 (unsigned char**)&ret.notify_waiters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
    deallocate((unsigned char*)ret.waiters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  // now derive the rest of the fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  if (mon != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    // this object has a heavyweight monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    // Number of waiters may actually be less than the waiter count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    // So NULL out memory so that unused memory will be NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
    memset(ret.waiters, 0, ret.waiter_count * sizeof(jthread *));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    memset(ret.notify_waiters, 0, ret.notify_waiter_count * sizeof(jthread *));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
    if (ret.waiter_count > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
      // we have contending and/or waiting threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
      HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
      if (nWant > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
        // we have contending threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
        ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
        // get_pending_threads returns only java thread so we do not need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
        // check for  non java threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
        GrowableArray<JavaThread*>* wantList = Threads::get_pending_threads(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
          nWant, (address)mon, !at_safepoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
        if (wantList->length() < nWant) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
          // robustness: the pending list has gotten smaller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
          nWant = wantList->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
        for (int i = 0; i < nWant; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
          JavaThread *pending_thread = wantList->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
          // If the monitor has no owner, then a non-suspended contending
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
          // thread could potentially change the state of the monitor by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
          // entering it. The JVM/TI spec doesn't allow this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
          if (owning_thread == NULL && !at_safepoint &
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
              !JvmtiEnv::is_thread_fully_suspended(pending_thread, true, &debug_bits)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
            if (ret.owner != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
              destroy_jni_reference(calling_thread, ret.owner);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
            for (int j = 0; j < i; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
              destroy_jni_reference(calling_thread, ret.waiters[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
            deallocate((unsigned char*)ret.waiters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
            deallocate((unsigned char*)ret.notify_waiters);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
            return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
          Handle th(pending_thread->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
          ret.waiters[i] = (jthread)jni_reference(calling_thread, th);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
      if (nWait > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
        // we have threads in Object.wait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
        int offset = nWant;  // add after any contending threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
        ObjectWaiter *waiter = mon->first_waiter();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
        for (int i = 0, j = 0; i < nWait; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
          if (waiter == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
            // robustness: the waiting list has gotten smaller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
            nWait = j;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
          Thread *t = mon->thread_of_waiter(waiter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
          if (t != NULL && t->is_Java_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
            JavaThread *wjava_thread = (JavaThread *)t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
            // If the thread was found on the ObjectWaiter list, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
            // it has not been notified. This thread can't change the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
            // state of the monitor so it doesn't need to be suspended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
            Handle th(wjava_thread->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
            ret.waiters[offset + j] = (jthread)jni_reference(calling_thread, th);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
            ret.notify_waiters[j++] = (jthread)jni_reference(calling_thread, th);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
          waiter = mon->next_waiter(waiter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    // Adjust count. nWant and nWait count values may be less than original.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    ret.waiter_count = nWant + nWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
    ret.notify_waiter_count = nWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
    // this object has a lightweight monitor and we have nothing more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
    // to do here because the defaults are just fine.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  // we don't update return parameter unless everything worked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
  *info_ptr = ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
ResourceTracker::ResourceTracker(JvmtiEnv* env) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  _env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
  _allocations = new (ResourceObj::C_HEAP) GrowableArray<unsigned char*>(20, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
  _failed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
ResourceTracker::~ResourceTracker() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  if (_failed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
    for (int i=0; i<_allocations->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
      _env->deallocate(_allocations->at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
  delete _allocations;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
jvmtiError ResourceTracker::allocate(jlong size, unsigned char** mem_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
  unsigned char *ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  jvmtiError err = _env->allocate(size, &ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  if (err == JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
    _allocations->append(ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
    *mem_ptr = ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
    *mem_ptr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
    _failed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
 }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
unsigned char* ResourceTracker::allocate(jlong size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  unsigned char* ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
  allocate(size, &ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  return ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
char* ResourceTracker::strdup(const char* str) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
  char *dup_str = (char*)allocate(strlen(str)+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
  if (dup_str != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
    strcpy(dup_str, str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  return dup_str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
struct StackInfoNode {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  struct StackInfoNode *next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
  jvmtiStackInfo info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
// Create a jvmtiStackInfo inside a linked list node and create a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
// buffer for the frame information, both allocated as resource objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
// Fill in both the jvmtiStackInfo and the jvmtiFrameInfo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
// Note that either or both of thr and thread_oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
// may be null if the thread is new or has exited.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
VM_GetMultipleStackTraces::fill_frames(jthread jt, JavaThread *thr, oop thread_oop) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  jint state = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  struct StackInfoNode *node = NEW_RESOURCE_OBJ(struct StackInfoNode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  jvmtiStackInfo *infop = &(node->info);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  node->next = head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
  set_head(node);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  infop->frame_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  infop->thread = jt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  if (thread_oop != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
    // get most state bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    state = (jint)java_lang_Thread::get_thread_status(thread_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  if (thr != NULL) {    // add more state bits if there is a JavaThead to query
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    // same as is_being_ext_suspended() but without locking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    if (thr->is_ext_suspended() || thr->is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
      state |= JVMTI_THREAD_STATE_SUSPENDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    JavaThreadState jts = thr->thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
    if (jts == _thread_in_native) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
      state |= JVMTI_THREAD_STATE_IN_NATIVE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    OSThread* osThread = thr->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    if (osThread != NULL && osThread->interrupted()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
      state |= JVMTI_THREAD_STATE_INTERRUPTED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
  infop->state = state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
  if (thr != NULL || (state & JVMTI_THREAD_STATE_ALIVE) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
    infop->frame_buffer = NEW_RESOURCE_ARRAY(jvmtiFrameInfo, max_frame_count());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    env()->get_stack_trace(thr, 0, max_frame_count(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
                           infop->frame_buffer, &(infop->frame_count));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    infop->frame_buffer = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
    infop->frame_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
  _frame_count_total += infop->frame_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
// Based on the stack information in the linked list, allocate memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
// block to return and fill it from the info in the linked list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
VM_GetMultipleStackTraces::allocate_and_fill_stacks(jint thread_count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
  // do I need to worry about alignment issues?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
  jlong alloc_size =  thread_count       * sizeof(jvmtiStackInfo)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
                    + _frame_count_total * sizeof(jvmtiFrameInfo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
  env()->allocate(alloc_size, (unsigned char **)&_stack_info);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
  // pointers to move through the newly allocated space as it is filled in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
  jvmtiStackInfo *si = _stack_info + thread_count;      // bottom of stack info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
  jvmtiFrameInfo *fi = (jvmtiFrameInfo *)si;            // is the top of frame info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
  // copy information in resource area into allocated buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
  // insert stack info backwards since linked list is backwards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  // insert frame info forwards
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
  // walk the StackInfoNodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
  for (struct StackInfoNode *sin = head(); sin != NULL; sin = sin->next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
    jint frame_count = sin->info.frame_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
    size_t frames_size = frame_count * sizeof(jvmtiFrameInfo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
    --si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
    memcpy(si, &(sin->info), sizeof(jvmtiStackInfo));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
    if (frames_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
      si->frame_buffer = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      memcpy(fi, sin->info.frame_buffer, frames_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      si->frame_buffer = fi;  // point to the new allocated copy of the frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
      fi += frame_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
  assert(si == _stack_info, "the last copied stack info must be the first record");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  assert((unsigned char *)fi == ((unsigned char *)_stack_info) + alloc_size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
         "the last copied frame info must be the last record");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
VM_GetThreadListStackTraces::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  for (int i = 0; i < _thread_count; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
    jthread jt = _thread_list[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
    oop thread_oop = JNIHandles::resolve_external_guard(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
    if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::thread_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
      set_result(JVMTI_ERROR_INVALID_THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
    fill_frames(jt, java_lang_Thread::thread(thread_oop), thread_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  allocate_and_fill_stacks(_thread_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
VM_GetAllStackTraces::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  _final_thread_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  for (JavaThread *jt = Threads::first(); jt != NULL; jt = jt->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    oop thread_oop = jt->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
    if (thread_oop != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
        !jt->is_exiting() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
        java_lang_Thread::is_alive(thread_oop) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
        !jt->is_hidden_from_external_view()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
      ++_final_thread_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
      // Handle block of the calling thread is used to create local refs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
      fill_frames((jthread)JNIHandles::make_local(_calling_thread, thread_oop),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
                  jt, thread_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  allocate_and_fill_stacks(_final_thread_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
// Verifies that the top frame is a java frame in an expected state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
// Deoptimizes frame if needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
// Checks that the frame method signature matches the return type (tos).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
// HandleMark must be defined in the caller only.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
// It is to keep a ret_ob_h handle alive after return to the caller.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
JvmtiEnvBase::check_top_frame(JavaThread* current_thread, JavaThread* java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
                              jvalue value, TosState tos, Handle* ret_ob_h) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  ResourceMark rm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  vframe *vf = vframeFor(java_thread, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  NULL_CHECK(vf, JVMTI_ERROR_NO_MORE_FRAMES);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  javaVFrame *jvf = (javaVFrame*) vf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  if (!vf->is_java_frame() || jvf->method()->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    return JVMTI_ERROR_OPAQUE_FRAME;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  // If the frame is a compiled one, need to deoptimize it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  if (vf->is_compiled_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    if (!vf->fr().can_be_deoptimized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
      return JVMTI_ERROR_OPAQUE_FRAME;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    VM_DeoptimizeFrame deopt(java_thread, jvf->fr().id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
    VMThread::execute(&deopt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
  // Get information about method return type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
  symbolHandle signature(current_thread, jvf->method()->signature());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  ResultTypeFinder rtf(signature);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  TosState fr_tos = as_TosState(rtf.type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  if (fr_tos != tos) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
    if (tos != itos || (fr_tos != btos && fr_tos != ctos && fr_tos != stos)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
      return JVMTI_ERROR_TYPE_MISMATCH;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
  // Check that the jobject class matches the return type signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  jobject jobj = value.l;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  if (tos == atos && jobj != NULL) { // NULL reference is allowed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
    Handle ob_h = Handle(current_thread, JNIHandles::resolve_external_guard(jobj));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
    NULL_CHECK(ob_h, JVMTI_ERROR_INVALID_OBJECT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
    KlassHandle ob_kh = KlassHandle(current_thread, ob_h()->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
    NULL_CHECK(ob_kh, JVMTI_ERROR_INVALID_OBJECT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
    // Method return type signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
    char* ty_sign = 1 + strchr(signature->as_C_string(), ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
    if (!VM_GetOrSetLocal::is_assignable(ty_sign, Klass::cast(ob_kh()), current_thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
      return JVMTI_ERROR_TYPE_MISMATCH;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
    *ret_ob_h = ob_h;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
} /* end check_top_frame */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
// ForceEarlyReturn<type> follows the PopFrame approach in many aspects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
// Main difference is on the last stage in the interpreter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
// The PopFrame stops method execution to continue execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
// from the same method call instruction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
// The ForceEarlyReturn forces return from method so the execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
// continues at the bytecode following the method call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
// Threads_lock NOT held, java_thread not protected by lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
// java_thread - pre-checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
jvmtiError
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState tos) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
  JavaThread* current_thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  HandleMark   hm(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1357
  // retrieve or create the state
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1358
  JvmtiThreadState* state = JvmtiThreadState::state_for(java_thread);
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1359
  if (state == NULL) {
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1360
    return JVMTI_ERROR_THREAD_NOT_ALIVE;
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1361
  }
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1623
diff changeset
  1362
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  // Check if java_thread is fully suspended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  if (!is_thread_fully_suspended(java_thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
                                 true /* wait for suspend completion */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
                                 &debug_bits)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
    return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
  // Check to see if a ForceEarlyReturn was already in progress
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  if (state->is_earlyret_pending()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
    // Probably possible for JVMTI clients to trigger this, but the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
    // JPDA backend shouldn't allow this to happen
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
    return JVMTI_ERROR_INTERNAL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
    // The same as for PopFrame. Workaround bug:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
    //  4812902: popFrame hangs if the method is waiting at a synchronize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
    // Catch this condition and return an error to avoid hanging.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
    // Now JVMTI spec allows an implementation to bail out with an opaque
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
    // frame error.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
    OSThread* osThread = java_thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
    if (osThread->get_state() == MONITOR_WAIT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
      return JVMTI_ERROR_OPAQUE_FRAME;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
  Handle ret_ob_h = Handle();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
  jvmtiError err = check_top_frame(current_thread, java_thread, value, tos, &ret_ob_h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
    return err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  assert(tos != atos || value.l == NULL || ret_ob_h() != NULL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
         "return object oop must not be NULL if jobject is not NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  // Update the thread state to reflect that the top frame must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  // forced to return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
  // The current frame will be returned later when the suspended
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  // thread is resumed and right before returning from VM to Java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
  // (see call_VM_base() in assembler_<cpu>.cpp).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  state->set_earlyret_pending();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
  state->set_earlyret_oop(ret_ob_h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
  state->set_earlyret_value(value, tos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  // Set pending step flag for this early return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  // It is cleared when next step event is posted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  state->set_pending_step_for_earlyret();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
} /* end force_early_return */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
  if ( _error != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
    // Error occurred in previous iteration so no need to add
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
    // to the list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  if (mon->owner() == _java_thread ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
    // Filter out on stack monitors collected during stack walk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
    oop obj = (oop)mon->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
    bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
    for (int j = 0; j < _owned_monitors_list->length(); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
      jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      oop check = JNIHandles::resolve(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
      if (check == obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
        // On stack monitor already collected during the stack walk.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
        found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
    if (found == false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
      // This is off stack monitor (e.g. acquired via jni MonitorEnter).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
      jvmtiError err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
      jvmtiMonitorStackDepthInfo *jmsdi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
      err = _env->allocate(sizeof(jvmtiMonitorStackDepthInfo), (unsigned char **)&jmsdi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
      if (err != JVMTI_ERROR_NONE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
        _error = err;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
      Handle hobj(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
      jmsdi->monitor = _env->jni_reference(_calling_thread, hobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
      // stack depth is unknown for this monitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
      jmsdi->stack_depth = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
      _owned_monitors_list->append(jmsdi);
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
#endif // !JVMTI_KERNEL