hotspot/src/share/vm/prims/jvmtiThreadState.hpp
author iveresov
Tue, 29 Apr 2008 13:51:26 +0400
changeset 388 bcc631c5bbec
parent 1 489c9b5090e2
child 2134 125f0fb7e9b1
permissions -rw-r--r--
6684395: Port NUMA-aware allocator to linux Summary: NUMA-aware allocator port to Linux Reviewed-by: jmasa, apetrusenko
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
#ifndef _JAVA_JVMTITHREADSTATE_H_
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
#define _JAVA_JVMTITHREADSTATE_H_
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
// Forward Declarations
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
class JvmtiEnvBase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
class JvmtiEnvThreadState;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
class JvmtiDynamicCodeEventCollector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
enum JvmtiClassLoadKind {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  jvmti_class_load_kind_load = 100,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  jvmti_class_load_kind_retransform,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  jvmti_class_load_kind_redefine
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
// class JvmtiEnvThreadStateIterator
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// The only safe means of iterating through the JvmtiEnvThreadStates
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// in a JvmtiThreadState.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// Note that this iteratation includes invalid environments pending
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
// deallocation -- in fact, some uses depend on this behavior.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
class JvmtiEnvThreadStateIterator : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  JvmtiThreadState* state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  JvmtiEnvThreadStateIterator(JvmtiThreadState* thread_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  ~JvmtiEnvThreadStateIterator();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  JvmtiEnvThreadState* first();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  JvmtiEnvThreadState* next(JvmtiEnvThreadState* ets);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
// class JvmtiThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
// The Jvmti state for each thread (across all JvmtiEnv):
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
// 1. Local table of enabled events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
class JvmtiThreadState : public CHeapObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  friend class JvmtiEnv;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  JavaThread        *_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  bool              _exception_detected;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  bool              _exception_caught;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  bool              _hide_single_stepping;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  bool              _pending_step_for_popframe;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  bool              _pending_step_for_earlyret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  int               _hide_level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  // Used to send class being redefined/retransformed and kind of transform
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // info to the class file load hook event handler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  KlassHandle           *_class_being_redefined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  JvmtiClassLoadKind    _class_load_kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  // This is only valid when is_interp_only_mode() returns true
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  int               _cur_stack_depth;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  JvmtiThreadEventEnable _thread_event_enable;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  // for support of JvmtiEnvThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  JvmtiEnvThreadState*   _head_env_thread_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  // doubly-linked linear list of active thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  // needed in order to iterate the list without holding Threads_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  static JvmtiThreadState *_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  JvmtiThreadState *_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  JvmtiThreadState *_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  // holds the current dynamic code event collector, NULL if no event collector in use
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  JvmtiDynamicCodeEventCollector* _dynamic_code_event_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  // holds the current vm object alloc event collector, NULL if no event collector in use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
  JvmtiVMObjectAllocEventCollector* _vm_object_alloc_event_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  // Should only be created by factory methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  JvmtiThreadState(JavaThread *thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  friend class JvmtiEnvThreadStateIterator;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  inline JvmtiEnvThreadState* head_env_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  inline void set_head_env_thread_state(JvmtiEnvThreadState* ets);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  ~JvmtiThreadState();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  // is event_type enabled and usable for this thread in any enviroments?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  bool is_enabled(jvmtiEvent event_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    return _thread_event_enable.is_enabled(event_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  JvmtiThreadEventEnable *thread_event_enable() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    return &_thread_event_enable;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // Must only be called in situations where the state is for the current thread and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  // the environment can not go away.  To be safe, the returned JvmtiEnvThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  // must be used in such a way as there can be no intervening safepoints.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  inline JvmtiEnvThreadState* env_thread_state(JvmtiEnvBase *env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  static void periodic_clean_up();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  void add_env(JvmtiEnvBase *env);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // Used by the interpreter for fullspeed debugging support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  bool is_interp_only_mode()                { return _thread->is_interp_only_mode(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  void enter_interp_only_mode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  void leave_interp_only_mode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  // access to the linked list of all JVMTI thread states
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  static JvmtiThreadState *first() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    assert(Threads::number_of_threads() == 0 || JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    return _head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  JvmtiThreadState *next()                  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    return _next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // Current stack depth is only valid when is_interp_only_mode() returns true.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  // These functions should only be called at a safepoint - usually called from same thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // Returns the number of Java activations on the stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  int cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  void invalidate_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  void incr_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  void decr_cur_stack_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  int count_frames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  inline JavaThread *get_thread()      { return _thread;              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  inline bool is_exception_detected()  { return _exception_detected;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  inline bool is_exception_caught()    { return _exception_caught;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  inline void set_exception_detected() { _exception_detected = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
                                         _exception_caught = false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  inline void set_exception_caught()   { _exception_caught = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
                                         _exception_detected = false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  inline void clear_hide_single_stepping() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    if (_hide_level > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
      _hide_level--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
      assert(_hide_single_stepping, "hide_single_stepping is out of phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
      _hide_single_stepping = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  inline bool hide_single_stepping() { return _hide_single_stepping; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  inline void set_hide_single_stepping() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    if (_hide_single_stepping) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
      _hide_level++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
      assert(_hide_level == 0, "hide_level is out of phase");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
      _hide_single_stepping = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // Step pending flag is set when PopFrame is called and it is cleared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // when step for the Pop Frame is completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  // This logic is used to distinguish b/w step for pop frame and repeat step.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  void set_pending_step_for_popframe() { _pending_step_for_popframe = true;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  void clr_pending_step_for_popframe() { _pending_step_for_popframe = false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  bool is_pending_step_for_popframe()  { return _pending_step_for_popframe;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  void process_pending_step_for_popframe();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  // Step pending flag is set when ForceEarlyReturn is called and it is cleared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  // when step for the ForceEarlyReturn is completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  // This logic is used to distinguish b/w step for early return and repeat step.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  void set_pending_step_for_earlyret() { _pending_step_for_earlyret = true;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  void clr_pending_step_for_earlyret() { _pending_step_for_earlyret = false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  bool is_pending_step_for_earlyret()  { return _pending_step_for_earlyret;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  void process_pending_step_for_earlyret();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  // Setter and getter method is used to send redefined class info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // when class file load hook event is posted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  // It is set while loading redefined class and cleared before the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // class file load hook event is posted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  inline void set_class_being_redefined(KlassHandle *h_class, JvmtiClassLoadKind kind) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    _class_being_redefined = h_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    _class_load_kind = kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  inline void clear_class_being_redefined() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    _class_being_redefined = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    _class_load_kind = jvmti_class_load_kind_load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  inline KlassHandle *get_class_being_redefined() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    return _class_being_redefined;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  inline JvmtiClassLoadKind get_class_load_kind() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    return _class_load_kind;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // RedefineClasses support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  // The bug 6214132 caused the verification to fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  // Below is the detailed description of the fix approach taken:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  // 1. What's done in RedefineClasses() before verification:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  //  a) A reference to the class being redefined (_the_class) and a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  //     reference to new version of the class (_scratch_class) are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  //     saved here for use during the bytecode verification phase of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  //     RedefineClasses. See RedefineVerifyMark for how these fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  //     are managed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  //   b) The _java_mirror field from _the_class is copied to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  //     _java_mirror field in _scratch_class. This means that a jclass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  //     returned for _the_class or _scratch_class will refer to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  //     same Java mirror. The verifier will see the "one true mirror"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  //     for the class being verified.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  // 2. What is done at verification:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  //   When the verifier makes calls into the VM to ask questions about
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  //   the class being verified, it will pass the jclass to JVM_* functions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  //   The jclass is always pointing to the mirror of _the_class.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  //   ~28 JVM_* functions called by the verifier for the information
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  //   about CP entries and klass structure should check the jvmtiThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  //   info about equivalent klass versions and use it to replace a klassOop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  //   of _the_class with a klassOop of _scratch_class. The function
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  //   class_to_verify_considering_redefinition() must be called for it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  //   Note again, that this redirection happens only for the verifier thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  //   Other threads have very small overhead by checking the existence
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  //   of the jvmtiThreadSate and the information about klasses equivalence.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  //   No JNI functions need to be changed, they don't reference the klass guts.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  //   The JavaThread pointer is already available in all JVM_* functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  //   used by the verifier, so there is no extra performance issue with it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  KlassHandle *_the_class_for_redefinition_verification;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  KlassHandle *_scratch_class_for_redefinition_verification;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  inline void set_class_versions_map(KlassHandle *the_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
                                     KlassHandle *scratch_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    _the_class_for_redefinition_verification = the_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    _scratch_class_for_redefinition_verification = scratch_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  inline void clear_class_versions_map() { set_class_versions_map(NULL, NULL); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  static inline
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  klassOop class_to_verify_considering_redefinition(klassOop klass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
                                                    JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
    if (state != NULL && state->_the_class_for_redefinition_verification != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      if ((*(state->_the_class_for_redefinition_verification))() == klass) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
        klass = (*(state->_scratch_class_for_redefinition_verification))();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    return klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // Todo: get rid of this!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  bool _debuggable;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  // Should the thread be enumerated by jvmtiInternal::GetAllThreads?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  bool is_debuggable()                 { return _debuggable; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  // If a thread cannot be suspended (has no valid last_java_frame) then it gets marked !debuggable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  void set_debuggable(bool debuggable) { _debuggable = debuggable; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  bool may_be_walked();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  // Thread local event collector setter and getter methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  JvmtiDynamicCodeEventCollector* get_dynamic_code_event_collector() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    return _dynamic_code_event_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  JvmtiVMObjectAllocEventCollector* get_vm_object_alloc_event_collector() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    return _vm_object_alloc_event_collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  void set_dynamic_code_event_collector(JvmtiDynamicCodeEventCollector* collector) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    _dynamic_code_event_collector = collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  void set_vm_object_alloc_event_collector(JvmtiVMObjectAllocEventCollector* collector) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    _vm_object_alloc_event_collector = collector;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  // Frame routines
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  //  true when the thread was suspended with a pointer to the last Java frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  bool has_last_frame()                     { return _thread->has_last_Java_frame(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  void update_for_pop_top_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  // already holding JvmtiThreadState_lock - retrieve or create JvmtiThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    assert(JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
      state = new JvmtiThreadState(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
    return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // retrieve or create JvmtiThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  inline static JvmtiThreadState *state_for(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
      MutexLocker mu(JvmtiThreadState_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
      // check again with the lock held
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
      state = state_for_while_locked(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // JVMTI ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  // This is set to earlyret_pending to signal that top Java frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  // should be returned immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  int           _earlyret_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  TosState      _earlyret_tos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  jvalue        _earlyret_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  oop           _earlyret_oop;         // Used to return an oop result into Java code from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
                                       // ForceEarlyReturnObject, GC-preserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  // Setting and clearing earlyret_state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  // earlyret_pending indicates that a ForceEarlyReturn() has been
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  // requested and not yet been completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  enum EarlyretState {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    earlyret_inactive = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    earlyret_pending  = 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  void set_earlyret_pending(void) { _earlyret_state = earlyret_pending;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  void clr_earlyret_pending(void) { _earlyret_state = earlyret_inactive; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  bool is_earlyret_pending(void)  { return (_earlyret_state == earlyret_pending);  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  TosState earlyret_tos()                            { return _earlyret_tos; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  oop  earlyret_oop() const                          { return _earlyret_oop; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  void set_earlyret_oop (oop x)                      { _earlyret_oop = x;    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  jvalue earlyret_value()                            { return _earlyret_value; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  void set_earlyret_value(jvalue val, TosState tos)  { _earlyret_tos = tos;  _earlyret_value = val;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  void clr_earlyret_value()                          { _earlyret_tos = ilgl; _earlyret_value.j = 0L; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  static ByteSize earlyret_state_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_state); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  static ByteSize earlyret_tos_offset()   { return byte_offset_of(JvmtiThreadState, _earlyret_tos); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  static ByteSize earlyret_oop_offset()   { return byte_offset_of(JvmtiThreadState, _earlyret_oop); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  static ByteSize earlyret_value_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_value); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  void oops_do(OopClosure* f); // GC support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
class RedefineVerifyMark : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  JvmtiThreadState *_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  RedefineVerifyMark(KlassHandle *the_class, KlassHandle *scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
                     JvmtiThreadState *state) : _state(state)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
    _state->set_class_versions_map(the_class, scratch_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    (*scratch_class)->set_java_mirror((*the_class)->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  ~RedefineVerifyMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    _state->clear_class_versions_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
#endif   /* _JAVA_JVMTITHREADSTATE_H_ */