hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
author ysr
Thu, 03 Dec 2009 15:01:57 -0800
changeset 4461 c17c526d36ef
parent 1 489c9b5090e2
child 5547 f4b087cbb361
permissions -rw-r--r--
6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-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
# include "incls/_precompiled.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
# include "incls/_jvmtiEnvThreadState.cpp.incl"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
// class JvmtiFramePop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
void JvmtiFramePop::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  tty->print_cr("_frame_number=%d", _frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
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
// class JvmtiFramePops - private methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
JvmtiFramePops::set(JvmtiFramePop& fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  if (_pops->find(fp.frame_number()) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    _pops->append(fp.frame_number());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
JvmtiFramePops::clear(JvmtiFramePop& fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  assert(_pops->length() > 0, "No more frame pops");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  _pops->remove(fp.frame_number());
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
int
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
JvmtiFramePops::clear_to(JvmtiFramePop& fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  int cleared = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  while (index < _pops->length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
    JvmtiFramePop pop = JvmtiFramePop(_pops->at(index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
    if (pop.above_on_stack(fp)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
      _pops->remove_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      ++cleared;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      ++index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  return cleared;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
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
// class JvmtiFramePops - public methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
JvmtiFramePops::JvmtiFramePops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  _pops = new (ResourceObj::C_HEAP) GrowableArray<int> (2, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
JvmtiFramePops::~JvmtiFramePops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  // return memory to c_heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  delete _pops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
void JvmtiFramePops::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  int n = _pops->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  for (int i=0; i<n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    JvmtiFramePop fp = JvmtiFramePop(_pops->at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    tty->print("%d: ", i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    fp.print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    tty->print_cr("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
///////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
// class JvmtiEnvThreadState
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
// Instances of JvmtiEnvThreadState hang off of each JvmtiThreadState,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
// one per JvmtiEnv.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
JvmtiEnvThreadState::JvmtiEnvThreadState(JavaThread *thread, JvmtiEnvBase *env) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  _event_enable() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  _thread                 = thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  _env                    = (JvmtiEnv*)env;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  _next                   = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  _frame_pops             = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  _current_bci            = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  _current_method_id      = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  _breakpoint_posted      = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  _single_stepping_posted = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  _agent_thread_local_storage_data = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
JvmtiEnvThreadState::~JvmtiEnvThreadState()   {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  delete _frame_pops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  _frame_pops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
// Given that a new (potential) event has come in,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
// maintain the current JVMTI location on a per-thread per-env basis
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
// and use it to filter out duplicate events:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
// - instruction rewrites
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
// - breakpoint followed by single step
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
// - single step at a breakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
void JvmtiEnvThreadState::compare_and_set_current_location(methodOop new_method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
                                                           address new_location, jvmtiEvent event) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  int new_bci = new_location - new_method->code_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // The method is identified and stored as a jmethodID which is safe in this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // case because the class cannot be unloaded while a method is executing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  jmethodID new_method_id = new_method->jmethod_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  // the last breakpoint or single step was at this same location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  if (_current_bci == new_bci && _current_method_id == new_method_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    switch (event) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    case JVMTI_EVENT_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      // Repeat breakpoint is complicated. If we previously posted a breakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      // event at this location and if we also single stepped at this location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
      // then we skip the duplicate breakpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      _breakpoint_posted = _breakpoint_posted && _single_stepping_posted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    case JVMTI_EVENT_SINGLE_STEP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      // Repeat single step is easy: just don't post it again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
      // If step is pending for popframe then it may not be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
      // a repeat step. The new_bci and method_id is same as current_bci
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
      // and current method_id after pop and step for recursive calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
      // This has been handled by clearing the location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
      _single_stepping_posted = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
      assert(false, "invalid event value passed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  set_current_location(new_method_id, new_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  _breakpoint_posted = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  _single_stepping_posted = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
         "frame pop data only accessible from same thread or while suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  if (_frame_pops == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    _frame_pops = new JvmtiFramePops();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
    assert(_frame_pops != NULL, "_frame_pops != NULL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  return _frame_pops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
bool JvmtiEnvThreadState::has_frame_pops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  return _frame_pops == NULL? false : (_frame_pops->length() > 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
void JvmtiEnvThreadState::set_frame_pop(int frame_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
         "frame pop data only accessible from same thread or while suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  JvmtiFramePop fpop(frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  JvmtiEventController::set_frame_pop(this, fpop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
         "frame pop data only accessible from same thread or while suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  JvmtiFramePop fpop(frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  JvmtiEventController::clear_frame_pop(this, fpop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number)  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
         "frame pop data only accessible from same thread or while suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  JvmtiFramePop fpop(frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  JvmtiEventController::clear_to_frame_pop(this, fpop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
         "frame pop data only accessible from same thread or while suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  JvmtiFramePop fp(cur_frame_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  return get_frame_pops()->contains(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
class VM_GetCurrentLocation : public VM_Operation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
   JavaThread *_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
   jmethodID _method_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
   int _bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  VM_GetCurrentLocation(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
     _thread = thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  VMOp_Type type() const { return VMOp_GetCurrentLocation; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  void doit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
    ResourceMark rmark; // _thread != Thread::current()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
    RegisterMap rm(_thread, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    javaVFrame* vf = _thread->last_java_vframe(&rm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    assert(vf != NULL, "must have last java frame");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    methodOop method = vf->method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    _method_id = method->jmethod_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    _bci = vf->bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  void get_current_location(jmethodID *method_id, int *bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    *method_id = _method_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    *bci = _bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
void JvmtiEnvThreadState::reset_current_location(jvmtiEvent event_type, bool enabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  assert(event_type == JVMTI_EVENT_SINGLE_STEP || event_type == JVMTI_EVENT_BREAKPOINT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
         "must be single-step or breakpoint event");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // Current location is used to detect the following:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  // 1) a breakpoint event followed by single-stepping to the same bci
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // 2) single-step to a bytecode that will be transformed to a fast version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // We skip to avoid posting the duplicate single-stepping event.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  // If single-stepping is disabled, clear current location so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  // single-stepping to the same method and bcp at a later time will be
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  // detected if single-stepping is enabled at that time (see 4388912).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  // If single-stepping is enabled, set the current location to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  // current method and bcp. This covers the following type of case,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // e.g., the debugger stepi command:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // - bytecode single stepped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  // - SINGLE_STEP event posted and SINGLE_STEP event disabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  // - SINGLE_STEP event reenabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  // - bytecode rewritten to fast version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // If breakpoint event is disabled, clear current location only if
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // single-stepping is not enabled.  Otherwise, keep the thread location
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // to detect any duplicate events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  if (enabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    // If enabling breakpoint, no need to reset.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    // Can't do anything if empty stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
    if (event_type == JVMTI_EVENT_SINGLE_STEP && _thread->has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      jmethodID method_id;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
      int bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
      // The java thread stack may not be walkable for a running thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
      // so get current location at safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
      VM_GetCurrentLocation op(_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      VMThread::execute(&op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      op.get_current_location(&method_id, &bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      set_current_location(method_id, bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  } else if (event_type == JVMTI_EVENT_SINGLE_STEP || !is_enabled(JVMTI_EVENT_SINGLE_STEP)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    // If this is to disable breakpoint, also check if single-step is not enabled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    clear_current_location();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
}