hotspot/src/share/vm/prims/jvmtiImpl.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 2137 b03f1da1a3d3
child 5547 f4b087cbb361
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
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_jvmtiImpl.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
void JvmtiPendingMonitors::transition_raw_monitors() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
  assert((Threads::number_of_threads()==1),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
         "Java thread has not created yet or more than one java thread \
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
is running. Raw monitor transition will not work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  JavaThread *current_java_thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
    ThreadBlockInVM __tbivm(current_java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
    for(int i=0; i< count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
      JvmtiRawMonitor *rmonitor = monitors()->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
      int r = rmonitor->raw_enter(current_java_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  // pending monitors are converted to real monitor so delete them all.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  dispose();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// class JvmtiAgentThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// JavaThread used to wrap a thread started by an agent
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// using the JVMTI method RunAgentThread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    : JavaThread(start_function_wrapper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
    _env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    _start_fn = start_fn;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    _start_arg = start_arg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
    // It is expected that any Agent threads will be created as
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
    // Java Threads.  If this is the case, notification of the creation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
    // of the thread is given in JavaThread::thread_main().
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    assert(thread == JavaThread::current(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
    JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    dthread->call_start_function();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
JvmtiAgentThread::call_start_function() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    ThreadToNativeFromVM transition(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
// class GrowableCache - private methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
void GrowableCache::recache() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  int len = _elements->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  FREE_C_HEAP_ARRAY(address, _cache);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  _cache = NEW_C_HEAP_ARRAY(address,len+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  for (int i=0; i<len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    _cache[i] = _elements->at(i)->getCacheValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    // The cache entry has gone bad. Without a valid frame pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    // value, the entry is useless so we simply delete it in product
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    // mode. The call to remove() will rebuild the cache again
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    // without the bad entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    if (_cache[i] == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
      assert(false, "cannot recache NULL elements");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      remove(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  _cache[len] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  _listener_fun(_this_obj,_cache);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
bool GrowableCache::equals(void* v, GrowableElement *e2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  GrowableElement *e1 = (GrowableElement *) v;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  assert(e1 != NULL, "e1 != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  assert(e2 != NULL, "e2 != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  return e1->equals(e2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
// class GrowableCache - public methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
GrowableCache::GrowableCache() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  _this_obj       = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  _listener_fun   = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  _elements       = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  _cache          = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
GrowableCache::~GrowableCache() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  delete _elements;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  FREE_C_HEAP_ARRAY(address, _cache);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  _this_obj       = this_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  _listener_fun   = listener_fun;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  _elements       = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  recache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
// number of elements in the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
int GrowableCache::length() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  return _elements->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
// get the value of the index element in the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
GrowableElement* GrowableCache::at(int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  GrowableElement *e = (GrowableElement *) _elements->at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  assert(e != NULL, "e != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  return e;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
int GrowableCache::find(GrowableElement* e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  return _elements->find(e, GrowableCache::equals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
// append a copy of the element to the end of the collection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
void GrowableCache::append(GrowableElement* e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  GrowableElement *new_e = e->clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  _elements->append(new_e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  recache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
// insert a copy of the element using lessthan()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
void GrowableCache::insert(GrowableElement* e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  GrowableElement *new_e = e->clone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  _elements->append(new_e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  int n = length()-2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  for (int i=n; i>=0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    GrowableElement *e1 = _elements->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    GrowableElement *e2 = _elements->at(i+1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    if (e2->lessThan(e1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      _elements->at_put(i+1, e1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
      _elements->at_put(i,   e2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  recache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// remove the element at index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
void GrowableCache::remove (int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  GrowableElement *e = _elements->at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  assert(e != NULL, "e != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  _elements->remove(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  delete e;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  recache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
// clear out all elements, release all heap space and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
// let our listener know that things have changed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
void GrowableCache::clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  int len = _elements->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  for (int i=0; i<len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    delete _elements->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  _elements->clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  recache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
void GrowableCache::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  int len = _elements->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  for (int i=0; i<len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
    GrowableElement *e = _elements->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    e->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
void GrowableCache::gc_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  int len = _elements->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  // recompute the new cache value after GC
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  for (int i=0; i<len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    _cache[i] = _elements->at(i)->getCacheValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
// class JvmtiRawMonitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  _name = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  _magic = JVMTI_RM_MAGIC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
JvmtiRawMonitor::~JvmtiRawMonitor() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  FreeHeap(_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  _magic = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
2137
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   241
bool
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   242
JvmtiRawMonitor::is_valid() {
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   243
  int value = 0;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   244
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   245
  // This object might not be a JvmtiRawMonitor so we can't assume
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   246
  // 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: 1
diff changeset
   247
  // way and then check against JVMTI_RM_MAGIC.
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   248
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   249
  switch (sizeof(_magic)) {
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   250
  case 2:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   251
    value = Bytes::get_native_u2((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   252
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   253
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   254
  case 4:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   255
    value = Bytes::get_native_u4((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   256
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   257
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   258
  case 8:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   259
    value = Bytes::get_native_u8((address)&_magic);
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   260
    break;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   261
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   262
  default:
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   263
    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: 1
diff changeset
   264
  }
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   265
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   266
  return value == JVMTI_RM_MAGIC;
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   267
}
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   268
b03f1da1a3d3 6567360: 3/4 SIGBUS in jvmti RawMonitor magic check for unaligned bad monitor pointer
dcubed
parents: 1
diff changeset
   269
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
// class JvmtiBreakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
JvmtiBreakpoint::JvmtiBreakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  _method = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  _bci    = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
#ifdef CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // This one is always allocated with new, but check it just in case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  if (thread->is_in_stack((address)&_method)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    thread->allow_unhandled_oop((oop*)&_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
#endif // CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  _method        = m_method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  assert(_method != NULL, "_method != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  _bci           = (int) location;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
#ifdef CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  // Could be allocated with new and wouldn't be on the unhandled oop list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  if (thread->is_in_stack((address)&_method)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    thread->allow_unhandled_oop(&_method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
#endif // CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  assert(_bci >= 0, "_bci >= 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  _method   = bp._method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  _bci      = bp._bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  Unimplemented();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  return _method   == bp._method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    &&   _bci      == bp._bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
bool JvmtiBreakpoint::is_valid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  return _method != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
         _bci >= 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
address JvmtiBreakpoint::getBcp() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  return _method->bcp_from(_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  ((methodOopDesc*)_method->*meth_act)(_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  // add/remove breakpoint to/from versions of the method that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  // are EMCP. Directly or transitively obsolete methods are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  // not saved in the PreviousVersionInfo.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  symbolOop m_name = _method->name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  symbolOop m_signature = _method->signature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    ResourceMark rm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    // PreviousVersionInfo objects returned via PreviousVersionWalker
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    // contain a GrowableArray of handles. We have to clean up the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
    // GrowableArray _after_ the PreviousVersionWalker destructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    // has destroyed the handles.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      // search previous versions if they exist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
      for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
           pv_info != NULL; pv_info = pvw.next_previous_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
        GrowableArray<methodHandle>* methods =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
          pv_info->prev_EMCP_method_handles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
        if (methods == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
          // We have run into a PreviousVersion generation where
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
          // all methods were made obsolete during that generation's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
          // RedefineClasses() operation. At the time of that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
          // operation, all EMCP methods were flushed so we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
          // have to go back any further.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
          //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
          // A NULL methods array is different than an empty methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
          // array. We cannot infer any optimizations about older
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
          // generations from an empty methods array for the current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
          // generation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
        for (int i = methods->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
          methodHandle method = methods->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
          if (method->name() == m_name && method->signature() == m_signature) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
            RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
              meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
              method->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
              method->signature()->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
            assert(!method->is_obsolete(), "only EMCP methods here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
            ((methodOopDesc*)method()->*meth_act)(_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
    } // pvw is cleaned up
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  } // rm is cleaned up
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
void JvmtiBreakpoint::set() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  each_method_version_do(&methodOopDesc::set_breakpoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
void JvmtiBreakpoint::clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  each_method_version_do(&methodOopDesc::clear_breakpoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
void JvmtiBreakpoint::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  const char *class_name  = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
// class VM_ChangeBreakpoints
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
// Modify the Breakpoints data structure at a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
void VM_ChangeBreakpoints::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  switch (_operation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  case SET_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    _breakpoints->set_at_safepoint(*_bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  case CLEAR_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    _breakpoints->clear_at_safepoint(*_bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  case CLEAR_ALL_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    _breakpoints->clearall_at_safepoint();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    assert(false, "Unknown operation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  // This operation keeps breakpoints alive
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  if (_breakpoints != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    _breakpoints->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  if (_bp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
    _bp->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
// class JvmtiBreakpoints
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
// a JVMTI internal collection of JvmtiBreakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  _bps.initialize(this,listener_fun);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
void  JvmtiBreakpoints::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  _bps.oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
void  JvmtiBreakpoints::gc_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  _bps.gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
void  JvmtiBreakpoints::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  int n = _bps.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  for (int i=0; i<n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    JvmtiBreakpoint& bp = _bps.at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    tty->print("%d: ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    bp.print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  int i = _bps.find(bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  if (i == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
    _bps.append(bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    bp.set();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  int i = _bps.find(bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  if (i != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
    _bps.remove(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
    bp.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
void JvmtiBreakpoints::clearall_at_safepoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  int len = _bps.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  for (int i=0; i<len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    _bps.at(i).clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  _bps.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
int JvmtiBreakpoints::length() { return _bps.length(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  if ( _bps.find(bp) != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
     return JVMTI_ERROR_DUPLICATE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  VMThread::execute(&set_breakpoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  if ( _bps.find(bp) == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
     return JVMTI_ERROR_NOT_FOUND;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  VMThread::execute(&clear_breakpoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  return JVMTI_ERROR_NONE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  bool changed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // We are going to run thru the list of bkpts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // and delete some.  This deletion probably alters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  // the list in some implementation defined way such
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // that when we delete entry i, the next entry might
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // no longer be at i+1.  To be safe, each time we delete
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  // an entry, we'll just start again from the beginning.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  // We'll stop when we make a pass thru the whole list without
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  // deleting anything.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  while (changed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
    int len = _bps.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    changed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
    for (int i = 0; i < len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
      JvmtiBreakpoint& bp = _bps.at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
      if (bp.method()->method_holder() == klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
        bp.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
        _bps.remove(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
        // This changed 'i' so we have to start over.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
        changed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
void JvmtiBreakpoints::clearall() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  VMThread::execute(&clearall_breakpoint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
// class JvmtiCurrentBreakpoints
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
address *         JvmtiCurrentBreakpoints::_breakpoint_list    = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
  if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  return (*_jvmti_breakpoints);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
void  JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  assert(this_jvmti != NULL, "this_jvmti != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  debug_only(int n = this_jvmti->length(););
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  assert(cache[n] == NULL, "cache must be NULL terminated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  set_breakpoint_list(cache);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  if (_jvmti_breakpoints != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
    _jvmti_breakpoints->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
void JvmtiCurrentBreakpoints::gc_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  if (_jvmti_breakpoints != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    _jvmti_breakpoints->gc_epilogue();
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
// class VM_GetOrSetLocal
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
// Constructor for non-object getter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  : _thread(thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  , _calling_thread(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  , _depth(depth)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
  , _index(index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
  , _type(type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  , _set(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
  , _jvf(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  , _result(JVMTI_ERROR_NONE)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
// Constructor for object or non-object setter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  : _thread(thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
  , _calling_thread(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  , _depth(depth)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  , _index(index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  , _type(type)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  , _value(value)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  , _set(true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  , _jvf(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  , _result(JVMTI_ERROR_NONE)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
// Constructor for object getter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  : _thread(thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
  , _calling_thread(calling_thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  , _depth(depth)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  , _index(index)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  , _type(T_OBJECT)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  , _set(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  , _jvf(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  , _result(JVMTI_ERROR_NONE)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
vframe *VM_GetOrSetLocal::get_vframe() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  if (!_thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  RegisterMap reg_map(_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  vframe *vf = _thread->last_java_vframe(&reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  int d = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  while ((vf != NULL) && (d < _depth)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    vf = vf->java_sender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    d++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
  return vf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  vframe* vf = get_vframe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
  if (vf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    _result = JVMTI_ERROR_NO_MORE_FRAMES;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  javaVFrame *jvf = (javaVFrame*)vf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  if (!vf->is_java_frame() || jvf->method()->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
    _result = JVMTI_ERROR_OPAQUE_FRAME;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  return jvf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
// Check that the klass is assignable to a type with the given signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
// Another solution could be to use the function Klass::is_subtype_of(type).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// But the type class can be forced to load/initialize eagerly in such a case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// This may cause unexpected consequences like CFLH or class-init JVMTI events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
// It is better to avoid such a behavior.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  assert(ty_sign != NULL, "type signature must not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
  assert(thread != NULL, "thread must not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  assert(klass != NULL, "klass must not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  int len = (int) strlen(ty_sign);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    ty_sign++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
    len -= 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  if (klass->name() == ty_sym()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  // Compare primary supers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
  int super_depth = klass->super_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  int idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  for (idx = 0; idx < super_depth; idx++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
    if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  // Compare secondary supers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  objArrayOop sec_supers = klass->secondary_supers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  for (idx = 0; idx < sec_supers->length(); idx++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
    if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
// Checks error conditions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
//   JVMTI_ERROR_INVALID_SLOT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
//   JVMTI_ERROR_TYPE_MISMATCH
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
// Returns: 'true' - everything is Ok, 'false' - error code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  methodOop method_oop = jvf->method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  if (!method_oop->has_localvariable_table()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    // Just to check index boundaries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
    jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
      _result = JVMTI_ERROR_INVALID_SLOT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
  jint num_entries = method_oop->localvariable_table_length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  if (num_entries == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
    _result = JVMTI_ERROR_INVALID_SLOT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
    return false;       // There are no slots
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  int signature_idx = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  int vf_bci = jvf->bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  LocalVariableTableElement* table = method_oop->localvariable_table_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  for (int i = 0; i < num_entries; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    int start_bci = table[i].start_bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    int end_bci = start_bci + table[i].length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    // Here we assume that locations of LVT entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
    // with the same slot number cannot be overlapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
    if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
      signature_idx = (int) table[i].descriptor_cp_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  if (signature_idx == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    _result = JVMTI_ERROR_INVALID_SLOT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    return false;       // Incorrect slot index
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  symbolOop   sign_sym  = method_oop->constants()->symbol_at(signature_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  const char* signature = (const char *) sign_sym->as_utf8();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  BasicType slot_type = char2type(signature[0]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  switch (slot_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
    slot_type = T_INT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  case T_ARRAY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    slot_type = T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  if (_type != slot_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    _result = JVMTI_ERROR_TYPE_MISMATCH;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  jobject jobj = _value.l;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
    // Check that the jobject class matches the return type signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
    JavaThread* cur_thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
    HandleMark hm(cur_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
    Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
    NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
    KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
      _result = JVMTI_ERROR_TYPE_MISMATCH;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
static bool can_be_deoptimized(vframe* vf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
bool VM_GetOrSetLocal::doit_prologue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  _jvf = get_java_vframe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  NULL_CHECK(_jvf, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  if (!check_slot_type(_jvf)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
void VM_GetOrSetLocal::doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  if (_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    // Force deoptimization of frame if compiled because it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    // possible the compiler emitted some locals as constant values,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    // meaning they are not mutable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    if (can_be_deoptimized(_jvf)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
      // Schedule deoptimization so that eventually the local
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
      // update will be written to an interpreter frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
      VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
      VMThread::execute(&deopt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
      // Now store a new value for the local which will be applied
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
      // once deoptimization occurs. Note however that while this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
      // write is deferred until deoptimization actually happens
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
      // can vframe created after this point will have its locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
      // reflecting this update so as far as anyone can see the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
      // write has already taken place.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
      // If we are updating an oop then get the oop from the handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
      // since the handle will be long gone by the time the deopt
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
      // happens. The oop stored in the deferred local will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
      // gc'd on its own.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
      if (_type == T_OBJECT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
        _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
      // Re-read the vframe so we can see that it is deoptimized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
      // [ Only need because of assert in update_local() ]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
      _jvf = get_java_vframe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
      ((compiledVFrame*)_jvf)->update_local(_type, _index, _value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    StackValueCollection *locals = _jvf->locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    switch (_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
    case T_INT:    locals->set_int_at   (_index, _value.i); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
    case T_LONG:   locals->set_long_at  (_index, _value.j); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
    case T_OBJECT: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
      Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
      locals->set_obj_at (_index, ob_h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
    default: ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    _jvf->set_locals(locals);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    StackValueCollection *locals = _jvf->locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
    if (locals->at(_index)->type() == T_CONFLICT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
      memset(&_value, 0, sizeof(_value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
      _value.l = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    switch (_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
    case T_INT:    _value.i = locals->int_at   (_index);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    case T_LONG:   _value.j = locals->long_at  (_index);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
    case T_FLOAT:  _value.f = locals->float_at (_index);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
    case T_DOUBLE: _value.d = locals->double_at(_index);   break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
    case T_OBJECT: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
      // Wrap the oop to be returned in a local JNI handle since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
      // oops_do() no longer applies after doit() is finished.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
      oop obj = locals->obj_at(_index)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
      _value.l = JNIHandles::make_local(_calling_thread, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
    default: ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
bool VM_GetOrSetLocal::allow_nested_vm_operations() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  return true; // May need to deoptimize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
/////////////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
// class JvmtiSuspendControl - see comments in jvmtiImpl.hpp
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
  // external suspend should have caught suspending a thread twice
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // Immediate suspension required for JPDA back-end so JVMTI agent threads do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  // not deadlock due to later suspension on transitions while holding
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  // raw monitors.  Passing true causes the immediate suspension.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  // java_suspend() will catch threads in the process of exiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  // and will ignore them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  java_thread->java_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
  // It would be nice to have the following assertion in all the time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  // but it is possible for a racing resume request to have resumed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
  // this thread right after we suspended it. Temporarily enable this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  // assertion if you are chasing a different kind of bug.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
  // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  //   java_thread->is_being_ext_suspended(), "thread is not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    // check again because we can get delayed in java_suspend():
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
    // the thread is in process of exiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
bool JvmtiSuspendControl::resume(JavaThread *java_thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  // external suspend should have caught resuming a thread twice
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  assert(java_thread->is_being_ext_suspended(), "thread should be suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  // resume thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    // must always grab Threads_lock, see JVM_SuspendThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    MutexLocker ml(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
    java_thread->java_resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
void JvmtiSuspendControl::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  MutexLocker mu(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  tty->print("Suspended Threads: [");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
#if JVMTI_TRACE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
    const char *name   = JvmtiTrace::safe_get_thread_name(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
    const char *name   = "";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
#endif /*JVMTI_TRACE */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    if (!thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
      tty->print("no stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    tty->print(") ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  tty->print_cr("]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
}