hotspot/src/share/vm/runtime/vmThread.cpp
author coleenp
Wed, 20 Mar 2013 08:04:54 -0400
changeset 16430 882cddc35bec
parent 15235 0a73bc0920e5
child 17006 b9bfa72b7dda
permissions -rw-r--r--
8008217: CDS: Class data sharing limits the malloc heap on Solaris Summary: In 64bit VM move CDS archive address to 32G on all platforms using new flag SharedBaseAddress. In 32bit VM set CDS archive address to 3Gb on Linux and let other OSs pick the address. Reviewed-by: kvn, dcubed, zgu, hseigel
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
15235
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
     2
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#include "compiler/compileBroker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "gc_interface/collectedHeap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "memory/resourceArea.hpp"
13728
882756847a04 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 12379
diff changeset
    29
#include "oops/method.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "runtime/interfaceSupport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "runtime/mutexLocker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "runtime/os.hpp"
14583
d70ee55535f4 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 14582
diff changeset
    34
#include "runtime/thread.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "runtime/vmThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "runtime/vm_operations.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
#include "services/runtimeService.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    38
#include "utilities/dtrace.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    39
#include "utilities/events.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    40
#include "utilities/xmlstream.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
    42
#ifndef USDT2
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
    43
HS_DTRACE_PROBE_DECL3(hotspot, vmops__request, char *, uintptr_t, int);
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
    44
HS_DTRACE_PROBE_DECL3(hotspot, vmops__begin, char *, uintptr_t, int);
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
    45
HS_DTRACE_PROBE_DECL3(hotspot, vmops__end, char *, uintptr_t, int);
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
    46
#endif /* !USDT2 */
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
    47
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// Dummy VM operation to act as first element in our circular double-linked list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
class VM_Dummy: public VM_Operation {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  VMOp_Type type() const { return VMOp_Dummy; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  void  doit() {};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
VMOperationQueue::VMOperationQueue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  // The queue is a circular doubled-linked list, which always contains
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  // one element (i.e., one element means empty).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  for(int i = 0; i < nof_priorities; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    _queue_length[i] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    _queue_counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
    _queue[i] = new VM_Dummy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
    _queue[i]->set_next(_queue[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
    _queue[i]->set_prev(_queue[i]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  _drain_list = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
bool VMOperationQueue::queue_empty(int prio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  // It is empty if there is exactly one element
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  bool empty = (_queue[prio] == _queue[prio]->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  assert( (_queue_length[prio] == 0 && empty) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
          (_queue_length[prio] > 0  && !empty), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  return _queue_length[prio] == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
// Inserts an element to the right of the q element
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
void VMOperationQueue::insert(VM_Operation* q, VM_Operation* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  assert(q->next()->prev() == q && q->prev()->next() == q, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  n->set_prev(q);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  n->set_next(q->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  q->next()->set_prev(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  q->set_next(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
void VMOperationQueue::queue_add_front(int prio, VM_Operation *op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  _queue_length[prio]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  insert(_queue[prio]->next(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
void VMOperationQueue::queue_add_back(int prio, VM_Operation *op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  _queue_length[prio]++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  insert(_queue[prio]->prev(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
void VMOperationQueue::unlink(VM_Operation* q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  assert(q->next()->prev() == q && q->prev()->next() == q, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  q->prev()->set_next(q->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  q->next()->set_prev(q->prev());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
VM_Operation* VMOperationQueue::queue_remove_front(int prio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  if (queue_empty(prio)) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  assert(_queue_length[prio] >= 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  _queue_length[prio]--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  VM_Operation* r = _queue[prio]->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  assert(r != _queue[prio], "cannot remove base element");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  unlink(r);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  return r;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
VM_Operation* VMOperationQueue::queue_drain(int prio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  if (queue_empty(prio)) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  DEBUG_ONLY(int length = _queue_length[prio];);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  assert(length >= 0, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  _queue_length[prio] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  VM_Operation* r = _queue[prio]->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  assert(r != _queue[prio], "cannot remove base element");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  // remove links to base element from head and tail
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  r->set_prev(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  _queue[prio]->prev()->set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  // restore queue to empty state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  _queue[prio]->set_next(_queue[prio]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  _queue[prio]->set_prev(_queue[prio]);
5402
c51fd0c1d005 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 5089
diff changeset
   125
  assert(queue_empty(prio), "drain corrupted queue");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
#ifdef DEBUG
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  int len = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  VM_Operation* cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  for(cur = r; cur != NULL; cur=cur->next()) len++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  assert(len == length, "drain lost some ops");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  return r;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
void VMOperationQueue::queue_oops_do(int queue, OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  VM_Operation* cur = _queue[queue];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  cur = cur->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  while (cur != _queue[queue]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    cur->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    cur = cur->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
void VMOperationQueue::drain_list_oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  VM_Operation* cur = _drain_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  while (cur != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    cur->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    cur = cur->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
//-----------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
// High-level interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
bool VMOperationQueue::add(VM_Operation *op) {
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   155
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   156
#ifndef USDT2
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   157
  HS_DTRACE_PROBE3(hotspot, vmops__request, op->name(), strlen(op->name()),
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   158
                   op->evaluation_mode());
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   159
#else /* USDT2 */
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   160
  HOTSPOT_VMOPS_REQUEST(
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   161
                   (char *) op->name(), strlen(op->name()),
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   162
                   op->evaluation_mode());
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   163
#endif /* USDT2 */
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   164
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  // Encapsulates VM queue policy. Currently, that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  // only involves putting them on the right list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  if (op->evaluate_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    queue_add_back(SafepointPriority, op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  queue_add_back(MediumPriority, op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
VM_Operation* VMOperationQueue::remove_next() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // Assuming VMOperation queue is two-level priority queue. If there are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // more than two priorities, we need a different scheduling algorithm.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  assert(SafepointPriority == 0 && MediumPriority == 1 && nof_priorities == 2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
         "current algorithm does not work");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  // simple counter based scheduling to prevent starvation of lower priority
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  // queue. -- see 4390175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  int high_prio, low_prio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  if (_queue_counter++ < 10) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      high_prio = SafepointPriority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      low_prio  = MediumPriority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
      _queue_counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
      high_prio = MediumPriority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
      low_prio  = SafepointPriority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  return queue_remove_front(queue_empty(high_prio) ? low_prio : high_prio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
void VMOperationQueue::oops_do(OopClosure* f) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  for(int i = 0; i < nof_priorities; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    queue_oops_do(i, f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  drain_list_oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
//------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
// Implementation of VMThread stuff
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
bool                VMThread::_should_terminate   = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
bool              VMThread::_terminated         = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
Monitor*          VMThread::_terminate_lock     = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
VMThread*         VMThread::_vm_thread          = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
VM_Operation*     VMThread::_cur_vm_operation   = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
VMOperationQueue* VMThread::_vm_queue           = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
PerfCounter*      VMThread::_perf_accumulated_vm_operation_time = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
void VMThread::create() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  assert(vm_thread() == NULL, "we can only allocate one VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  _vm_thread = new VMThread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  // Create VM operation queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  _vm_queue = new VMOperationQueue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  guarantee(_vm_queue != NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  if (UsePerfData) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    // jvmstat performance counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    Thread* THREAD = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    _perf_accumulated_vm_operation_time =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
                 PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
                                                 PerfData::U_Ticks, CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
4489
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 3908
diff changeset
   237
VMThread::VMThread() : NamedThread() {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 3908
diff changeset
   238
  set_name("VM Thread");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
void VMThread::destroy() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  if (_vm_thread != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
    delete _vm_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    _vm_thread = NULL;      // VM thread is gone
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
void VMThread::run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  assert(this == vm_thread(), "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  this->initialize_thread_local_storage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  this->record_stack_base_and_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  // Notify_lock wait checks on active_handles() to rewait in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // case of spurious wakeup, it should wait on the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  // value set prior to the notify
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  this->set_active_handles(JNIHandleBlock::allocate_block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
    MutexLocker ml(Notify_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    Notify_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // Notify_lock is destroyed by Threads::create_vm()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  int prio = (VMThreadPriority == -1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
    ? os::java_to_os_priority[NearMaxPriority]
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    : VMThreadPriority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  // Note that I cannot call os::set_priority because it expects Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // priorities and I am *explicitly* using OS priorities so that it's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  // possible to set the VM thread priority higher than any Java thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  os::set_native_priority( this, prio );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  // Wait for VM_Operations until termination
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  this->loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // Note the intention to exit before safepointing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  // 6295565  This has the effect of waiting for any large tty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // outputs to finish.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  if (xtty != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    ttyLocker ttyl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    xtty->begin_elem("destroy_vm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    xtty->stamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    xtty->end_elem();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    assert(should_terminate(), "termination flag must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // 4526887 let VM thread exit at Safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  SafepointSynchronize::begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  if (VerifyBeforeExit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    HandleMark hm(VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    // Among other things, this ensures that Eden top is correct.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    Universe::heap()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    os::check_heap();
9342
456b8d0486b5 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 7397
diff changeset
   294
    // Silent verification so as not to pollute normal output,
456b8d0486b5 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents: 7397
diff changeset
   295
    // unless we really asked for it.
12379
2cf45b79ce3a 4988100: oop_verify_old_oop appears to be dead
brutisso
parents: 10739
diff changeset
   296
    Universe::verify(!(PrintGCDetails || Verbose));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  CompileBroker::set_should_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  // wait for threads (compiler threads or daemon threads) in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  // _thread_in_native state to block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  VM_Exit::wait_for_threads_in_native_to_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // signal other threads that VM process is gone
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    // Note: we must have the _no_safepoint_check_flag. Mutex::lock() allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    // VM thread to enter any lock at Safepoint as long as its _owner is NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    // If that happens after _terminate_lock->wait() has unset _owner
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    // but before it actually drops the lock and waits, the notification below
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    // may get lost and we will have a hang. To avoid this, we need to use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    // Mutex::lock_without_safepoint_check().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    _terminated = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    _terminate_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  // Deletion must be done synchronously by the JNI DestroyJavaVM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  // so that the VMThread deletion completes before the main thread frees
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  // up the CodeHeap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
// Notify the VMThread that the last non-daemon JavaThread has terminated,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
// and wait until operation is performed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
void VMThread::wait_for_vm_thread_exit() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  { MutexLocker mu(VMOperationQueue_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    _should_terminate = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
    VMOperationQueue_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // Note: VM thread leaves at Safepoint. We are not stopped by Safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // because this thread has been removed from the threads list. But anything
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  // that could get blocked by Safepoint should not be used after this point,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // otherwise we will hang, since there is no one can end the safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  // Wait until VM thread is terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  // Note: it should be OK to use Terminator_lock here. But this is called
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  // at a very delicate time (VM shutdown) and we are operating in non- VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // thread at Safepoint. It's safer to not share lock with other threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  { MutexLockerEx ml(_terminate_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    while(!VMThread::is_terminated()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
        _terminate_lock->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
void VMThread::print_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  st->print("\"%s\" ", name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  Thread::print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
void VMThread::evaluate_operation(VM_Operation* op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    PerfTraceTime vm_op_timer(perf_accumulated_vm_operation_time());
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   360
#ifndef USDT2
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   361
    HS_DTRACE_PROBE3(hotspot, vmops__begin, op->name(), strlen(op->name()),
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   362
                     op->evaluation_mode());
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   363
#else /* USDT2 */
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   364
    HOTSPOT_VMOPS_BEGIN(
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   365
                     (char *) op->name(), strlen(op->name()),
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   366
                     op->evaluation_mode());
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   367
#endif /* USDT2 */
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
    op->evaluate();
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   369
#ifndef USDT2
5089
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   370
    HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
0cce506a0158 6935224: Adding new DTrace probes to work with Palantir
fparain
parents: 4901
diff changeset
   371
                     op->evaluation_mode());
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   372
#else /* USDT2 */
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   373
    HOTSPOT_VMOPS_END(
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   374
                     (char *) op->name(), strlen(op->name()),
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   375
                     op->evaluation_mode());
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10565
diff changeset
   376
#endif /* USDT2 */
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  // Last access of info in _cur_vm_operation!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  bool c_heap_allocated = op->is_cheap_allocated();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  // Mark as completed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  if (!op->evaluate_concurrently()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
    op->calling_thread()->increment_vm_operation_completed_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  // It is unsafe to access the _cur_vm_operation after the 'increment_vm_operation_completed_count' call,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  // since if it is stack allocated the calling thread might have deallocated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  if (c_heap_allocated) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    delete _cur_vm_operation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
void VMThread::loop() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  assert(_cur_vm_operation == NULL, "no current one should be executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  while(true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
    VM_Operation* safepoint_ops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    // Wait for VM operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
    // use no_safepoint_check to get lock without attempting to "sneak"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
    { MutexLockerEx mu_queue(VMOperationQueue_lock,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
                             Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
      // Look for new operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
      assert(_cur_vm_operation == NULL, "no current one should be executing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      _cur_vm_operation = _vm_queue->remove_next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
      // Stall time tracking code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
      if (PrintVMQWaitTime && _cur_vm_operation != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
          !_cur_vm_operation->evaluate_concurrently()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
        long stall = os::javaTimeMillis() - _cur_vm_operation->timestamp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
        if (stall > 0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
          tty->print_cr("%s stall: %Ld",  _cur_vm_operation->name(), stall);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
      while (!should_terminate() && _cur_vm_operation == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
        // wait with a timeout to guarantee safepoints at regular intervals
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
        bool timedout =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
          VMOperationQueue_lock->wait(Mutex::_no_safepoint_check_flag,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
                                      GuaranteedSafepointInterval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
        // Support for self destruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
        if ((SelfDestructTimer != 0) && !is_error_reported() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
            (os::elapsedTime() > SelfDestructTimer * 60)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
          tty->print_cr("VM self-destructed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
          exit(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
        if (timedout && (SafepointALot ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
                         SafepointSynchronize::is_cleanup_needed())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
          MutexUnlockerEx mul(VMOperationQueue_lock,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
                              Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
          // Force a safepoint since we have not had one for at least
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
          // 'GuaranteedSafepointInterval' milliseconds.  This will run all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
          // the clean-up processing that needs to be done regularly at a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
          // safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
          SafepointSynchronize::begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
          #ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
            if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
          #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
          SafepointSynchronize::end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        _cur_vm_operation = _vm_queue->remove_next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        // If we are at a safepoint we will evaluate all the operations that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
        // follow that also require a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        if (_cur_vm_operation != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
            _cur_vm_operation->evaluate_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
          safepoint_ops = _vm_queue->drain_at_safepoint_priority();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
      if (should_terminate()) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    } // Release mu_queue_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    // Execute VM operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    { HandleMark hm(VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
      EventMark em("Executing VM operation: %s", vm_operation()->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
      assert(_cur_vm_operation != NULL, "we should have found an operation to execute");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
      // Give the VM thread an extra quantum.  Jobs tend to be bursty and this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
      // helps the VM thread to finish up the job.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
      // FIXME: When this is enabled and there are many threads, this can degrade
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
      // performance significantly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      if( VMThreadHintNoPreempt )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
        os::hint_no_preempt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
      // If we are at a safepoint we will evaluate all the operations that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
      // follow that also require a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
      if (_cur_vm_operation->evaluate_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
        _vm_queue->set_drain_list(safepoint_ops); // ensure ops can be scanned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
        SafepointSynchronize::begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
        evaluate_operation(_cur_vm_operation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        // now process all queued safepoint ops, iteratively draining
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
        // the queue until there are none left
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
        do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
          _cur_vm_operation = safepoint_ops;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
          if (_cur_vm_operation != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
            do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
              // evaluate_operation deletes the op object so we have
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
              // to grab the next op now
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
              VM_Operation* next = _cur_vm_operation->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
              _vm_queue->set_drain_list(next);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
              evaluate_operation(_cur_vm_operation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
              _cur_vm_operation = next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
              if (PrintSafepointStatistics) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
                SafepointSynchronize::inc_vmop_coalesced_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
              }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
            } while (_cur_vm_operation != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
          // There is a chance that a thread enqueued a safepoint op
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
          // since we released the op-queue lock and initiated the safepoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
          // So we drain the queue again if there is anything there, as an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
          // optimization to try and reduce the number of safepoints.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
          // As the safepoint synchronizes us with JavaThreads we will see
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
          // any enqueue made by a JavaThread, but the peek will not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
          // necessarily detect a concurrent enqueue by a GC thread, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
          // that simply means the op will wait for the next major cycle of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
          // VMThread - just as it would if the GC thread lost the race for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
          // the lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
          if (_vm_queue->peek_at_safepoint_priority()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
            // must hold lock while draining queue
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
            MutexLockerEx mu_queue(VMOperationQueue_lock,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
                                     Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
            safepoint_ops = _vm_queue->drain_at_safepoint_priority();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
            safepoint_ops = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
        } while(safepoint_ops != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
        _vm_queue->set_drain_list(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
        // Complete safepoint synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
        SafepointSynchronize::end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
      } else {  // not a safepoint operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
        if (TraceLongCompiles) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
          elapsedTimer t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
          t.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
          evaluate_operation(_cur_vm_operation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
          t.stop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
          double secs = t.seconds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
          if (secs * 1e3 > LongCompileThreshold) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
            // XXX - _cur_vm_operation should not be accessed after
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
            // the completed count has been incremented; the waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
            // thread may have already freed this memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
            tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
          evaluate_operation(_cur_vm_operation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
        _cur_vm_operation = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
    //  Notify (potential) waiting Java thread(s) - lock without safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
    //  check so that sneaking is not possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
    { MutexLockerEx mu(VMOperationRequest_lock,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
                       Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
      VMOperationRequest_lock->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    // We want to make sure that we get to a safepoint regularly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
    if (SafepointALot || SafepointSynchronize::is_cleanup_needed()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
      long interval          = SafepointSynchronize::last_non_safepoint_interval();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
      bool max_time_exceeded = GuaranteedSafepointInterval != 0 && (interval > GuaranteedSafepointInterval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
      if (SafepointALot || max_time_exceeded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
        HandleMark hm(VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
        SafepointSynchronize::begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
        SafepointSynchronize::end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
void VMThread::execute(VM_Operation* op) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  Thread* t = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  if (!t->is_VM_thread()) {
2995
d8283445992a 6820167: GCALotAtAllSafepoints + FullGCALot(ScavengeALot) options crash JVM
ysr
parents: 1
diff changeset
   571
    SkipGCALot sgcalot(t);    // avoid re-entrant attempts to gc-a-lot
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
    // JavaThread or WatcherThread
15235
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
   573
    bool concurrent = op->evaluate_concurrently();
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
   574
    // only blocking VM operations need to verify the caller's safepoint state:
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
   575
    if (!concurrent) {
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
   576
      t->check_for_valid_safepoint_state(true);
0a73bc0920e5 8004903: VMThread::execute() calls Thread::check_for_valid_safepoint_state() on concurrent VM ops
dcubed
parents: 14583
diff changeset
   577
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    // New request from Java thread, evaluate prologue
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
    if (!op->doit_prologue()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
      return;   // op was cancelled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
    // Setup VM_operations for execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    op->set_calling_thread(t, Thread::get_priority(t));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    // It does not make sense to execute the epilogue, if the VM operation object is getting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    // deallocated by the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    bool execute_epilog = !op->is_cheap_allocated();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    // Get ticket number for non-concurrent VM operations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
    int ticket = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    if (!concurrent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
      ticket = t->vm_operation_ticket();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    // Add VM operation to list of waiting threads. We are guaranteed not to block while holding the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    // VMOperationQueue_lock, so we can block without a safepoint check. This allows vm operation requests
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    // to be queued up during a safepoint synchronization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      VMOperationQueue_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      bool ok = _vm_queue->add(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      op->set_timestamp(os::javaTimeMillis());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
      VMOperationQueue_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      VMOperationQueue_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      // VM_Operation got skipped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      if (!ok) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
        assert(concurrent, "can only skip concurrent tasks");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
        if (op->is_cheap_allocated()) delete op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    if (!concurrent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      // Wait for completion of request (non-concurrent)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
      // Note: only a JavaThread triggers the safepoint check when locking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
      MutexLocker mu(VMOperationRequest_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
      while(t->vm_operation_completed_count() < ticket) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
        VMOperationRequest_lock->wait(!t->is_Java_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
    if (execute_epilog) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
      op->doit_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
    // invoked by VM thread; usually nested VM operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    assert(t->is_VM_thread(), "must be a VM thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
    VM_Operation* prev_vm_operation = vm_operation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    if (prev_vm_operation != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
      // Check the VM operation allows nested VM operation. This normally not the case, e.g., the compiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
      // does not allow nested scavenges or compiles.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
      if (!prev_vm_operation->allow_nested_vm_operations()) {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5402
diff changeset
   635
        fatal(err_msg("Nested VM operation %s requested by operation %s",
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5402
diff changeset
   636
                      op->name(), vm_operation()->name()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
      op->set_calling_thread(prev_vm_operation->calling_thread(), prev_vm_operation->priority());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    EventMark em("Executing %s VM operation: %s", prev_vm_operation ? "nested" : "", op->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
    // Release all internal handles after operation is evaluated
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
    HandleMark hm(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    _cur_vm_operation = op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    if (op->evaluate_at_safepoint() && !SafepointSynchronize::is_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
      SafepointSynchronize::begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
      op->evaluate();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
      SafepointSynchronize::end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
      op->evaluate();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    // Free memory if needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    if (op->is_cheap_allocated()) delete op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
    _cur_vm_operation = prev_vm_operation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
14582
490bb6c0df7c 8003720: NPG: Method in interpreter stack frame can be deallocated
stefank
parents: 13728
diff changeset
   663
void VMThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) {
490bb6c0df7c 8003720: NPG: Method in interpreter stack frame can be deallocated
stefank
parents: 13728
diff changeset
   664
  Thread::oops_do(f, cld_f, cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  _vm_queue->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
//------------------------------------------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
void VMOperationQueue::verify_queue(int prio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  // Check that list is correctly linked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  int length = _queue_length[prio];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  VM_Operation *cur = _queue[prio];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
  // Check forward links
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  for(i = 0; i < length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    cur = cur->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    assert(cur != _queue[prio], "list to short (forward)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  assert(cur->next() == _queue[prio], "list to long (forward)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  // Check backwards links
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  cur = _queue[prio];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  for(i = 0; i < length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
    cur = cur->prev();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    assert(cur != _queue[prio], "list to short (backwards)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  assert(cur->prev() == _queue[prio], "list to long (backwards)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
void VMThread::verify() {
14582
490bb6c0df7c 8003720: NPG: Method in interpreter stack frame can be deallocated
stefank
parents: 13728
diff changeset
   696
  oops_do(&VerifyOopClosure::verify_oop, NULL, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
}