hotspot/src/share/vm/prims/jvmtiThreadState.hpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 2135 f82c3012ec86
child 4761 bdb7375a1fee
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-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
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 2134
diff changeset
   317
  // Can return NULL if JavaThread is exiting.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  inline static JvmtiThreadState *state_for_while_locked(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    assert(JvmtiThreadState_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    if (state == NULL) {
2134
125f0fb7e9b1 6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents: 1
diff changeset
   323
      if (thread->is_exiting()) {
125f0fb7e9b1 6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents: 1
diff changeset
   324
        // don't add a JvmtiThreadState to a thread that is exiting
125f0fb7e9b1 6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents: 1
diff changeset
   325
        return NULL;
125f0fb7e9b1 6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents: 1
diff changeset
   326
      }
125f0fb7e9b1 6700114: 3/4 Assertion (_thread->get_interp_only_mode() == 1,"leaving interp only when mode not one")
dcubed
parents: 1
diff changeset
   327
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      state = new JvmtiThreadState(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // retrieve or create JvmtiThreadState
2135
f82c3012ec86 6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents: 2134
diff changeset
   334
  // Can return NULL if JavaThread is exiting.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  inline static JvmtiThreadState *state_for(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    JvmtiThreadState *state = thread->jvmti_thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    if (state == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
      MutexLocker mu(JvmtiThreadState_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
      // check again with the lock held
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
      state = state_for_while_locked(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
    return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // JVMTI ForceEarlyReturn support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  // This is set to earlyret_pending to signal that top Java frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  // should be returned immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  int           _earlyret_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  TosState      _earlyret_tos;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  jvalue        _earlyret_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  oop           _earlyret_oop;         // Used to return an oop result into Java code from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
                                       // ForceEarlyReturnObject, GC-preserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  // Setting and clearing earlyret_state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  // earlyret_pending indicates that a ForceEarlyReturn() has been
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  // requested and not yet been completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  enum EarlyretState {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    earlyret_inactive = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    earlyret_pending  = 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  void set_earlyret_pending(void) { _earlyret_state = earlyret_pending;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  void clr_earlyret_pending(void) { _earlyret_state = earlyret_inactive; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  bool is_earlyret_pending(void)  { return (_earlyret_state == earlyret_pending);  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  TosState earlyret_tos()                            { return _earlyret_tos; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  oop  earlyret_oop() const                          { return _earlyret_oop; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  void set_earlyret_oop (oop x)                      { _earlyret_oop = x;    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  jvalue earlyret_value()                            { return _earlyret_value; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  void set_earlyret_value(jvalue val, TosState tos)  { _earlyret_tos = tos;  _earlyret_value = val;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  void clr_earlyret_value()                          { _earlyret_tos = ilgl; _earlyret_value.j = 0L; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  static ByteSize earlyret_state_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_state); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  static ByteSize earlyret_tos_offset()   { return byte_offset_of(JvmtiThreadState, _earlyret_tos); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  static ByteSize earlyret_oop_offset()   { return byte_offset_of(JvmtiThreadState, _earlyret_oop); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  static ByteSize earlyret_value_offset() { return byte_offset_of(JvmtiThreadState, _earlyret_value); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  void oops_do(OopClosure* f); // GC support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
class RedefineVerifyMark : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  JvmtiThreadState *_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  RedefineVerifyMark(KlassHandle *the_class, KlassHandle *scratch_class,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
                     JvmtiThreadState *state) : _state(state)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    _state->set_class_versions_map(the_class, scratch_class);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
    (*scratch_class)->set_java_mirror((*the_class)->java_mirror());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  ~RedefineVerifyMark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    _state->clear_class_versions_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
#endif   /* _JAVA_JVMTITHREADSTATE_H_ */