hotspot/src/share/vm/prims/jvmtiExport.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 3581 c84159af60dd
child 4571 80b553bddc26
child 4492 63c49e60fc25
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
3580
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
     2
 * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_jvmtiExport.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#ifdef JVMTI_TRACE
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
#define EVT_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_SENT) != 0) { SafeResourceMark rm; tty->print_cr out; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
#define EVT_TRIG_TRACE(evt,out) if ((JvmtiTrace::event_trace_flags(evt) & JvmtiTrace::SHOW_EVENT_TRIGGER) != 0) { SafeResourceMark rm; tty->print_cr out; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
#define EVT_TRIG_TRACE(evt,out)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
#define EVT_TRACE(evt,out)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// JvmtiEventTransition
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
// TO DO --
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
//  more handle purging
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
// Use this for JavaThreads and state is  _thread_in_vm.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
class JvmtiJavaThreadEventTransition : StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  ResourceMark _rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  ThreadToNativeFromVM _transition;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  HandleMark _hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  JvmtiJavaThreadEventTransition(JavaThread *thread) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    _rm(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    _transition(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
    _hm(thread)  {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// For JavaThreads which are not in _thread_in_vm state
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
// and other system threads use this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
class JvmtiThreadEventTransition : StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  ResourceMark _rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  HandleMark _hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  JavaThreadState _saved_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  JavaThread *_jthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    if (thread->is_Java_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
       _jthread = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
       _saved_state = _jthread->thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
       if (_saved_state == _thread_in_Java) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
         ThreadStateTransition::transition_from_java(_jthread, _thread_in_native);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
       } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
         ThreadStateTransition::transition(_jthread, _saved_state, _thread_in_native);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
       }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      _jthread = NULL;
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
  ~JvmtiThreadEventTransition() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    if (_jthread != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
      ThreadStateTransition::transition_from_native(_jthread, _saved_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
// JvmtiEventMark
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
class JvmtiEventMark : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  JavaThread *_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  JNIEnv* _jni_env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  bool _exception_detected;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  bool _exception_caught;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  JNIHandleBlock* _hblock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  JvmtiEventMark(JavaThread *thread) :  _thread(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
                                         _jni_env(thread->jni_environment()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    _hblock = thread->active_handles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    _hblock->clear_thoroughly(); // so we can be safe
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    // we want to use the code above - but that needs the JNIHandle changes - later...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    // for now, steal JNI push local frame code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    // we are before an event.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    // Save current jvmti thread exception state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      _exception_detected = state->is_exception_detected();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
      _exception_caught = state->is_exception_caught();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
      _exception_detected = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
      _exception_caught = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    JNIHandleBlock* old_handles = thread->active_handles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    assert(new_handles != NULL, "should not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    new_handles->set_pop_frame_link(old_handles);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    thread->set_active_handles(new_handles);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    assert(thread == JavaThread::current(), "thread must be current!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    thread->frame_anchor()->make_walkable(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  ~JvmtiEventMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
    _hblock->clear(); // for consistency with future correct behavior
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    // we want to use the code above - but that needs the JNIHandle changes - later...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    // for now, steal JNI pop local frame code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    JNIHandleBlock* old_handles = _thread->active_handles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    JNIHandleBlock* new_handles = old_handles->pop_frame_link();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    assert(new_handles != NULL, "should not be NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    _thread->set_active_handles(new_handles);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    // Note that we set the pop_frame_link to NULL explicitly, otherwise
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    // the release_block call will release the blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    old_handles->set_pop_frame_link(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
    JNIHandleBlock::release_block(old_handles, _thread); // may block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    JvmtiThreadState* state = _thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    // we are continuing after an event.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
      // Restore the jvmti thread exception state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      if (_exception_detected) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
        state->set_exception_detected();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      if (_exception_caught) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
        state->set_exception_caught();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
#if 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  jobject to_jobject(oop obj) { return obj == NULL? NULL : _hblock->allocate_handle_fast(obj); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // we want to use the code above - but that needs the JNIHandle changes - later...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  // for now, use regular make_local
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  jobject to_jobject(oop obj) { return JNIHandles::make_local(_thread,obj); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  jclass to_jclass(klassOop klass) { return (klass == NULL ? NULL : (jclass)to_jobject(Klass::cast(klass)->java_mirror())); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  jmethodID to_jmethodID(methodHandle method) { return method->jmethod_id(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  JNIEnv* jni_env() { return _jni_env; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
class JvmtiThreadEventMark : public JvmtiEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  jthread _jt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  JvmtiThreadEventMark(JavaThread *thread) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    JvmtiEventMark(thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    _jt = (jthread)(to_jobject(thread->threadObj()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
 jthread jni_thread() { return _jt; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
class JvmtiClassEventMark : public JvmtiThreadEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  jclass _jc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  JvmtiClassEventMark(JavaThread *thread, klassOop klass) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
    JvmtiThreadEventMark(thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    _jc = to_jclass(klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  jclass jni_class() { return _jc; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
class JvmtiMethodEventMark : public JvmtiThreadEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  jmethodID _mid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  JvmtiMethodEventMark(JavaThread *thread, methodHandle method) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    JvmtiThreadEventMark(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    _mid(to_jmethodID(method)) {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  jmethodID jni_methodID() { return _mid; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
class JvmtiLocationEventMark : public JvmtiMethodEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  jlocation _loc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  JvmtiLocationEventMark(JavaThread *thread, methodHandle method, address location) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
    JvmtiMethodEventMark(thread, method),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
    _loc(location - method->code_base()) {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  jlocation location() { return _loc; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
class JvmtiExceptionEventMark : public JvmtiLocationEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  jobject _exc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  JvmtiExceptionEventMark(JavaThread *thread, methodHandle method, address location, Handle exception) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    JvmtiLocationEventMark(thread, method, location),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    _exc(to_jobject(exception())) {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  jobject exception() { return _exc; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
class JvmtiClassFileLoadEventMark : public JvmtiThreadEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  const char *_class_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  jobject _jloader;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  jobject _protection_domain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  jclass  _class_being_redefined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  JvmtiClassFileLoadEventMark(JavaThread *thread, symbolHandle name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
     Handle class_loader, Handle prot_domain, KlassHandle *class_being_redefined) : JvmtiThreadEventMark(thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      _class_name = name() != NULL? name->as_utf8() : NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      _jloader = (jobject)to_jobject(class_loader());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      _protection_domain = (jobject)to_jobject(prot_domain());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      if (class_being_redefined == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
        _class_being_redefined = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
        _class_being_redefined = (jclass)to_jclass((*class_being_redefined)());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  const char *class_name() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    return _class_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  jobject jloader() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    return _jloader;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  jobject protection_domain() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    return _protection_domain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  jclass class_being_redefined() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    return _class_being_redefined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
int               JvmtiExport::_field_access_count                        = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
int               JvmtiExport::_field_modification_count                  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
bool              JvmtiExport::_can_access_local_variables                = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
bool              JvmtiExport::_can_examine_or_deopt_anywhere             = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
bool              JvmtiExport::_can_hotswap_or_post_breakpoint            = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
bool              JvmtiExport::_can_modify_any_class                      = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
bool              JvmtiExport::_can_walk_any_space                        = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
bool              JvmtiExport::_has_redefined_a_class                     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
bool              JvmtiExport::_all_dependencies_are_recorded             = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
// field access management
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
// interpreter generator needs the address of the counter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
address JvmtiExport::get_field_access_count_addr() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // We don't grab a lock because we don't want to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  // serialize field access between all threads. This means that a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  // thread on another processor can see the wrong count value and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  // may either miss making a needed call into post_field_access()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  // or will make an unneeded call into post_field_access(). We pay
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // this price to avoid slowing down the VM when we aren't watching
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // field accesses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // Other access/mutation safe by virtue of being in VM state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  return (address)(&_field_access_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
// field modification management
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
// interpreter generator needs the address of the counter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
address JvmtiExport::get_field_modification_count_addr() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  // We don't grab a lock because we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // want to serialize field modification between all threads. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  // means that a thread on another processor can see the wrong
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  // count value and may either miss making a needed call into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  // post_field_modification() or will make an unneeded call into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  // post_field_modification(). We pay this price to avoid slowing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  // down the VM when we aren't watching field modifications.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  // Other access/mutation safe by virtue of being in VM state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  return (address)(&_field_modification_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
// Functions needed by java.lang.instrument for starting up javaagent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
jint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  /* To Do: add version checks */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    // transition code: native to VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    ThreadInVMfromNative __tiv(current_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    __ENTRY(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    debug_only(VMNativeEntryWrapper __vew;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    *penv = jvmti_env->jvmti_external();  // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  } else if (JvmtiEnv::get_phase() == JVMTI_PHASE_ONLOAD) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    // not live, no thread to transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    *penv = jvmti_env->jvmti_external();  // actual type is jvmtiEnv* -- not to be confused with JvmtiEnv*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    // Called at the wrong time
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    *penv = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
    return JNI_EDETACHED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
void JvmtiExport::enter_primordial_phase() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
void JvmtiExport::enter_start_phase() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  JvmtiManageCapabilities::recompute_always_capabilities();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  JvmtiEnvBase::set_phase(JVMTI_PHASE_START);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
void JvmtiExport::enter_onload_phase() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
void JvmtiExport::enter_live_phase() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
// JVMTI events that the VM posts to the debugger and also startup agent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
// and call the agent's premain() for java.lang.instrument.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
void JvmtiExport::post_vm_start() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  // can now enable some events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  JvmtiEventController::vm_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
    if (env->is_enabled(JVMTI_EVENT_VM_START)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
      EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
      JavaThread *thread  = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
      JvmtiThreadEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      jvmtiEventVMStart callback = env->callbacks()->VMStart;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
        (*callback)(env->jvmti_external(), jem.jni_env());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
void JvmtiExport::post_vm_initialized() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  // can now enable events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  JvmtiEventController::vm_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
      EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
      JavaThread *thread  = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
      JvmtiThreadEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
      jvmtiEventVMInit callback = env->callbacks()->VMInit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
void JvmtiExport::post_vm_death() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
      EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
      JavaThread *thread  = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
      JvmtiEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
      jvmtiEventVMDeath callback = env->callbacks()->VMDeath;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
        (*callback)(env->jvmti_external(), jem.jni_env());
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  JvmtiEventController::vm_death();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
char**
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
JvmtiExport::get_all_native_method_prefixes(int* count_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // Have to grab JVMTI thread state lock to be sure environment doesn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  // go away while we iterate them.  No locks during VM bring-up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    MutexLocker mu(JvmtiThreadState_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
class JvmtiClassFileLoadHookPoster : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  symbolHandle         _h_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  Handle               _class_loader;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  Handle               _h_protection_domain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  unsigned char **     _data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  unsigned char **     _end_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  JavaThread *         _thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  jint                 _curr_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  unsigned char *      _curr_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  JvmtiEnv *           _curr_env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  jint *               _cached_length_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
  unsigned char **     _cached_data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  JvmtiThreadState *   _state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  KlassHandle *        _h_class_being_redefined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  JvmtiClassLoadKind   _load_kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
                                      Handle h_protection_domain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
                                      unsigned char **data_ptr, unsigned char **end_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
                                      unsigned char **cached_data_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
                                      jint *cached_length_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
    _h_name = h_name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    _class_loader = class_loader;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
    _h_protection_domain = h_protection_domain;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    _data_ptr = data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    _end_ptr = end_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    _thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
    _curr_len = *end_ptr - *data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
    _curr_data = *data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
    _curr_env = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
    _cached_length_ptr = cached_length_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
    _cached_data_ptr = cached_data_ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
    *_cached_length_ptr = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    *_cached_data_ptr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
    _state = _thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    if (_state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
      _h_class_being_redefined = _state->get_class_being_redefined();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
      _load_kind = _state->get_class_load_kind();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      // Clear class_being_redefined flag here. The action
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
      // from agent handler could generate a new class file load
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      // hook event and if it is not cleared the new event generated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
      // from regular class file load could have this stale redefined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
      // class handle info.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
      _state->clear_class_being_redefined();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
      // redefine and retransform will always set the thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      _h_class_being_redefined = (KlassHandle *) NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      _load_kind = jvmti_class_load_kind_load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  void post() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
//    EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
//                   ("JVMTI [%s] class file load hook event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
//                    JvmtiTrace::safe_get_thread_name(_thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
    post_all_envs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
    copy_modified_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  void post_all_envs() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
    if (_load_kind != jvmti_class_load_kind_retransform) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
      // for class load and redefine,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
      // call the non-retransformable agents
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
      JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
      for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
        if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
          // non-retransformable agents cannot retransform back,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
          // so no need to cache the original class file bytes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
          post_to_env(env, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
      // retransformable agents get all events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
      if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        // retransformable agents need to cache the original class file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
        // bytes if changes are made via the ClassFileLoadHook
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
        post_to_env(env, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  void post_to_env(JvmtiEnv* env, bool caching_needed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    unsigned char *new_data = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    jint new_len = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
//    EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
//     ("JVMTI [%s] class file load hook event sent %s  data_ptr = %d, data_len = %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
//               JvmtiTrace::safe_get_thread_name(_thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
//               _h_name.is_null() ? "NULL" : _h_name->as_utf8(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
//               _curr_data, _curr_len ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
                                    _h_protection_domain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
                                    _h_class_being_redefined);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
    JvmtiJavaThreadEventTransition jet(_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
    JNIEnv* jni_env =  (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
                                                        NULL : jem.jni_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
    jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
      (*callback)(env->jvmti_external(), jni_env,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
                  jem.class_being_redefined(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
                  jem.jloader(), jem.class_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
                  jem.protection_domain(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
                  _curr_len, _curr_data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
                  &new_len, &new_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    if (new_data != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
      // this agent has modified class data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
      if (caching_needed && *_cached_data_ptr == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
        // data has been changed by the new retransformable agent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
        // and it hasn't already been cached, cache it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
        *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
        memcpy(*_cached_data_ptr, _curr_data, _curr_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
        *_cached_length_ptr = _curr_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
      if (_curr_data != *_data_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
        // curr_data is previous agent modified class data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
        // And this has been changed by the new agent so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
        // we can delete it now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
        _curr_env->Deallocate(_curr_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
      // Class file data has changed by the current agent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
      _curr_data = new_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
      _curr_len = new_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      // Save the current agent env we need this to deallocate the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
      // memory allocated by this agent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
      _curr_env = env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  void copy_modified_data() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    // if one of the agent has modified class file data.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    // Copy modified class data to new resources array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    if (_curr_data != *_data_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
      memcpy(*_data_ptr, _curr_data, _curr_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      *_end_ptr = *_data_ptr + _curr_len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      _curr_env->Deallocate(_curr_data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
bool JvmtiExport::_should_post_class_file_load_hook = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
// this entry is for class file load hook on class load, redefine and retransform
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
void JvmtiExport::post_class_file_load_hook(symbolHandle h_name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
                                            Handle class_loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
                                            Handle h_protection_domain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
                                            unsigned char **data_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
                                            unsigned char **end_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
                                            unsigned char **cached_data_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
                                            jint *cached_length_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  JvmtiClassFileLoadHookPoster poster(h_name, class_loader,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
                                      h_protection_domain,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
                                      data_ptr, end_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
                                      cached_data_ptr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
                                      cached_length_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  poster.post();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
void JvmtiExport::report_unsupported(bool on) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  // If any JVMTI service is turned on, we need to exit before native code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  // tries to access nonexistant services.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  if (on) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    vm_exit_during_initialization("Java Kernel does not support JVMTI.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
#ifndef JVMTI_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
static inline klassOop oop_to_klassOop(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  klassOop k = obj->klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  // if the object is a java.lang.Class then return the java mirror
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  if (k == SystemDictionary::class_klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    if (!java_lang_Class::is_primitive(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
      k = java_lang_Class::as_klassOop(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      assert(k != NULL, "class for non-primitive mirror must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  return k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
   jobject _jobj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
   jlong    _size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
   JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
     _jobj = (jobject)to_jobject(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
     _size = obj->size() * wordSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
   };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
   jobject jni_jobject() { return _jobj; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
   jlong size() { return _size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  jint _code_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  const void *_code_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  jint _map_length;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  jvmtiAddrLocationMap *_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  const void *_compile_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
          : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    _code_data = nm->code_begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    _code_size = nm->code_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    _compile_info = NULL; /* no info for our VM. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
    JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  ~JvmtiCompiledMethodLoadEventMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
     FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  jint code_size() { return _code_size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  const void *code_data() { return _code_data; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  jint map_length() { return _map_length; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  const jvmtiAddrLocationMap* map() { return _map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  const void *compile_info() { return _compile_info; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  jobject _jobj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  JvmtiMonitorEventMark(JavaThread *thread, oop object)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
          : JvmtiThreadEventMark(thread){
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
     _jobj = to_jobject(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  jobject jni_object() { return _jobj; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
// pending CompiledMethodUnload support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
bool JvmtiExport::_have_pending_compiled_method_unload_events;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
JavaThread* JvmtiExport::_current_poster;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
// post any pending CompiledMethodUnload events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
void JvmtiExport::post_pending_compiled_method_unload_events() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  JavaThread* self = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  assert(!self->owns_locks(), "can't hold locks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  // Indicates if this is the first activiation of this function.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
  // In theory the profiler's callback could call back into VM and provoke
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  // another CompiledMethodLoad event to be posted from this thread. As the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  // stack rewinds we need to ensure that the original activation does the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  // completion and notifies any waiters.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  bool first_activation = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  // the jmethodID (may not be valid) to be used for a single event
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  jmethodID method;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  const void *code_begin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  // grab the monitor and check if another thread is already posting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  // events. If there is another thread posting events then we wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  // until it completes. (In theory we could check the pending events to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  // see if any of the addresses overlap with the event that we want to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  // post but as it will happen so rarely we just block any thread waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  // to post a CompiledMethodLoad or DynamicCodeGenerated event until all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  // pending CompiledMethodUnload events have been posted).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  // If another thread isn't posting we examine the list of pending jmethodIDs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  // If the list is empty then we are done. If it's not empty then this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  // (self) becomes the pending event poster and we remove the top (last)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  // event from the list. Note that this means we remove the newest event first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  // but as they are all CompiledMethodUnload events the order doesn't matter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  // Once we have removed a jmethodID then we exit the monitor. Any other thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // be forced to wait on the monitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
    MutexLocker mu(JvmtiPendingEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    if (_current_poster != self) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
      while (_current_poster != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
        JvmtiPendingEvent_lock->wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    if ((_pending_compiled_method_unload_method_ids == NULL) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
        (_pending_compiled_method_unload_method_ids->length() == 0)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
    if (_current_poster == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
      _current_poster = self;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
      first_activation = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
      // re-entrant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
      guarantee(_current_poster == self, "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    method = _pending_compiled_method_unload_method_ids->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    code_begin = _pending_compiled_method_unload_code_begins->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
  // This thread is the pending event poster so it first posts the CompiledMethodUnload
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  // event for the jmethodID that has been removed from the list. Once posted it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  // re-grabs the monitor and checks the list again. If the list is empty then and this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  // is the first activation of the function then we reset the _have_pending_events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  // flag, cleanup _current_poster to indicate that no thread is now servicing the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  // pending events list, and finally notify any thread that might be waiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
    EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
                   ("JVMTI [%s] method compile unload event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
                   JvmtiTrace::safe_get_thread_name(self)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
    // post the event for each environment that has this event enabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
      if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
        EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
                  ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
                  JvmtiTrace::safe_get_thread_name(self), method));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
        JvmtiEventMark jem(self);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
        JvmtiJavaThreadEventTransition jet(self);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
        jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
          (*callback)(env->jvmti_external(), method, code_begin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    // event posted, now re-grab monitor and get the next event
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
    // If there's no next event then we are done. If this is the first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    // activiation of this function by this thread notify any waiters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    // so that they can post.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
      MutexLocker ml(JvmtiPendingEvent_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
      if (_pending_compiled_method_unload_method_ids->length() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
        if (first_activation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
          _have_pending_compiled_method_unload_events = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
          _current_poster = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
          JvmtiPendingEvent_lock->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
      method = _pending_compiled_method_unload_method_ids->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
      code_begin = _pending_compiled_method_unload_code_begins->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
// JvmtiExport
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
    ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
      ThreadState old_os_state = thread->osthread()->get_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
      thread->osthread()->set_state(BREAKPOINTED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
      EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
                     JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
                     location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
      JvmtiLocationEventMark jem(thread, mh, location);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
      jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
                    jem.jni_methodID(), jem.location());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
      ets->set_breakpoint_posted();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
      thread->osthread()->set_state(old_os_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
bool              JvmtiExport::_can_get_source_debug_extension            = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
bool              JvmtiExport::_can_maintain_original_method_order        = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
bool              JvmtiExport::_can_post_interpreter_events               = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
bool              JvmtiExport::_can_post_exceptions                       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
bool              JvmtiExport::_can_post_breakpoint                       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
bool              JvmtiExport::_can_post_field_access                     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
bool              JvmtiExport::_can_post_field_modification               = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
bool              JvmtiExport::_can_post_method_entry                     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
bool              JvmtiExport::_can_post_method_exit                      = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
bool              JvmtiExport::_can_pop_frame                             = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
bool              JvmtiExport::_can_force_early_return                    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
bool              JvmtiExport::_should_post_single_step                   = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
bool              JvmtiExport::_should_post_field_access                  = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
bool              JvmtiExport::_should_post_field_modification            = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
bool              JvmtiExport::_should_post_class_load                    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
bool              JvmtiExport::_should_post_class_prepare                 = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
bool              JvmtiExport::_should_post_class_unload                  = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
bool              JvmtiExport::_should_post_thread_life                   = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
bool              JvmtiExport::_should_clean_up_heap_objects              = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
bool              JvmtiExport::_should_post_native_method_bind            = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
bool              JvmtiExport::_should_post_dynamic_code_generated        = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
bool              JvmtiExport::_should_post_data_dump                     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
bool              JvmtiExport::_should_post_compiled_method_load          = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
bool              JvmtiExport::_should_post_compiled_method_unload        = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
bool              JvmtiExport::_should_post_monitor_contended_enter       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
bool              JvmtiExport::_should_post_monitor_contended_entered     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
bool              JvmtiExport::_should_post_monitor_wait                  = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
bool              JvmtiExport::_should_post_monitor_waited                = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
bool              JvmtiExport::_should_post_garbage_collection_start      = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
bool              JvmtiExport::_should_post_garbage_collection_finish     = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
bool              JvmtiExport::_should_post_object_free                   = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
bool              JvmtiExport::_should_post_resource_exhausted            = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
bool              JvmtiExport::_should_post_vm_object_alloc               = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
////////////////////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
// JVMTI single step management
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
void JvmtiExport::at_single_stepping_point(JavaThread *thread, methodOop method, address location) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
  assert(JvmtiExport::should_post_single_step(), "must be single stepping");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  // update information about current location and post a step event
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
  EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  if (!state->hide_single_stepping()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
    if (state->is_pending_step_for_popframe()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
      state->process_pending_step_for_popframe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
    if (state->is_pending_step_for_earlyret()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      state->process_pending_step_for_earlyret();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
    JvmtiExport::post_single_step(thread, mh(), location);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
void JvmtiExport::expose_single_stepping(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
    state->clear_hide_single_stepping();
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
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
bool JvmtiExport::hide_single_stepping(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
    state->set_hide_single_stepping();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
void JvmtiExport::post_class_load(JavaThread *thread, klassOop klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
  KlassHandle kh(thread, klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Trg Class Load triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  JvmtiThreadState* state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
    if (ets->is_enabled(JVMTI_EVENT_CLASS_LOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      EVT_TRACE(JVMTI_EVENT_CLASS_LOAD, ("JVMTI [%s] Evt Class Load sent %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
                                         JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
                                         kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
      JvmtiClassEventMark jem(thread, kh());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
      jvmtiEventClassLoad callback = env->callbacks()->ClassLoad;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
void JvmtiExport::post_class_prepare(JavaThread *thread, klassOop klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  KlassHandle kh(thread, klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Trg Class Prepare triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  JvmtiThreadState* state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
    if (ets->is_enabled(JVMTI_EVENT_CLASS_PREPARE)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
      EVT_TRACE(JVMTI_EVENT_CLASS_PREPARE, ("JVMTI [%s] Evt Class Prepare sent %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
                                            JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
                                            kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
      JvmtiClassEventMark jem(thread, kh());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
      jvmtiEventClassPrepare callback = env->callbacks()->ClassPrepare;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_class());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
void JvmtiExport::post_class_unload(klassOop klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  KlassHandle kh(thread, klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Trg Class Unload triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    assert(thread->is_VM_thread(), "wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
    // get JavaThread for whom we are proxy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
    JavaThread *real_thread =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
        (JavaThread *)((VMThread *)thread)->vm_operation()->calling_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
      if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
        EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("JVMTI [?] Evt Class Unload sent %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
                  kh()==NULL? "NULL" : Klass::cast(kh())->external_name() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
        // do everything manually, since this is a proxy - needs special care
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
        JNIEnv* jni_env = real_thread->jni_environment();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
        jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
        jclass jk = (jclass)JNIHandles::make_local(real_thread, Klass::cast(kh())->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
        // Before we call the JVMTI agent, we have to set the state in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
        // thread for which we are proxying.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
        JavaThreadState prev_state = real_thread->thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
        assert(prev_state == _thread_blocked, "JavaThread should be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
        real_thread->set_thread_state(_thread_in_native);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
        jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
          (*callback)(env->jvmti_external(), jni_env, jt, jk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
        assert(real_thread->thread_state() == _thread_in_native,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
               "JavaThread should be in native");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
        real_thread->set_thread_state(prev_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
        JNIHandles::destroy_local(jk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
        JNIHandles::destroy_local(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
void JvmtiExport::post_thread_start(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Trg Thread Start event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  // do JVMTI thread initialization (if needed)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  JvmtiEventController::thread_started(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
  // Do not post thread start event for hidden java thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
  if (JvmtiEventController::is_enabled(JVMTI_EVENT_THREAD_START) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
      !thread->is_hidden_from_external_view()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
      if (env->is_enabled(JVMTI_EVENT_THREAD_START)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
        EVT_TRACE(JVMTI_EVENT_THREAD_START, ("JVMTI [%s] Evt Thread Start event sent",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
                     JvmtiTrace::safe_get_thread_name(thread) ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
        JvmtiThreadEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
        jvmtiEventThreadStart callback = env->callbacks()->ThreadStart;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
          (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
void JvmtiExport::post_thread_end(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
  EVT_TRIG_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Trg Thread End event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  // Do not post thread end event for hidden java thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  if (state->is_enabled(JVMTI_EVENT_THREAD_END) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
      !thread->is_hidden_from_external_view()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
      if (ets->is_enabled(JVMTI_EVENT_THREAD_END)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
        EVT_TRACE(JVMTI_EVENT_THREAD_END, ("JVMTI [%s] Evt Thread End event sent",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
                     JvmtiTrace::safe_get_thread_name(thread) ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
        JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
        JvmtiThreadEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
        jvmtiEventThreadEnd callback = env->callbacks()->ThreadEnd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
          (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
void JvmtiExport::post_object_free(JvmtiEnv* env, jlong tag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  assert(SafepointSynchronize::is_at_safepoint(), "must be executed at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  assert(env->is_enabled(JVMTI_EVENT_OBJECT_FREE), "checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  EVT_TRIG_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Trg Object Free triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  EVT_TRACE(JVMTI_EVENT_OBJECT_FREE, ("JVMTI [?] Evt Object Free sent"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  jvmtiEventObjectFree callback = env->callbacks()->ObjectFree;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    (*callback)(env->jvmti_external(), tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
void JvmtiExport::post_resource_exhausted(jint resource_exhausted_flags, const char* description) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  EVT_TRIG_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Trg resource exhausted event triggered" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
    if (env->is_enabled(JVMTI_EVENT_RESOURCE_EXHAUSTED)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      EVT_TRACE(JVMTI_EVENT_RESOURCE_EXHAUSTED, ("JVMTI Evt resource exhausted event sent" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
      JavaThread *thread  = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
      JvmtiThreadEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
      jvmtiEventResourceExhausted callback = env->callbacks()->ResourceExhausted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        (*callback)(env->jvmti_external(), jem.jni_env(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
                    resource_exhausted_flags, NULL, description);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
void JvmtiExport::post_method_entry(JavaThread *thread, methodOop method, frame current_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
  EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Trg Method Entry triggered %s.%s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
                     JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  JvmtiThreadState* state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  if (state == NULL || !state->is_interp_only_mode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
    // for any thread that actually wants method entry, interp_only_mode is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  state->incr_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  if (state->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
    JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
      if (ets->is_enabled(JVMTI_EVENT_METHOD_ENTRY)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
        EVT_TRACE(JVMTI_EVENT_METHOD_ENTRY, ("JVMTI [%s] Evt Method Entry sent %s.%s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
                                             JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
                                             (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
                                             (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
        JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
        JvmtiMethodEventMark jem(thread, mh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
        jvmtiEventMethodEntry callback = env->callbacks()->MethodEntry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
          (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_methodID());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
void JvmtiExport::post_method_exit(JavaThread *thread, methodOop method, frame current_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  EVT_TRIG_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Trg Method Exit triggered %s.%s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
                     JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  if (state == NULL || !state->is_interp_only_mode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    // for any thread that actually wants method exit, interp_only_mode is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  // return a flag when a method terminates by throwing an exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  // i.e. if an exception is thrown and it's not caught by the current method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
  bool exception_exit = state->is_exception_detected() && !state->is_exception_caught();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
  if (state->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    Handle result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    jvalue value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    value.j = 0L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    // if the method hasn't been popped because of an exception then we populate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    // the return_value parameter for the callback. At this point we only have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
    // the address of a "raw result" and we just call into the interpreter to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
    // convert this into a jvalue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    if (!exception_exit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
      oop oop_result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
      BasicType type = current_frame.interpreter_frame_result(&oop_result, &value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
      if (type == T_OBJECT || type == T_ARRAY) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
        result = Handle(thread, oop_result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
      if (ets->is_enabled(JVMTI_EVENT_METHOD_EXIT)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
        EVT_TRACE(JVMTI_EVENT_METHOD_EXIT, ("JVMTI [%s] Evt Method Exit sent %s.%s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
                                            JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
                                            (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
                                            (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
        JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
        JvmtiMethodEventMark jem(thread, mh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
        if (result.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
          value.l = JNIHandles::make_local(thread, result());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
        jvmtiEventMethodExit callback = env->callbacks()->MethodExit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
          (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
                      jem.jni_methodID(), exception_exit,  value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
  if (state->is_enabled(JVMTI_EVENT_FRAME_POP)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
    JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
      int cur_frame_number = state->cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
      if (ets->is_frame_pop(cur_frame_number)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
        // we have a NotifyFramePop entry for this frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
        // now check that this env/thread wants this event
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
        if (ets->is_enabled(JVMTI_EVENT_FRAME_POP)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
          EVT_TRACE(JVMTI_EVENT_FRAME_POP, ("JVMTI [%s] Evt Frame Pop sent %s.%s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
                                            JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
                                            (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
                                            (mh() == NULL) ? "NULL" : mh()->name()->as_C_string() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
          // we also need to issue a frame pop event for this frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
          JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
          JvmtiMethodEventMark jem(thread, mh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
          JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
          jvmtiEventFramePop callback = env->callbacks()->FramePop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
          if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
            (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
                        jem.jni_methodID(), exception_exit);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
        // remove the frame's entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
        ets->clear_frame_pop(cur_frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  state->decr_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
// Todo: inline this for optimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
void JvmtiExport::post_single_step(JavaThread *thread, methodOop method, address location) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
    ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_SINGLE_STEP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
    if (!ets->single_stepping_posted() && ets->is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
      EVT_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Evt Single Step sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
                    JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
                    (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
                    (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
                    location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
      JvmtiLocationEventMark jem(thread, mh, location);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
      jvmtiEventSingleStep callback = env->callbacks()->SingleStep;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
                    jem.jni_methodID(), jem.location());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
      ets->set_single_stepping_posted();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
void JvmtiExport::post_exception_throw(JavaThread *thread, methodOop method, address location, oop exception) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  Handle exception_handle(thread, exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
  EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION, ("JVMTI [%s] Trg Exception thrown triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
  if (!state->is_exception_detected()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    state->set_exception_detected();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
    for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
      if (ets->is_enabled(JVMTI_EVENT_EXCEPTION) && (exception != NULL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
        EVT_TRACE(JVMTI_EVENT_EXCEPTION,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
                     ("JVMTI [%s] Evt Exception thrown sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
                      JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
                      (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
                      (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
                      location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
        JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
        JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
        // It's okay to clear these exceptions here because we duplicate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
        // this lookup in InterpreterRuntime::exception_handler_for_exception.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
        EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
        bool should_repeat;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
        vframeStream st(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
        assert(!st.at_end(), "cannot be at end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
        methodOop current_method = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
        int current_bci = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
        do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
          current_method = st.method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
          current_bci = st.bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
          do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
            should_repeat = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
            KlassHandle eh_klass(thread, exception_handle()->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
            current_bci = current_method->fast_exception_handler_bci_for(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
              eh_klass, current_bci, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
            if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
              exception_handle = KlassHandle(thread, PENDING_EXCEPTION);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
              CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
              should_repeat = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
          } while (should_repeat && (current_bci != -1));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
          st.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
        } while ((current_bci < 0) && (!st.at_end()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
        jmethodID catch_jmethodID;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
        if (current_bci < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
          catch_jmethodID = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
          current_bci = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
          catch_jmethodID = jem.to_jmethodID(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
                                     methodHandle(thread, current_method));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
        jvmtiEventException callback = env->callbacks()->Exception;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
          (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
                      jem.jni_methodID(), jem.location(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
                      jem.exception(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
                      catch_jmethodID, current_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  // frames may get popped because of this throw, be safe - invalidate cached depth
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  state->invalidate_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
void JvmtiExport::notice_unwind_due_to_exception(JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  Handle exception_handle(thread, exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
  EVT_TRIG_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
                    ("JVMTI [%s] Trg unwind_due_to_exception triggered %s.%s @ %s%d - %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
                     JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
                     location==0? "no location:" : "",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
                     location==0? 0 : location - mh()->code_base(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
                     in_handler_frame? "in handler frame" : "not handler frame" ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  if (state->is_exception_detected()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
    state->invalidate_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
    if (!in_handler_frame) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
      // Not in exception handler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
      if(state->is_interp_only_mode()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
        // method exit and frame pop events are posted only in interp mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
        // When these events are enabled code should be in running in interp mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
        JvmtiExport::post_method_exit(thread, method, thread->last_frame());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
        // The cached cur_stack_depth might have changed from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
        // operations of frame pop or method exit. We are not 100% sure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
        // the cached cur_stack_depth is still valid depth so invalidate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
        // it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
        state->invalidate_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
      // In exception handler frame. Report exception catch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
      assert(location != NULL, "must be a known location");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
      // Update cur_stack_depth - the frames above the current frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
      // have been unwound due to this exception:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
      assert(!state->is_exception_caught(), "exception must not be caught yet.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
      state->set_exception_caught();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
      JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
      for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
        if (ets->is_enabled(JVMTI_EVENT_EXCEPTION_CATCH) && (exception_handle() != NULL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
          EVT_TRACE(JVMTI_EVENT_EXCEPTION_CATCH,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
                     ("JVMTI [%s] Evt ExceptionCatch sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
                      JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
                      (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
                      (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
                      location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
          JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
          JvmtiExceptionEventMark jem(thread, mh, location, exception_handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
          JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
          jvmtiEventExceptionCatch callback = env->callbacks()->ExceptionCatch;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
          if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
            (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
                      jem.jni_methodID(), jem.location(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
                      jem.exception());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
oop JvmtiExport::jni_GetField_probe(JavaThread *thread, jobject jobj, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
                                    klassOop klass, jfieldID fieldID, bool is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
  if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
    // At least one field access watch is set so we have more work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
    // to do. This wrapper is used by entry points that allow us
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
    // to create handles in post_field_access_by_jni().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
    post_field_access_by_jni(thread, obj, klass, fieldID, is_static);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
    // event posting can block so refetch oop if we were passed a jobj
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
    if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
oop JvmtiExport::jni_GetField_probe_nh(JavaThread *thread, jobject jobj, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
                                       klassOop klass, jfieldID fieldID, bool is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
  if (*((int *)get_field_access_count_addr()) > 0 && thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
    // At least one field access watch is set so we have more work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    // to do. This wrapper is used by "quick" entry points that don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
    // allow us to create handles in post_field_access_by_jni(). We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
    // override that with a ResetNoHandleMark.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
    ResetNoHandleMark rnhm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
    post_field_access_by_jni(thread, obj, klass, fieldID, is_static);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
    // event posting can block so refetch oop if we were passed a jobj
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
void JvmtiExport::post_field_access_by_jni(JavaThread *thread, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
                                           klassOop klass, jfieldID fieldID, bool is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  // We must be called with a Java context in order to provide reasonable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
  // values for the klazz, method, and location fields. The callers of this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  // function don't make the call unless there is a Java context.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
  assert(thread->has_last_Java_frame(), "must be called with a Java context");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  fieldDescriptor fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
  // if get_field_descriptor finds fieldID to be invalid, then we just bail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
  bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
  assert(valid_fieldID == true,"post_field_access_by_jni called with invalid fieldID");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
  if (!valid_fieldID) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
  // field accesses are not watched so bail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
  if (!fd.is_field_access_watched()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
  KlassHandle h_klass(thread, klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
  Handle h_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
  if (!is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
    // non-static field accessors have an object, but we need a handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
    assert(obj != NULL, "non-static needs an object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
    h_obj = Handle(thread, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
  post_field_access(thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
                    thread->last_frame().interpreter_frame_method(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
                    thread->last_frame().interpreter_frame_bcp(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
                    h_klass, h_obj, fieldID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
void JvmtiExport::post_field_access(JavaThread *thread, methodOop method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
  address location, KlassHandle field_klass, Handle object, jfieldID field) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Trg Field Access event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
    if (ets->is_enabled(JVMTI_EVENT_FIELD_ACCESS)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
      EVT_TRACE(JVMTI_EVENT_FIELD_ACCESS, ("JVMTI [%s] Evt Field Access event sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
                     JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
                     (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
                     (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
                     location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
      JvmtiLocationEventMark jem(thread, mh, location);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
      jclass field_jclass = jem.to_jclass(field_klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
      jobject field_jobject = jem.to_jobject(object());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
      jvmtiEventFieldAccess callback = env->callbacks()->FieldAccess;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
                    jem.jni_methodID(), jem.location(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
                    field_jclass, field_jobject, field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
oop JvmtiExport::jni_SetField_probe(JavaThread *thread, jobject jobj, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
                                    klassOop klass, jfieldID fieldID, bool is_static,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
                                    char sig_type, jvalue *value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
  if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
    // At least one field modification watch is set so we have more work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
    // to do. This wrapper is used by entry points that allow us
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    // to create handles in post_field_modification_by_jni().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
    post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
    // event posting can block so refetch oop if we were passed a jobj
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
    if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
oop JvmtiExport::jni_SetField_probe_nh(JavaThread *thread, jobject jobj, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
                                       klassOop klass, jfieldID fieldID, bool is_static,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
                                       char sig_type, jvalue *value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  if (*((int *)get_field_modification_count_addr()) > 0 && thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
    // At least one field modification watch is set so we have more work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    // to do. This wrapper is used by "quick" entry points that don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
    // allow us to create handles in post_field_modification_by_jni(). We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    // override that with a ResetNoHandleMark.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    ResetNoHandleMark rnhm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    post_field_modification_by_jni(thread, obj, klass, fieldID, is_static, sig_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
    // event posting can block so refetch oop if we were passed a jobj
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    if (jobj != NULL) return JNIHandles::resolve_non_null(jobj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  return obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
void JvmtiExport::post_field_modification_by_jni(JavaThread *thread, oop obj,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
                                                 klassOop klass, jfieldID fieldID, bool is_static,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
                                                 char sig_type, jvalue *value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  // We must be called with a Java context in order to provide reasonable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  // values for the klazz, method, and location fields. The callers of this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  // function don't make the call unless there is a Java context.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  assert(thread->has_last_Java_frame(), "must be called with Java context");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
  fieldDescriptor fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
  // if get_field_descriptor finds fieldID to be invalid, then we just bail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  bool valid_fieldID = JvmtiEnv::get_field_descriptor(klass, fieldID, &fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
  assert(valid_fieldID == true,"post_field_modification_by_jni called with invalid fieldID");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
  if (!valid_fieldID) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
  // field modifications are not watched so bail
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
  if (!fd.is_field_modification_watched()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  Handle h_obj;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
  if (!is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
    // non-static field accessors have an object, but we need a handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
    assert(obj != NULL, "non-static needs an object");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
    h_obj = Handle(thread, obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
  KlassHandle h_klass(thread, klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
  post_field_modification(thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
                          thread->last_frame().interpreter_frame_method(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
                          thread->last_frame().interpreter_frame_bcp(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
                          h_klass, h_obj, fieldID, sig_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
void JvmtiExport::post_raw_field_modification(JavaThread *thread, methodOop method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  address location, KlassHandle field_klass, Handle object, jfieldID field,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  char sig_type, jvalue *value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  if (sig_type == 'I' || sig_type == 'Z' || sig_type == 'C' || sig_type == 'S') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
    // 'I' instructions are used for byte, char, short and int.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
    // determine which it really is, and convert
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
    fieldDescriptor fd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
    bool found = JvmtiEnv::get_field_descriptor(field_klass(), field, &fd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
    // should be found (if not, leave as is)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
    if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
      jint ival = value->i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
      // convert value from int to appropriate type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
      switch (fd.field_type()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
      case T_BOOLEAN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
        sig_type = 'Z';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
        value->i = 0; // clear it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
        value->z = (jboolean)ival;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
      case T_BYTE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
        sig_type = 'B';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
        value->i = 0; // clear it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
        value->b = (jbyte)ival;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
      case T_CHAR:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
        sig_type = 'C';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
        value->i = 0; // clear it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
        value->c = (jchar)ival;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
      case T_SHORT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
        sig_type = 'S';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
        value->i = 0; // clear it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
        value->s = (jshort)ival;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
      case T_INT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
        // nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
        // this is an integer instruction, should be one of above
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
        ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
  // convert oop to JNI handle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
  if (sig_type == 'L' || sig_type == '[') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
    value->l = (jobject)JNIHandles::make_local(thread, (oop)value->l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
  post_field_modification(thread, method, location, field_klass, object, field, sig_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
  // Destroy the JNI handle allocated above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
  if (sig_type == 'L') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
    JNIHandles::destroy_local(value->l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
void JvmtiExport::post_field_modification(JavaThread *thread, methodOop method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
  address location, KlassHandle field_klass, Handle object, jfieldID field,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
  char sig_type, jvalue *value_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  EVT_TRIG_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
                     ("JVMTI [%s] Trg Field Modification event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
    if (ets->is_enabled(JVMTI_EVENT_FIELD_MODIFICATION)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
      EVT_TRACE(JVMTI_EVENT_FIELD_MODIFICATION,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
                   ("JVMTI [%s] Evt Field Modification event sent %s.%s @ %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
                    JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
                    (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
                    (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
                    location - mh()->code_base() ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
      JvmtiLocationEventMark jem(thread, mh, location);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
      jclass field_jclass = jem.to_jclass(field_klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
      jobject field_jobject = jem.to_jobject(object());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
      jvmtiEventFieldModification callback = env->callbacks()->FieldModification;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
                    jem.jni_methodID(), jem.location(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
                    field_jclass, field_jobject, field, sig_type, *value_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
void JvmtiExport::post_native_method_bind(methodOop method, address* function_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
  assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
  methodHandle mh(thread, method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  EVT_TRIG_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Trg Native Method Bind event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
  if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
    JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
    for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
      if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
        EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
                     JvmtiTrace::safe_get_thread_name(thread) ));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
        JvmtiMethodEventMark jem(thread, mh);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
        JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
        JNIEnv* jni_env =  JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
        jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
        if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
          (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
                      jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
void JvmtiExport::post_compiled_method_load(nmethod *nm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
  // If there are pending CompiledMethodUnload events then these are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  // posted before this CompiledMethodLoad event. We "lock" the nmethod and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  // maintain a handle to the methodOop to ensure that the nmethod isn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  // flushed or unloaded while posting the events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
  if (have_pending_compiled_method_unload_events()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
    methodHandle mh(thread, nm->method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
    nmethodLocker nml(nm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
    post_pending_compiled_method_unload_events();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
  EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
                 ("JVMTI [%s] method compile load event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
    if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
      EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
                ("JVMTI [%s] class compile method load event sent %s.%s  ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
                JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
                (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
                (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
      ResourceMark rm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
      JvmtiCompiledMethodLoadEventMark jem(thread, nm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
      jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
        (*callback)(env->jvmti_external(), jem.jni_methodID(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
                    jem.code_size(), jem.code_data(), jem.map_length(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
                    jem.map(), jem.compile_info());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
// post a COMPILED_METHOD_LOAD event for a given environment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
                                            const void *code_begin, const jint map_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
                                            const jvmtiAddrLocationMap* map)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
                 ("JVMTI [%s] method compile load event triggered (by GenerateEvents)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
  if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
    EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
              ("JVMTI [%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
              JvmtiTrace::safe_get_thread_name(thread), method));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
    JvmtiEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
    JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
    jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
    if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
      (*callback)(env->jvmti_external(), method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
                  length, code_begin, map_length,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
                  map, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
// used at a safepoint to post a CompiledMethodUnload event
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
void JvmtiExport::post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
  // create list lazily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  if (_pending_compiled_method_unload_method_ids == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
    _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  _pending_compiled_method_unload_method_ids->append(mid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
  _pending_compiled_method_unload_code_begins->append(code_begin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  _have_pending_compiled_method_unload_events = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
  EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
                 ("JVMTI [%s] method dynamic code generated event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
    if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
      EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
                ("JVMTI [%s] dynamic code generated event sent for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
                JvmtiTrace::safe_get_thread_name(thread), name));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
      JvmtiEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
      jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
      jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
        (*callback)(env->jvmti_external(), name, (void*)code_begin, length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  // In theory everyone coming thru here is in_vm but we need to be certain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
  // because a callee will do a vm->native transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
  ThreadInVMfromUnknown __tiv;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
  jvmtiPhase phase = JvmtiEnv::get_phase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
  if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
    post_dynamic_code_generated_internal(name, code_begin, code_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  if (have_pending_compiled_method_unload_events()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
    post_pending_compiled_method_unload_events();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
  post_dynamic_code_generated_internal(name, code_begin, code_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
// post a DYNAMIC_CODE_GENERATED event for a given environment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
// used by GenerateEvents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
void JvmtiExport::post_dynamic_code_generated(JvmtiEnv* env, const char *name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
                                              const void *code_begin, const void *code_end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
                 ("JVMTI [%s] dynamic code generated event triggered (by GenerateEvents)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
                  JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
  if (env->is_enabled(JVMTI_EVENT_DYNAMIC_CODE_GENERATED)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
    EVT_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
              ("JVMTI [%s] dynamic code generated event sent for %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
               JvmtiTrace::safe_get_thread_name(thread), name));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
    JvmtiEventMark jem(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
    JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
    jint length = (jint)pointer_delta(code_end, code_begin, sizeof(char));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
    jvmtiEventDynamicCodeGenerated callback = env->callbacks()->DynamicCodeGenerated;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
    if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
      (*callback)(env->jvmti_external(), name, (void*)code_begin, length);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
// post a DynamicCodeGenerated event while holding locks in the VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* name,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
                                                                  address code_begin, address code_end)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
  // register the stub with the current dynamic code event collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  1875
  // state can only be NULL if the current thread is exiting which
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  1876
  // should not happen since we're trying to post an event
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  1877
  guarantee(state != NULL, "attempt to register stub via an exiting thread");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
  JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  guarantee(collector != NULL, "attempt to register stub without event collector");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
  collector->register_stub(name, code_begin, code_end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1881
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
// Collect all the vm internally allocated objects which are visible to java world
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
void JvmtiExport::record_vm_internal_object_allocation(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
  Thread* thread = ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
  if (thread != NULL && thread->is_Java_thread())  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
    // Can not take safepoint here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
    No_Safepoint_Verifier no_sfpt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
    // Can not take safepoint here so can not use state_for to get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
    // jvmti thread state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
    JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
    if (state != NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
      // state is non NULL when VMObjectAllocEventCollector is enabled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
      JvmtiVMObjectAllocEventCollector *collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
      collector = state->get_vm_object_alloc_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
      if (collector != NULL && collector->is_enabled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
        // Don't record classes as these will be notified via the ClassLoad
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
        // event.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
        if (obj->klass() != SystemDictionary::class_klass()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
          collector->record_allocation(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
void JvmtiExport::post_garbage_collection_finish() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  Thread *thread = Thread::current(); // this event is posted from VM-Thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
                 ("JVMTI [%s] garbage collection finish event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
                  JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
    if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
      EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_FINISH,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
                ("JVMTI [%s] garbage collection finish event sent ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
      // JNIEnv is NULL here because this event is posted from VM Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
      jvmtiEventGarbageCollectionFinish callback = env->callbacks()->GarbageCollectionFinish;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
        (*callback)(env->jvmti_external());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
void JvmtiExport::post_garbage_collection_start() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  Thread* thread = Thread::current(); // this event is posted from vm-thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  EVT_TRIG_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
                 ("JVMTI [%s] garbage collection start event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
                  JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
    if (env->is_enabled(JVMTI_EVENT_GARBAGE_COLLECTION_START)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
      EVT_TRACE(JVMTI_EVENT_GARBAGE_COLLECTION_START,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
                ("JVMTI [%s] garbage collection start event sent ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
      // JNIEnv is NULL here because this event is posted from VM Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
      jvmtiEventGarbageCollectionStart callback = env->callbacks()->GarbageCollectionStart;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
        (*callback)(env->jvmti_external());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
void JvmtiExport::post_data_dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
  Thread *thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
  EVT_TRIG_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
                 ("JVMTI [%s] data dump request event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
                  JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    if (env->is_enabled(JVMTI_EVENT_DATA_DUMP_REQUEST)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
      EVT_TRACE(JVMTI_EVENT_DATA_DUMP_REQUEST,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
                ("JVMTI [%s] data dump request event sent ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
                 JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
     JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
     // JNIEnv is NULL here because this event is posted from VM Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
     jvmtiEventDataDumpRequest callback = env->callbacks()->DataDumpRequest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
     if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
       (*callback)(env->jvmti_external());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  oop object = (oop)obj_mntr->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
  if (!ServiceUtil::visible_oop(object)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
    // Ignore monitor contended enter for vm internal object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  Handle h(thread, object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
  EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
                     ("JVMTI [%s] montior contended enter event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
    if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTER)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
      EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTER,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1992
                   ("JVMTI [%s] monitor contended enter event sent",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
                    JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
      JvmtiMonitorEventMark  jem(thread, h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
      jvmtiEventMonitorContendedEnter callback = env->callbacks()->MonitorContendedEnter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  oop object = (oop)obj_mntr->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
  if (!ServiceUtil::visible_oop(object)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
    // Ignore monitor contended entered for vm internal object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
  Handle h(thread, object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
                     ("JVMTI [%s] montior contended entered event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    if (ets->is_enabled(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
      EVT_TRACE(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
                   ("JVMTI [%s] monitor contended enter event sent",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
                    JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
      JvmtiMonitorEventMark  jem(thread, h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
      jvmtiEventMonitorContendedEntered callback = env->callbacks()->MonitorContendedEntered;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), jem.jni_object());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
                                          jlong timeout) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
  Handle h(thread, object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
  EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAIT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
                     ("JVMTI [%s] montior wait event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
    if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAIT)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
      EVT_TRACE(JVMTI_EVENT_MONITOR_WAIT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
                   ("JVMTI [%s] monitor wait event sent ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
                    JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
      JvmtiMonitorEventMark  jem(thread, h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
      jvmtiEventMonitorWait callback = env->callbacks()->MonitorWait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
                    jem.jni_object(), timeout);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
  oop object = (oop)obj_mntr->object();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
  if (!ServiceUtil::visible_oop(object)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
    // Ignore monitor waited for vm internal object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
  JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
  if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
  Handle h(thread, object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  EVT_TRIG_TRACE(JVMTI_EVENT_MONITOR_WAITED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
                     ("JVMTI [%s] montior waited event triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
  JvmtiEnvThreadStateIterator it(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
  for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
    if (ets->is_enabled(JVMTI_EVENT_MONITOR_WAITED)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
      EVT_TRACE(JVMTI_EVENT_MONITOR_WAITED,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
                   ("JVMTI [%s] monitor waited event sent ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
                    JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
      JvmtiMonitorEventMark  jem(thread, h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
      JvmtiEnv *env = ets->get_env();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
      JvmtiThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
      jvmtiEventMonitorWaited callback = env->callbacks()->MonitorWaited;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
                    jem.jni_object(), timed_out);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
void JvmtiExport::post_vm_object_alloc(JavaThread *thread,  oop object) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  EVT_TRIG_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Trg vm object alloc triggered",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
                      JvmtiTrace::safe_get_thread_name(thread)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  if (object == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
  HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  Handle h(thread, object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
  JvmtiEnvIterator it;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
  for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
    if (env->is_enabled(JVMTI_EVENT_VM_OBJECT_ALLOC)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
      EVT_TRACE(JVMTI_EVENT_VM_OBJECT_ALLOC, ("JVMTI [%s] Evt vmobject alloc sent %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
                                         JvmtiTrace::safe_get_thread_name(thread),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
                                         object==NULL? "NULL" : Klass::cast(java_lang_Class::as_klassOop(object))->external_name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
      JvmtiVMObjectAllocEventMark jem(thread, h());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
      JvmtiJavaThreadEventTransition jet(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
      jvmtiEventVMObjectAlloc callback = env->callbacks()->VMObjectAlloc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
      if (callback != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
        (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
                    jem.jni_jobject(), jem.jni_class(), jem.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
////////////////////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
void JvmtiExport::cleanup_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
  assert(JavaThread::current() == thread, "thread is not current");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
  // This has to happen after the thread state is removed, which is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
  // why it is not in post_thread_end_event like its complement
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
  // Maybe both these functions should be rolled into the posts?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
  JvmtiEventController::thread_ended(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
void JvmtiExport::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
  JvmtiCurrentBreakpoints::oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
  JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
// Onload raw monitor transition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
void JvmtiExport::transition_pending_onload_raw_monitors() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
  JvmtiPendingMonitors::transition_raw_monitors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
////////////////////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
// type for the Agent_OnAttach entry point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
  typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
#ifndef SERVICES_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
  char ebuf[1024];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
  char buffer[JVM_MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
  void* library;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
  jint result = JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
  // get agent name and options
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
  const char* agent = op->arg(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
  const char* absParam = op->arg(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
  const char* options = op->arg(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
  // The abs paramter should be "true" or "false"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
  bool is_absolute_path = (absParam != NULL) && (strcmp(absParam,"true")==0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
  // If the path is absolute we attempt to load the library. Otherwise we try to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
  // load it from the standard dll directory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
  if (is_absolute_path) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
    library = hpi::dll_load(agent, ebuf, sizeof ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
    // Try to load the agent from the standard dll directory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
    hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
    library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
    if (library == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
      // not found - try local path
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
      char ns[1] = {0};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
      hpi::dll_build_name(buffer, sizeof(buffer), ns, agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
      library = hpi::dll_load(buffer, ebuf, sizeof ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
  // If the library was loaded then we attempt to invoke the Agent_OnAttach
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
  // function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
  if (library != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    // Lookup the Agent_OnAttach function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
    OnAttachEntry_t on_attach_entry = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
    const char *on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_attach_symbols); symbol_index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
      on_attach_entry =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
        CAST_TO_FN_PTR(OnAttachEntry_t, hpi::dll_lookup(library, on_attach_symbols[symbol_index]));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
      if (on_attach_entry != NULL) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    if (on_attach_entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
      // Agent_OnAttach missing - unload library
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
      hpi::dll_unload(library);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
      // Invoke the Agent_OnAttach function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
      JavaThread* THREAD = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
        extern struct JavaVM_ main_vm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
        JvmtiThreadEventMark jem(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
        JvmtiJavaThreadEventTransition jet(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
        result = (*on_attach_entry)(&main_vm, (char*)options, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
      // Agent_OnAttach may have used JNI
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
      if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
        CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
      // If OnAttach returns JNI_OK then we add it to the list of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
      // agent libraries so that we can call Agent_OnUnload later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
      if (result == JNI_OK) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
        Arguments::add_loaded_agent(agent, (char*)options, is_absolute_path, library);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
      // Agent_OnAttach executed so completion status is JNI_OK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
      st->print_cr("%d", result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
      result = JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
#endif // SERVICES_KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
// CMS has completed referencing processing so may need to update
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
// tag maps.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
void JvmtiExport::cms_ref_processing_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
  if (JvmtiEnv::environments_might_exist()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
    JvmtiTagMap::cms_ref_processing_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
////////////////////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
// Setup current current thread for event collection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
void JvmtiEventCollector::setup_jvmti_thread_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
  // set this event collector to be the current one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  2259
  // state can only be NULL if the current thread is exiting which
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  2260
  // should not happen since we're trying to configure for event collection
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 1374
diff changeset
  2261
  guarantee(state != NULL, "exiting thread called setup_jvmti_thread_state");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  if (is_vm_object_alloc_event()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
    _prev = state->get_vm_object_alloc_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
    state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
  } else if (is_dynamic_code_event()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
    _prev = state->get_dynamic_code_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
    state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
// Unset current event collection in this thread and reset it with previous
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
// collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
void JvmtiEventCollector::unset_jvmti_thread_state() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
  if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
    // restore the previous event collector (if any)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
    if (is_vm_object_alloc_event()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
      if (state->get_vm_object_alloc_event_collector() == this) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
        state->set_vm_object_alloc_event_collector((JvmtiVMObjectAllocEventCollector *)_prev);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
        // this thread's jvmti state was created during the scope of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
        // the event collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
      if (is_dynamic_code_event()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
        if (state->get_dynamic_code_event_collector() == this) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
          state->set_dynamic_code_event_collector((JvmtiDynamicCodeEventCollector *)_prev);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
          // this thread's jvmti state was created during the scope of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
          // the event collector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
// create the dynamic code event collector
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
JvmtiDynamicCodeEventCollector::JvmtiDynamicCodeEventCollector() : _code_blobs(NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
  if (JvmtiExport::should_post_dynamic_code_generated()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
    setup_jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
// iterate over any code blob descriptors collected and post a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
// DYNAMIC_CODE_GENERATED event to the profiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
 // iterate over any code blob descriptors that we collected
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
 if (_code_blobs != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
   for (int i=0; i<_code_blobs->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
     JvmtiCodeBlobDesc* blob = _code_blobs->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
     JvmtiExport::post_dynamic_code_generated(blob->name(), blob->code_begin(), blob->code_end());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
     FreeHeap(blob);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
   delete _code_blobs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
 }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
 unset_jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
// register a stub
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
 if (_code_blobs == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
   _code_blobs = new (ResourceObj::C_HEAP) GrowableArray<JvmtiCodeBlobDesc*>(1,true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
 }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
 _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
// Setup current thread to record vm allocated objects.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
JvmtiVMObjectAllocEventCollector::JvmtiVMObjectAllocEventCollector() : _allocated(NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
  if (JvmtiExport::should_post_vm_object_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
    _enable = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
    setup_jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
    _enable = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
// Post vm_object_alloc event for vm allocated objects visible to java
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
// world.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
JvmtiVMObjectAllocEventCollector::~JvmtiVMObjectAllocEventCollector() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
  if (_allocated != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
    set_enabled(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
    for (int i = 0; i < _allocated->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
      oop obj = _allocated->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
      if (ServiceUtil::visible_oop(obj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
        JvmtiExport::post_vm_object_alloc(JavaThread::current(), obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
    delete _allocated;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
  unset_jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  assert(is_enabled(), "VM object alloc event collector is not enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
  if (_allocated == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
    _allocated = new (ResourceObj::C_HEAP) GrowableArray<oop>(1, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
  _allocated->push(obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
// GC support.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
void JvmtiVMObjectAllocEventCollector::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
  if (_allocated != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
    for(int i=_allocated->length() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      if (_allocated->at(i) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
        f->do_oop(_allocated->adr_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
void JvmtiVMObjectAllocEventCollector::oops_do_for_all_threads(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
  // no-op if jvmti not enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
  if (!JvmtiEnv::environments_might_exist()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
  // Runs at safepoint. So no need to acquire Threads_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
  for (JavaThread *jthr = Threads::first(); jthr != NULL; jthr = jthr->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
    JvmtiThreadState *state = jthr->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
    if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
      JvmtiVMObjectAllocEventCollector *collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
      collector = state->get_vm_object_alloc_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
      while (collector != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
        collector->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
        collector = (JvmtiVMObjectAllocEventCollector *)collector->get_prev();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
// Disable collection of VMObjectAlloc events
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
  // a no-op if VMObjectAlloc event is not enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
  if (!JvmtiExport::should_post_vm_object_alloc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
  Thread* thread = ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
  if (thread != NULL && thread->is_Java_thread())  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
    JavaThread* current_thread = (JavaThread*)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
    JvmtiThreadState *state = current_thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
    if (state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
      JvmtiVMObjectAllocEventCollector *collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
      collector = state->get_vm_object_alloc_event_collector();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
      if (collector != NULL && collector->is_enabled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
        _collector = collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
        _collector->set_enabled(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
// Re-Enable collection of VMObjectAlloc events (if previously enabled)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
NoJvmtiVMObjectAllocMark::~NoJvmtiVMObjectAllocMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
  if (was_enabled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
    _collector->set_enabled(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
JvmtiGCMarker::JvmtiGCMarker(bool full) : _full(full), _invocation_count(0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
  assert(Thread::current()->is_VM_thread(), "wrong thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
  // if there aren't any JVMTI environments then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
  if (!JvmtiEnv::environments_might_exist()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
3580
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
  2430
  if (ForceFullGCJVMTIEpilogues) {
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
  2431
    // force 'Full GC' was done semantics for JVMTI GC epilogues
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
  2432
    _full = true;
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
  2433
  }
55775b48f5e5 6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents: 1374
diff changeset
  2434
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
  // GarbageCollectionStart event posted from VM thread - okay because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
  // JVMTI is clear that the "world is stopped" and callback shouldn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
  // try to call into the VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
  if (JvmtiExport::should_post_garbage_collection_start()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
    JvmtiExport::post_garbage_collection_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  // if "full" is false it probably means this is a scavenge of the young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
  // generation. However it could turn out that a "full" GC is required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
  // so we record the number of collections so that it can be checked in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
  // the destructor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
  if (!_full) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
  2447
    _invocation_count = Universe::heap()->total_full_collections();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
  // Do clean up tasks that need to be done at a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
  JvmtiEnvBase::check_for_periodic_clean_up();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
JvmtiGCMarker::~JvmtiGCMarker() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
  // if there aren't any JVMTI environments then nothing to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
  if (!JvmtiEnv::environments_might_exist()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
  // JVMTI notify gc finish
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
  if (JvmtiExport::should_post_garbage_collection_finish()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
    JvmtiExport::post_garbage_collection_finish();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
  // we might have initially started out doing a scavenge of the young
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
  // generation but could have ended up doing a "full" GC - check the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
  // GC count to see.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
  if (!_full) {
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 1
diff changeset
  2469
    _full = (_invocation_count != Universe::heap()->total_full_collections());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
  // Full collection probably means the perm generation has been GC'ed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
  // so we clear the breakpoint cache.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
  if (_full) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
    JvmtiCurrentBreakpoints::gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
  // Notify heap/object tagging support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
  JvmtiTagMap::gc_epilogue(_full);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
#endif // JVMTI_KERNEL