src/share/vm/prims/jvmtiImpl.cpp

changeset 435
a61af66fc99e
child 1046
2f716c0acb64
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,912 @@
     1.4 +/*
     1.5 + * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +# include "incls/_precompiled.incl"
    1.29 +# include "incls/_jvmtiImpl.cpp.incl"
    1.30 +
    1.31 +GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true);
    1.32 +
    1.33 +void JvmtiPendingMonitors::transition_raw_monitors() {
    1.34 +  assert((Threads::number_of_threads()==1),
    1.35 +         "Java thread has not created yet or more than one java thread \
    1.36 +is running. Raw monitor transition will not work");
    1.37 +  JavaThread *current_java_thread = JavaThread::current();
    1.38 +  assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
    1.39 +  {
    1.40 +    ThreadBlockInVM __tbivm(current_java_thread);
    1.41 +    for(int i=0; i< count(); i++) {
    1.42 +      JvmtiRawMonitor *rmonitor = monitors()->at(i);
    1.43 +      int r = rmonitor->raw_enter(current_java_thread);
    1.44 +      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
    1.45 +    }
    1.46 +  }
    1.47 +  // pending monitors are converted to real monitor so delete them all.
    1.48 +  dispose();
    1.49 +}
    1.50 +
    1.51 +//
    1.52 +// class JvmtiAgentThread
    1.53 +//
    1.54 +// JavaThread used to wrap a thread started by an agent
    1.55 +// using the JVMTI method RunAgentThread.
    1.56 +//
    1.57 +
    1.58 +JvmtiAgentThread::JvmtiAgentThread(JvmtiEnv* env, jvmtiStartFunction start_fn, const void *start_arg)
    1.59 +    : JavaThread(start_function_wrapper) {
    1.60 +    _env = env;
    1.61 +    _start_fn = start_fn;
    1.62 +    _start_arg = start_arg;
    1.63 +}
    1.64 +
    1.65 +void
    1.66 +JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {
    1.67 +    // It is expected that any Agent threads will be created as
    1.68 +    // Java Threads.  If this is the case, notification of the creation
    1.69 +    // of the thread is given in JavaThread::thread_main().
    1.70 +    assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");
    1.71 +    assert(thread == JavaThread::current(), "sanity check");
    1.72 +
    1.73 +    JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;
    1.74 +    dthread->call_start_function();
    1.75 +}
    1.76 +
    1.77 +void
    1.78 +JvmtiAgentThread::call_start_function() {
    1.79 +    ThreadToNativeFromVM transition(this);
    1.80 +    _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg);
    1.81 +}
    1.82 +
    1.83 +
    1.84 +//
    1.85 +// class GrowableCache - private methods
    1.86 +//
    1.87 +
    1.88 +void GrowableCache::recache() {
    1.89 +  int len = _elements->length();
    1.90 +
    1.91 +  FREE_C_HEAP_ARRAY(address, _cache);
    1.92 +  _cache = NEW_C_HEAP_ARRAY(address,len+1);
    1.93 +
    1.94 +  for (int i=0; i<len; i++) {
    1.95 +    _cache[i] = _elements->at(i)->getCacheValue();
    1.96 +    //
    1.97 +    // The cache entry has gone bad. Without a valid frame pointer
    1.98 +    // value, the entry is useless so we simply delete it in product
    1.99 +    // mode. The call to remove() will rebuild the cache again
   1.100 +    // without the bad entry.
   1.101 +    //
   1.102 +    if (_cache[i] == NULL) {
   1.103 +      assert(false, "cannot recache NULL elements");
   1.104 +      remove(i);
   1.105 +      return;
   1.106 +    }
   1.107 +  }
   1.108 +  _cache[len] = NULL;
   1.109 +
   1.110 +  _listener_fun(_this_obj,_cache);
   1.111 +}
   1.112 +
   1.113 +bool GrowableCache::equals(void* v, GrowableElement *e2) {
   1.114 +  GrowableElement *e1 = (GrowableElement *) v;
   1.115 +  assert(e1 != NULL, "e1 != NULL");
   1.116 +  assert(e2 != NULL, "e2 != NULL");
   1.117 +
   1.118 +  return e1->equals(e2);
   1.119 +}
   1.120 +
   1.121 +//
   1.122 +// class GrowableCache - public methods
   1.123 +//
   1.124 +
   1.125 +GrowableCache::GrowableCache() {
   1.126 +  _this_obj       = NULL;
   1.127 +  _listener_fun   = NULL;
   1.128 +  _elements       = NULL;
   1.129 +  _cache          = NULL;
   1.130 +}
   1.131 +
   1.132 +GrowableCache::~GrowableCache() {
   1.133 +  clear();
   1.134 +  delete _elements;
   1.135 +  FREE_C_HEAP_ARRAY(address, _cache);
   1.136 +}
   1.137 +
   1.138 +void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
   1.139 +  _this_obj       = this_obj;
   1.140 +  _listener_fun   = listener_fun;
   1.141 +  _elements       = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true);
   1.142 +  recache();
   1.143 +}
   1.144 +
   1.145 +// number of elements in the collection
   1.146 +int GrowableCache::length() {
   1.147 +  return _elements->length();
   1.148 +}
   1.149 +
   1.150 +// get the value of the index element in the collection
   1.151 +GrowableElement* GrowableCache::at(int index) {
   1.152 +  GrowableElement *e = (GrowableElement *) _elements->at(index);
   1.153 +  assert(e != NULL, "e != NULL");
   1.154 +  return e;
   1.155 +}
   1.156 +
   1.157 +int GrowableCache::find(GrowableElement* e) {
   1.158 +  return _elements->find(e, GrowableCache::equals);
   1.159 +}
   1.160 +
   1.161 +// append a copy of the element to the end of the collection
   1.162 +void GrowableCache::append(GrowableElement* e) {
   1.163 +  GrowableElement *new_e = e->clone();
   1.164 +  _elements->append(new_e);
   1.165 +  recache();
   1.166 +}
   1.167 +
   1.168 +// insert a copy of the element using lessthan()
   1.169 +void GrowableCache::insert(GrowableElement* e) {
   1.170 +  GrowableElement *new_e = e->clone();
   1.171 +  _elements->append(new_e);
   1.172 +
   1.173 +  int n = length()-2;
   1.174 +  for (int i=n; i>=0; i--) {
   1.175 +    GrowableElement *e1 = _elements->at(i);
   1.176 +    GrowableElement *e2 = _elements->at(i+1);
   1.177 +    if (e2->lessThan(e1)) {
   1.178 +      _elements->at_put(i+1, e1);
   1.179 +      _elements->at_put(i,   e2);
   1.180 +    }
   1.181 +  }
   1.182 +
   1.183 +  recache();
   1.184 +}
   1.185 +
   1.186 +// remove the element at index
   1.187 +void GrowableCache::remove (int index) {
   1.188 +  GrowableElement *e = _elements->at(index);
   1.189 +  assert(e != NULL, "e != NULL");
   1.190 +  _elements->remove(e);
   1.191 +  delete e;
   1.192 +  recache();
   1.193 +}
   1.194 +
   1.195 +// clear out all elements, release all heap space and
   1.196 +// let our listener know that things have changed.
   1.197 +void GrowableCache::clear() {
   1.198 +  int len = _elements->length();
   1.199 +  for (int i=0; i<len; i++) {
   1.200 +    delete _elements->at(i);
   1.201 +  }
   1.202 +  _elements->clear();
   1.203 +  recache();
   1.204 +}
   1.205 +
   1.206 +void GrowableCache::oops_do(OopClosure* f) {
   1.207 +  int len = _elements->length();
   1.208 +  for (int i=0; i<len; i++) {
   1.209 +    GrowableElement *e = _elements->at(i);
   1.210 +    e->oops_do(f);
   1.211 +  }
   1.212 +}
   1.213 +
   1.214 +void GrowableCache::gc_epilogue() {
   1.215 +  int len = _elements->length();
   1.216 +  // recompute the new cache value after GC
   1.217 +  for (int i=0; i<len; i++) {
   1.218 +    _cache[i] = _elements->at(i)->getCacheValue();
   1.219 +  }
   1.220 +}
   1.221 +
   1.222 +
   1.223 +//
   1.224 +// class JvmtiRawMonitor
   1.225 +//
   1.226 +
   1.227 +JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
   1.228 +#ifdef ASSERT
   1.229 +  _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name);
   1.230 +#else
   1.231 +  _name = NULL;
   1.232 +#endif
   1.233 +  _magic = JVMTI_RM_MAGIC;
   1.234 +}
   1.235 +
   1.236 +JvmtiRawMonitor::~JvmtiRawMonitor() {
   1.237 +#ifdef ASSERT
   1.238 +  FreeHeap(_name);
   1.239 +#endif
   1.240 +  _magic = 0;
   1.241 +}
   1.242 +
   1.243 +
   1.244 +//
   1.245 +// class JvmtiBreakpoint
   1.246 +//
   1.247 +
   1.248 +JvmtiBreakpoint::JvmtiBreakpoint() {
   1.249 +  _method = NULL;
   1.250 +  _bci    = 0;
   1.251 +#ifdef CHECK_UNHANDLED_OOPS
   1.252 +  // This one is always allocated with new, but check it just in case.
   1.253 +  Thread *thread = Thread::current();
   1.254 +  if (thread->is_in_stack((address)&_method)) {
   1.255 +    thread->allow_unhandled_oop((oop*)&_method);
   1.256 +  }
   1.257 +#endif // CHECK_UNHANDLED_OOPS
   1.258 +}
   1.259 +
   1.260 +JvmtiBreakpoint::JvmtiBreakpoint(methodOop m_method, jlocation location) {
   1.261 +  _method        = m_method;
   1.262 +  assert(_method != NULL, "_method != NULL");
   1.263 +  _bci           = (int) location;
   1.264 +#ifdef CHECK_UNHANDLED_OOPS
   1.265 +  // Could be allocated with new and wouldn't be on the unhandled oop list.
   1.266 +  Thread *thread = Thread::current();
   1.267 +  if (thread->is_in_stack((address)&_method)) {
   1.268 +    thread->allow_unhandled_oop(&_method);
   1.269 +  }
   1.270 +#endif // CHECK_UNHANDLED_OOPS
   1.271 +
   1.272 +  assert(_bci >= 0, "_bci >= 0");
   1.273 +}
   1.274 +
   1.275 +void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
   1.276 +  _method   = bp._method;
   1.277 +  _bci      = bp._bci;
   1.278 +}
   1.279 +
   1.280 +bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
   1.281 +  Unimplemented();
   1.282 +  return false;
   1.283 +}
   1.284 +
   1.285 +bool JvmtiBreakpoint::equals(JvmtiBreakpoint& bp) {
   1.286 +  return _method   == bp._method
   1.287 +    &&   _bci      == bp._bci;
   1.288 +}
   1.289 +
   1.290 +bool JvmtiBreakpoint::is_valid() {
   1.291 +  return _method != NULL &&
   1.292 +         _bci >= 0;
   1.293 +}
   1.294 +
   1.295 +address JvmtiBreakpoint::getBcp() {
   1.296 +  return _method->bcp_from(_bci);
   1.297 +}
   1.298 +
   1.299 +void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
   1.300 +  ((methodOopDesc*)_method->*meth_act)(_bci);
   1.301 +
   1.302 +  // add/remove breakpoint to/from versions of the method that
   1.303 +  // are EMCP. Directly or transitively obsolete methods are
   1.304 +  // not saved in the PreviousVersionInfo.
   1.305 +  Thread *thread = Thread::current();
   1.306 +  instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
   1.307 +  symbolOop m_name = _method->name();
   1.308 +  symbolOop m_signature = _method->signature();
   1.309 +
   1.310 +  {
   1.311 +    ResourceMark rm(thread);
   1.312 +    // PreviousVersionInfo objects returned via PreviousVersionWalker
   1.313 +    // contain a GrowableArray of handles. We have to clean up the
   1.314 +    // GrowableArray _after_ the PreviousVersionWalker destructor
   1.315 +    // has destroyed the handles.
   1.316 +    {
   1.317 +      // search previous versions if they exist
   1.318 +      PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part());
   1.319 +      for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
   1.320 +           pv_info != NULL; pv_info = pvw.next_previous_version()) {
   1.321 +        GrowableArray<methodHandle>* methods =
   1.322 +          pv_info->prev_EMCP_method_handles();
   1.323 +
   1.324 +        if (methods == NULL) {
   1.325 +          // We have run into a PreviousVersion generation where
   1.326 +          // all methods were made obsolete during that generation's
   1.327 +          // RedefineClasses() operation. At the time of that
   1.328 +          // operation, all EMCP methods were flushed so we don't
   1.329 +          // have to go back any further.
   1.330 +          //
   1.331 +          // A NULL methods array is different than an empty methods
   1.332 +          // array. We cannot infer any optimizations about older
   1.333 +          // generations from an empty methods array for the current
   1.334 +          // generation.
   1.335 +          break;
   1.336 +        }
   1.337 +
   1.338 +        for (int i = methods->length() - 1; i >= 0; i--) {
   1.339 +          methodHandle method = methods->at(i);
   1.340 +          if (method->name() == m_name && method->signature() == m_signature) {
   1.341 +            RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
   1.342 +              meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear",
   1.343 +              method->name()->as_C_string(),
   1.344 +              method->signature()->as_C_string()));
   1.345 +            assert(!method->is_obsolete(), "only EMCP methods here");
   1.346 +
   1.347 +            ((methodOopDesc*)method()->*meth_act)(_bci);
   1.348 +            break;
   1.349 +          }
   1.350 +        }
   1.351 +      }
   1.352 +    } // pvw is cleaned up
   1.353 +  } // rm is cleaned up
   1.354 +}
   1.355 +
   1.356 +void JvmtiBreakpoint::set() {
   1.357 +  each_method_version_do(&methodOopDesc::set_breakpoint);
   1.358 +}
   1.359 +
   1.360 +void JvmtiBreakpoint::clear() {
   1.361 +  each_method_version_do(&methodOopDesc::clear_breakpoint);
   1.362 +}
   1.363 +
   1.364 +void JvmtiBreakpoint::print() {
   1.365 +#ifndef PRODUCT
   1.366 +  const char *class_name  = (_method == NULL) ? "NULL" : _method->klass_name()->as_C_string();
   1.367 +  const char *method_name = (_method == NULL) ? "NULL" : _method->name()->as_C_string();
   1.368 +
   1.369 +  tty->print("Breakpoint(%s,%s,%d,%p)",class_name, method_name, _bci, getBcp());
   1.370 +#endif
   1.371 +}
   1.372 +
   1.373 +
   1.374 +//
   1.375 +// class VM_ChangeBreakpoints
   1.376 +//
   1.377 +// Modify the Breakpoints data structure at a safepoint
   1.378 +//
   1.379 +
   1.380 +void VM_ChangeBreakpoints::doit() {
   1.381 +  switch (_operation) {
   1.382 +  case SET_BREAKPOINT:
   1.383 +    _breakpoints->set_at_safepoint(*_bp);
   1.384 +    break;
   1.385 +  case CLEAR_BREAKPOINT:
   1.386 +    _breakpoints->clear_at_safepoint(*_bp);
   1.387 +    break;
   1.388 +  case CLEAR_ALL_BREAKPOINT:
   1.389 +    _breakpoints->clearall_at_safepoint();
   1.390 +    break;
   1.391 +  default:
   1.392 +    assert(false, "Unknown operation");
   1.393 +  }
   1.394 +}
   1.395 +
   1.396 +void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
   1.397 +  // This operation keeps breakpoints alive
   1.398 +  if (_breakpoints != NULL) {
   1.399 +    _breakpoints->oops_do(f);
   1.400 +  }
   1.401 +  if (_bp != NULL) {
   1.402 +    _bp->oops_do(f);
   1.403 +  }
   1.404 +}
   1.405 +
   1.406 +//
   1.407 +// class JvmtiBreakpoints
   1.408 +//
   1.409 +// a JVMTI internal collection of JvmtiBreakpoint
   1.410 +//
   1.411 +
   1.412 +JvmtiBreakpoints::JvmtiBreakpoints(void listener_fun(void *,address *)) {
   1.413 +  _bps.initialize(this,listener_fun);
   1.414 +}
   1.415 +
   1.416 +JvmtiBreakpoints:: ~JvmtiBreakpoints() {}
   1.417 +
   1.418 +void  JvmtiBreakpoints::oops_do(OopClosure* f) {
   1.419 +  _bps.oops_do(f);
   1.420 +}
   1.421 +
   1.422 +void  JvmtiBreakpoints::gc_epilogue() {
   1.423 +  _bps.gc_epilogue();
   1.424 +}
   1.425 +
   1.426 +void  JvmtiBreakpoints::print() {
   1.427 +#ifndef PRODUCT
   1.428 +  ResourceMark rm;
   1.429 +
   1.430 +  int n = _bps.length();
   1.431 +  for (int i=0; i<n; i++) {
   1.432 +    JvmtiBreakpoint& bp = _bps.at(i);
   1.433 +    tty->print("%d: ", i);
   1.434 +    bp.print();
   1.435 +    tty->print_cr("");
   1.436 +  }
   1.437 +#endif
   1.438 +}
   1.439 +
   1.440 +
   1.441 +void JvmtiBreakpoints::set_at_safepoint(JvmtiBreakpoint& bp) {
   1.442 +  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   1.443 +
   1.444 +  int i = _bps.find(bp);
   1.445 +  if (i == -1) {
   1.446 +    _bps.append(bp);
   1.447 +    bp.set();
   1.448 +  }
   1.449 +}
   1.450 +
   1.451 +void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {
   1.452 +  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   1.453 +
   1.454 +  int i = _bps.find(bp);
   1.455 +  if (i != -1) {
   1.456 +    _bps.remove(i);
   1.457 +    bp.clear();
   1.458 +  }
   1.459 +}
   1.460 +
   1.461 +void JvmtiBreakpoints::clearall_at_safepoint() {
   1.462 +  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   1.463 +
   1.464 +  int len = _bps.length();
   1.465 +  for (int i=0; i<len; i++) {
   1.466 +    _bps.at(i).clear();
   1.467 +  }
   1.468 +  _bps.clear();
   1.469 +}
   1.470 +
   1.471 +int JvmtiBreakpoints::length() { return _bps.length(); }
   1.472 +
   1.473 +int JvmtiBreakpoints::set(JvmtiBreakpoint& bp) {
   1.474 +  if ( _bps.find(bp) != -1) {
   1.475 +     return JVMTI_ERROR_DUPLICATE;
   1.476 +  }
   1.477 +  VM_ChangeBreakpoints set_breakpoint(this,VM_ChangeBreakpoints::SET_BREAKPOINT, &bp);
   1.478 +  VMThread::execute(&set_breakpoint);
   1.479 +  return JVMTI_ERROR_NONE;
   1.480 +}
   1.481 +
   1.482 +int JvmtiBreakpoints::clear(JvmtiBreakpoint& bp) {
   1.483 +  if ( _bps.find(bp) == -1) {
   1.484 +     return JVMTI_ERROR_NOT_FOUND;
   1.485 +  }
   1.486 +
   1.487 +  VM_ChangeBreakpoints clear_breakpoint(this,VM_ChangeBreakpoints::CLEAR_BREAKPOINT, &bp);
   1.488 +  VMThread::execute(&clear_breakpoint);
   1.489 +  return JVMTI_ERROR_NONE;
   1.490 +}
   1.491 +
   1.492 +void JvmtiBreakpoints::clearall_in_class_at_safepoint(klassOop klass) {
   1.493 +  bool changed = true;
   1.494 +  // We are going to run thru the list of bkpts
   1.495 +  // and delete some.  This deletion probably alters
   1.496 +  // the list in some implementation defined way such
   1.497 +  // that when we delete entry i, the next entry might
   1.498 +  // no longer be at i+1.  To be safe, each time we delete
   1.499 +  // an entry, we'll just start again from the beginning.
   1.500 +  // We'll stop when we make a pass thru the whole list without
   1.501 +  // deleting anything.
   1.502 +  while (changed) {
   1.503 +    int len = _bps.length();
   1.504 +    changed = false;
   1.505 +    for (int i = 0; i < len; i++) {
   1.506 +      JvmtiBreakpoint& bp = _bps.at(i);
   1.507 +      if (bp.method()->method_holder() == klass) {
   1.508 +        bp.clear();
   1.509 +        _bps.remove(i);
   1.510 +        // This changed 'i' so we have to start over.
   1.511 +        changed = true;
   1.512 +        break;
   1.513 +      }
   1.514 +    }
   1.515 +  }
   1.516 +}
   1.517 +
   1.518 +void JvmtiBreakpoints::clearall() {
   1.519 +  VM_ChangeBreakpoints clearall_breakpoint(this,VM_ChangeBreakpoints::CLEAR_ALL_BREAKPOINT);
   1.520 +  VMThread::execute(&clearall_breakpoint);
   1.521 +}
   1.522 +
   1.523 +//
   1.524 +// class JvmtiCurrentBreakpoints
   1.525 +//
   1.526 +
   1.527 +JvmtiBreakpoints *JvmtiCurrentBreakpoints::_jvmti_breakpoints  = NULL;
   1.528 +address *         JvmtiCurrentBreakpoints::_breakpoint_list    = NULL;
   1.529 +
   1.530 +
   1.531 +JvmtiBreakpoints& JvmtiCurrentBreakpoints::get_jvmti_breakpoints() {
   1.532 +  if (_jvmti_breakpoints != NULL) return (*_jvmti_breakpoints);
   1.533 +  _jvmti_breakpoints = new JvmtiBreakpoints(listener_fun);
   1.534 +  assert(_jvmti_breakpoints != NULL, "_jvmti_breakpoints != NULL");
   1.535 +  return (*_jvmti_breakpoints);
   1.536 +}
   1.537 +
   1.538 +void  JvmtiCurrentBreakpoints::listener_fun(void *this_obj, address *cache) {
   1.539 +  JvmtiBreakpoints *this_jvmti = (JvmtiBreakpoints *) this_obj;
   1.540 +  assert(this_jvmti != NULL, "this_jvmti != NULL");
   1.541 +
   1.542 +  debug_only(int n = this_jvmti->length(););
   1.543 +  assert(cache[n] == NULL, "cache must be NULL terminated");
   1.544 +
   1.545 +  set_breakpoint_list(cache);
   1.546 +}
   1.547 +
   1.548 +
   1.549 +void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
   1.550 +  if (_jvmti_breakpoints != NULL) {
   1.551 +    _jvmti_breakpoints->oops_do(f);
   1.552 +  }
   1.553 +}
   1.554 +
   1.555 +void JvmtiCurrentBreakpoints::gc_epilogue() {
   1.556 +  if (_jvmti_breakpoints != NULL) {
   1.557 +    _jvmti_breakpoints->gc_epilogue();
   1.558 +  }
   1.559 +}
   1.560 +
   1.561 +
   1.562 +///////////////////////////////////////////////////////////////
   1.563 +//
   1.564 +// class VM_GetOrSetLocal
   1.565 +//
   1.566 +
   1.567 +// Constructor for non-object getter
   1.568 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type)
   1.569 +  : _thread(thread)
   1.570 +  , _calling_thread(NULL)
   1.571 +  , _depth(depth)
   1.572 +  , _index(index)
   1.573 +  , _type(type)
   1.574 +  , _set(false)
   1.575 +  , _jvf(NULL)
   1.576 +  , _result(JVMTI_ERROR_NONE)
   1.577 +{
   1.578 +}
   1.579 +
   1.580 +// Constructor for object or non-object setter
   1.581 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, jint depth, int index, BasicType type, jvalue value)
   1.582 +  : _thread(thread)
   1.583 +  , _calling_thread(NULL)
   1.584 +  , _depth(depth)
   1.585 +  , _index(index)
   1.586 +  , _type(type)
   1.587 +  , _value(value)
   1.588 +  , _set(true)
   1.589 +  , _jvf(NULL)
   1.590 +  , _result(JVMTI_ERROR_NONE)
   1.591 +{
   1.592 +}
   1.593 +
   1.594 +// Constructor for object getter
   1.595 +VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_thread, jint depth, int index)
   1.596 +  : _thread(thread)
   1.597 +  , _calling_thread(calling_thread)
   1.598 +  , _depth(depth)
   1.599 +  , _index(index)
   1.600 +  , _type(T_OBJECT)
   1.601 +  , _set(false)
   1.602 +  , _jvf(NULL)
   1.603 +  , _result(JVMTI_ERROR_NONE)
   1.604 +{
   1.605 +}
   1.606 +
   1.607 +
   1.608 +vframe *VM_GetOrSetLocal::get_vframe() {
   1.609 +  if (!_thread->has_last_Java_frame()) {
   1.610 +    return NULL;
   1.611 +  }
   1.612 +  RegisterMap reg_map(_thread);
   1.613 +  vframe *vf = _thread->last_java_vframe(&reg_map);
   1.614 +  int d = 0;
   1.615 +  while ((vf != NULL) && (d < _depth)) {
   1.616 +    vf = vf->java_sender();
   1.617 +    d++;
   1.618 +  }
   1.619 +  return vf;
   1.620 +}
   1.621 +
   1.622 +javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
   1.623 +  vframe* vf = get_vframe();
   1.624 +  if (vf == NULL) {
   1.625 +    _result = JVMTI_ERROR_NO_MORE_FRAMES;
   1.626 +    return NULL;
   1.627 +  }
   1.628 +  javaVFrame *jvf = (javaVFrame*)vf;
   1.629 +
   1.630 +  if (!vf->is_java_frame() || jvf->method()->is_native()) {
   1.631 +    _result = JVMTI_ERROR_OPAQUE_FRAME;
   1.632 +    return NULL;
   1.633 +  }
   1.634 +  return jvf;
   1.635 +}
   1.636 +
   1.637 +// Check that the klass is assignable to a type with the given signature.
   1.638 +// Another solution could be to use the function Klass::is_subtype_of(type).
   1.639 +// But the type class can be forced to load/initialize eagerly in such a case.
   1.640 +// This may cause unexpected consequences like CFLH or class-init JVMTI events.
   1.641 +// It is better to avoid such a behavior.
   1.642 +bool VM_GetOrSetLocal::is_assignable(const char* ty_sign, Klass* klass, Thread* thread) {
   1.643 +  assert(ty_sign != NULL, "type signature must not be NULL");
   1.644 +  assert(thread != NULL, "thread must not be NULL");
   1.645 +  assert(klass != NULL, "klass must not be NULL");
   1.646 +
   1.647 +  int len = (int) strlen(ty_sign);
   1.648 +  if (ty_sign[0] == 'L' && ty_sign[len-1] == ';') { // Need pure class/interface name
   1.649 +    ty_sign++;
   1.650 +    len -= 2;
   1.651 +  }
   1.652 +  symbolHandle ty_sym = oopFactory::new_symbol_handle(ty_sign, len, thread);
   1.653 +  if (klass->name() == ty_sym()) {
   1.654 +    return true;
   1.655 +  }
   1.656 +  // Compare primary supers
   1.657 +  int super_depth = klass->super_depth();
   1.658 +  int idx;
   1.659 +  for (idx = 0; idx < super_depth; idx++) {
   1.660 +    if (Klass::cast(klass->primary_super_of_depth(idx))->name() == ty_sym()) {
   1.661 +      return true;
   1.662 +    }
   1.663 +  }
   1.664 +  // Compare secondary supers
   1.665 +  objArrayOop sec_supers = klass->secondary_supers();
   1.666 +  for (idx = 0; idx < sec_supers->length(); idx++) {
   1.667 +    if (Klass::cast((klassOop) sec_supers->obj_at(idx))->name() == ty_sym()) {
   1.668 +      return true;
   1.669 +    }
   1.670 +  }
   1.671 +  return false;
   1.672 +}
   1.673 +
   1.674 +// Checks error conditions:
   1.675 +//   JVMTI_ERROR_INVALID_SLOT
   1.676 +//   JVMTI_ERROR_TYPE_MISMATCH
   1.677 +// Returns: 'true' - everything is Ok, 'false' - error code
   1.678 +
   1.679 +bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {
   1.680 +  methodOop method_oop = jvf->method();
   1.681 +  if (!method_oop->has_localvariable_table()) {
   1.682 +    // Just to check index boundaries
   1.683 +    jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
   1.684 +    if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
   1.685 +      _result = JVMTI_ERROR_INVALID_SLOT;
   1.686 +      return false;
   1.687 +    }
   1.688 +    return true;
   1.689 +  }
   1.690 +
   1.691 +  jint num_entries = method_oop->localvariable_table_length();
   1.692 +  if (num_entries == 0) {
   1.693 +    _result = JVMTI_ERROR_INVALID_SLOT;
   1.694 +    return false;       // There are no slots
   1.695 +  }
   1.696 +  int signature_idx = -1;
   1.697 +  int vf_bci = jvf->bci();
   1.698 +  LocalVariableTableElement* table = method_oop->localvariable_table_start();
   1.699 +  for (int i = 0; i < num_entries; i++) {
   1.700 +    int start_bci = table[i].start_bci;
   1.701 +    int end_bci = start_bci + table[i].length;
   1.702 +
   1.703 +    // Here we assume that locations of LVT entries
   1.704 +    // with the same slot number cannot be overlapped
   1.705 +    if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
   1.706 +      signature_idx = (int) table[i].descriptor_cp_index;
   1.707 +      break;
   1.708 +    }
   1.709 +  }
   1.710 +  if (signature_idx == -1) {
   1.711 +    _result = JVMTI_ERROR_INVALID_SLOT;
   1.712 +    return false;       // Incorrect slot index
   1.713 +  }
   1.714 +  symbolOop   sign_sym  = method_oop->constants()->symbol_at(signature_idx);
   1.715 +  const char* signature = (const char *) sign_sym->as_utf8();
   1.716 +  BasicType slot_type = char2type(signature[0]);
   1.717 +
   1.718 +  switch (slot_type) {
   1.719 +  case T_BYTE:
   1.720 +  case T_SHORT:
   1.721 +  case T_CHAR:
   1.722 +  case T_BOOLEAN:
   1.723 +    slot_type = T_INT;
   1.724 +    break;
   1.725 +  case T_ARRAY:
   1.726 +    slot_type = T_OBJECT;
   1.727 +    break;
   1.728 +  };
   1.729 +  if (_type != slot_type) {
   1.730 +    _result = JVMTI_ERROR_TYPE_MISMATCH;
   1.731 +    return false;
   1.732 +  }
   1.733 +
   1.734 +  jobject jobj = _value.l;
   1.735 +  if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed
   1.736 +    // Check that the jobject class matches the return type signature.
   1.737 +    JavaThread* cur_thread = JavaThread::current();
   1.738 +    HandleMark hm(cur_thread);
   1.739 +
   1.740 +    Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));
   1.741 +    NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
   1.742 +    KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
   1.743 +    NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
   1.744 +
   1.745 +    if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) {
   1.746 +      _result = JVMTI_ERROR_TYPE_MISMATCH;
   1.747 +      return false;
   1.748 +    }
   1.749 +  }
   1.750 +  return true;
   1.751 +}
   1.752 +
   1.753 +static bool can_be_deoptimized(vframe* vf) {
   1.754 +  return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized());
   1.755 +}
   1.756 +
   1.757 +bool VM_GetOrSetLocal::doit_prologue() {
   1.758 +  _jvf = get_java_vframe();
   1.759 +  NULL_CHECK(_jvf, false);
   1.760 +
   1.761 +  if (!check_slot_type(_jvf)) {
   1.762 +    return false;
   1.763 +  }
   1.764 +  return true;
   1.765 +}
   1.766 +
   1.767 +void VM_GetOrSetLocal::doit() {
   1.768 +  if (_set) {
   1.769 +    // Force deoptimization of frame if compiled because it's
   1.770 +    // possible the compiler emitted some locals as constant values,
   1.771 +    // meaning they are not mutable.
   1.772 +    if (can_be_deoptimized(_jvf)) {
   1.773 +
   1.774 +      // Schedule deoptimization so that eventually the local
   1.775 +      // update will be written to an interpreter frame.
   1.776 +      VM_DeoptimizeFrame deopt(_jvf->thread(), _jvf->fr().id());
   1.777 +      VMThread::execute(&deopt);
   1.778 +
   1.779 +      // Now store a new value for the local which will be applied
   1.780 +      // once deoptimization occurs. Note however that while this
   1.781 +      // write is deferred until deoptimization actually happens
   1.782 +      // can vframe created after this point will have its locals
   1.783 +      // reflecting this update so as far as anyone can see the
   1.784 +      // write has already taken place.
   1.785 +
   1.786 +      // If we are updating an oop then get the oop from the handle
   1.787 +      // since the handle will be long gone by the time the deopt
   1.788 +      // happens. The oop stored in the deferred local will be
   1.789 +      // gc'd on its own.
   1.790 +      if (_type == T_OBJECT) {
   1.791 +        _value.l = (jobject) (JNIHandles::resolve_external_guard(_value.l));
   1.792 +      }
   1.793 +      // Re-read the vframe so we can see that it is deoptimized
   1.794 +      // [ Only need because of assert in update_local() ]
   1.795 +      _jvf = get_java_vframe();
   1.796 +      ((compiledVFrame*)_jvf)->update_local(_type, _index, _value);
   1.797 +      return;
   1.798 +    }
   1.799 +    StackValueCollection *locals = _jvf->locals();
   1.800 +    HandleMark hm;
   1.801 +
   1.802 +    switch (_type) {
   1.803 +    case T_INT:    locals->set_int_at   (_index, _value.i); break;
   1.804 +    case T_LONG:   locals->set_long_at  (_index, _value.j); break;
   1.805 +    case T_FLOAT:  locals->set_float_at (_index, _value.f); break;
   1.806 +    case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
   1.807 +    case T_OBJECT: {
   1.808 +      Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
   1.809 +      locals->set_obj_at (_index, ob_h);
   1.810 +      break;
   1.811 +    }
   1.812 +    default: ShouldNotReachHere();
   1.813 +    }
   1.814 +    _jvf->set_locals(locals);
   1.815 +  } else {
   1.816 +    StackValueCollection *locals = _jvf->locals();
   1.817 +
   1.818 +    if (locals->at(_index)->type() == T_CONFLICT) {
   1.819 +      memset(&_value, 0, sizeof(_value));
   1.820 +      _value.l = NULL;
   1.821 +      return;
   1.822 +    }
   1.823 +
   1.824 +    switch (_type) {
   1.825 +    case T_INT:    _value.i = locals->int_at   (_index);   break;
   1.826 +    case T_LONG:   _value.j = locals->long_at  (_index);   break;
   1.827 +    case T_FLOAT:  _value.f = locals->float_at (_index);   break;
   1.828 +    case T_DOUBLE: _value.d = locals->double_at(_index);   break;
   1.829 +    case T_OBJECT: {
   1.830 +      // Wrap the oop to be returned in a local JNI handle since
   1.831 +      // oops_do() no longer applies after doit() is finished.
   1.832 +      oop obj = locals->obj_at(_index)();
   1.833 +      _value.l = JNIHandles::make_local(_calling_thread, obj);
   1.834 +      break;
   1.835 +    }
   1.836 +    default: ShouldNotReachHere();
   1.837 +    }
   1.838 +  }
   1.839 +}
   1.840 +
   1.841 +
   1.842 +bool VM_GetOrSetLocal::allow_nested_vm_operations() const {
   1.843 +  return true; // May need to deoptimize
   1.844 +}
   1.845 +
   1.846 +
   1.847 +/////////////////////////////////////////////////////////////////////////////////////////
   1.848 +
   1.849 +//
   1.850 +// class JvmtiSuspendControl - see comments in jvmtiImpl.hpp
   1.851 +//
   1.852 +
   1.853 +bool JvmtiSuspendControl::suspend(JavaThread *java_thread) {
   1.854 +  // external suspend should have caught suspending a thread twice
   1.855 +
   1.856 +  // Immediate suspension required for JPDA back-end so JVMTI agent threads do
   1.857 +  // not deadlock due to later suspension on transitions while holding
   1.858 +  // raw monitors.  Passing true causes the immediate suspension.
   1.859 +  // java_suspend() will catch threads in the process of exiting
   1.860 +  // and will ignore them.
   1.861 +  java_thread->java_suspend();
   1.862 +
   1.863 +  // It would be nice to have the following assertion in all the time,
   1.864 +  // but it is possible for a racing resume request to have resumed
   1.865 +  // this thread right after we suspended it. Temporarily enable this
   1.866 +  // assertion if you are chasing a different kind of bug.
   1.867 +  //
   1.868 +  // assert(java_lang_Thread::thread(java_thread->threadObj()) == NULL ||
   1.869 +  //   java_thread->is_being_ext_suspended(), "thread is not suspended");
   1.870 +
   1.871 +  if (java_lang_Thread::thread(java_thread->threadObj()) == NULL) {
   1.872 +    // check again because we can get delayed in java_suspend():
   1.873 +    // the thread is in process of exiting.
   1.874 +    return false;
   1.875 +  }
   1.876 +
   1.877 +  return true;
   1.878 +}
   1.879 +
   1.880 +bool JvmtiSuspendControl::resume(JavaThread *java_thread) {
   1.881 +  // external suspend should have caught resuming a thread twice
   1.882 +  assert(java_thread->is_being_ext_suspended(), "thread should be suspended");
   1.883 +
   1.884 +  // resume thread
   1.885 +  {
   1.886 +    // must always grab Threads_lock, see JVM_SuspendThread
   1.887 +    MutexLocker ml(Threads_lock);
   1.888 +    java_thread->java_resume();
   1.889 +  }
   1.890 +
   1.891 +  return true;
   1.892 +}
   1.893 +
   1.894 +
   1.895 +void JvmtiSuspendControl::print() {
   1.896 +#ifndef PRODUCT
   1.897 +  MutexLocker mu(Threads_lock);
   1.898 +  ResourceMark rm;
   1.899 +
   1.900 +  tty->print("Suspended Threads: [");
   1.901 +  for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
   1.902 +#if JVMTI_TRACE
   1.903 +    const char *name   = JvmtiTrace::safe_get_thread_name(thread);
   1.904 +#else
   1.905 +    const char *name   = "";
   1.906 +#endif /*JVMTI_TRACE */
   1.907 +    tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
   1.908 +    if (!thread->has_last_Java_frame()) {
   1.909 +      tty->print("no stack");
   1.910 +    }
   1.911 +    tty->print(") ");
   1.912 +  }
   1.913 +  tty->print_cr("]");
   1.914 +#endif
   1.915 +}

mercurial