hotspot/src/share/vm/runtime/thread.cpp
author johnc
Thu, 22 Sep 2011 10:57:37 -0700
changeset 10670 4ea0e7d2ffbc
parent 10546 e79347eebbc5
child 10678 ecb473e90f9b
permissions -rw-r--r--
6484982: G1: process references during evacuation pauses Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate. Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
7724
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
     2
 * Copyright (c) 1997, 2011, 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: 5085
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5085
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: 5085
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: 7123
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    26
#include "classfile/classLoader.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    27
#include "classfile/javaClasses.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    28
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    29
#include "classfile/vmSymbols.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    30
#include "code/scopeDesc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    31
#include "compiler/compileBroker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    32
#include "interpreter/interpreter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    33
#include "interpreter/linkResolver.hpp"
9437
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
    34
#include "interpreter/oopMapCache.hpp"
7897
201a8b00ec91 6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents: 7724
diff changeset
    35
#include "jvmtifiles/jvmtiEnv.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    36
#include "memory/oopFactory.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    37
#include "memory/universe.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    38
#include "oops/instanceKlass.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    39
#include "oops/objArrayOop.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    40
#include "oops/oop.inline.hpp"
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
    41
#include "oops/symbol.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    42
#include "prims/jvm_misc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    43
#include "prims/jvmtiExport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    44
#include "prims/jvmtiThreadState.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    45
#include "prims/privilegedStack.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    46
#include "runtime/aprofiler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    47
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    48
#include "runtime/biasedLocking.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    49
#include "runtime/deoptimization.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    50
#include "runtime/fprofiler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    51
#include "runtime/frame.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    52
#include "runtime/init.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    53
#include "runtime/interfaceSupport.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    54
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    55
#include "runtime/javaCalls.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    56
#include "runtime/jniPeriodicChecker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    57
#include "runtime/memprofiler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    58
#include "runtime/mutexLocker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    59
#include "runtime/objectMonitor.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    60
#include "runtime/osThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    61
#include "runtime/safepoint.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    62
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    63
#include "runtime/statSampler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    64
#include "runtime/stubRoutines.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    65
#include "runtime/task.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    66
#include "runtime/threadCritical.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    67
#include "runtime/threadLocalStorage.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    68
#include "runtime/vframe.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    69
#include "runtime/vframeArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    70
#include "runtime/vframe_hp.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    71
#include "runtime/vmThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    72
#include "runtime/vm_operations.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    73
#include "services/attachListener.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    74
#include "services/management.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    75
#include "services/threadService.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    76
#include "utilities/defaultStream.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    77
#include "utilities/dtrace.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    78
#include "utilities/events.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    79
#include "utilities/preserveException.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    80
#ifdef TARGET_OS_FAMILY_linux
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    81
# include "os_linux.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    82
# include "thread_linux.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    83
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    84
#ifdef TARGET_OS_FAMILY_solaris
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    85
# include "os_solaris.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    86
# include "thread_solaris.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    87
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    88
#ifdef TARGET_OS_FAMILY_windows
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    89
# include "os_windows.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    90
# include "thread_windows.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    91
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    92
#ifndef SERIALGC
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    93
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    94
#include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    95
#include "gc_implementation/parallelScavenge/pcTasks.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    96
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    97
#ifdef COMPILER1
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    98
#include "c1/c1_Compiler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
    99
#endif
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
   100
#ifdef COMPILER2
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
   101
#include "opto/c2compiler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
   102
#include "opto/idealGraphPrinter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 7123
diff changeset
   103
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
#ifdef DTRACE_ENABLED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
// Only bother with this argument setup if dtrace is available
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
HS_DTRACE_PROBE_DECL(hotspot, vm__init__begin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
HS_DTRACE_PROBE_DECL(hotspot, vm__init__end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
HS_DTRACE_PROBE_DECL5(hotspot, thread__start, char*, intptr_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  intptr_t, intptr_t, bool);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
HS_DTRACE_PROBE_DECL5(hotspot, thread__stop, char*, intptr_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  intptr_t, intptr_t, bool);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
#define DTRACE_THREAD_PROBE(probe, javathread)                             \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  {                                                                        \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
    ResourceMark rm(this);                                                 \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    int len = 0;                                                           \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    const char* name = (javathread)->get_thread_name();                    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    len = strlen(name);                                                    \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    HS_DTRACE_PROBE5(hotspot, thread__##probe,                             \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
      name, len,                                                           \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
      java_lang_Thread::thread_id((javathread)->threadObj()),              \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
      (javathread)->osthread()->thread_id(),                               \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
      java_lang_Thread::is_daemon((javathread)->threadObj()));             \
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
#else //  ndef DTRACE_ENABLED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
#define DTRACE_THREAD_PROBE(probe, javathread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
#endif // ndef DTRACE_ENABLED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
// Class hierarchy
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
// - Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
//   - VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
//   - WatcherThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
//   - ConcurrentMarkSweepThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
//   - JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
//     - CompilerThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
// ======= Thread ========
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
// Support for forcing alignment of thread objects for biased locking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
void* Thread::operator new(size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    const int alignment = markOopDesc::biased_lock_alignment;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    size_t aligned_size = size + (alignment - sizeof(intptr_t));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    void* real_malloc_addr = CHeapObj::operator new(aligned_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    void* aligned_addr     = (void*) align_size_up((intptr_t) real_malloc_addr, alignment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    assert(((uintptr_t) aligned_addr + (uintptr_t) size) <=
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
           ((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
           "JavaThread alignment code overflowed allocated storage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
    if (TraceBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      if (aligned_addr != real_malloc_addr)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
        tty->print_cr("Aligned thread " INTPTR_FORMAT " to " INTPTR_FORMAT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
                      real_malloc_addr, aligned_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    ((Thread*) aligned_addr)->_real_malloc_address = real_malloc_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    return aligned_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    return CHeapObj::operator new(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
void Thread::operator delete(void* p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    void* real_malloc_addr = ((Thread*) p)->_real_malloc_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    CHeapObj::operator delete(real_malloc_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    CHeapObj::operator delete(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
// Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
// JavaThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
Thread::Thread() {
7724
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   182
  // stack and get_thread
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   183
  set_stack_base(NULL);
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   184
  set_stack_size(0);
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   185
  set_self_raw_id(0);
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   186
  set_lgrp_id(-1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // allocated data structures
7724
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   189
  set_osthread(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
  set_resource_area(new ResourceArea());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  set_handle_area(new HandleArea(NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  set_active_handles(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  set_free_handle_block(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  set_last_handle_mark(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  // This initial value ==> never claimed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  _oops_do_parity = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  // the handle mark links itself to last_handle_mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  new HandleMark(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // plain initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  debug_only(_owned_locks = NULL;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  debug_only(_allow_allocation_count = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  NOT_PRODUCT(_allow_safepoint_count = 0;)
2995
d8283445992a 6820167: GCALotAtAllSafepoints + FullGCALot(ScavengeALot) options crash JVM
ysr
parents: 2526
diff changeset
   206
  NOT_PRODUCT(_skip_gcalot = false;)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  _jvmti_env_iteration_count = 0;
7724
a92d706dbdd5 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 7439
diff changeset
   209
  set_allocated_bytes(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  _vm_operation_started_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  _vm_operation_completed_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  _current_pending_monitor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  _current_pending_monitor_is_from_java = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  _current_waiting_monitor = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  _num_nested_signal = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  omFreeList = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  omFreeCount = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  omFreeProvision = 32 ;
5710
d664086c0add 6852873: Reduce safepoint cleanup time
acorn
parents: 5085
diff changeset
   219
  omInUseList = NULL ;
d664086c0add 6852873: Reduce safepoint cleanup time
acorn
parents: 5085
diff changeset
   220
  omInUseCount = 0 ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  _suspend_flags = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  // thread-specific hashCode stream generator state - Marsaglia shift-xor form
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  _hashStateX = os::random() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  _hashStateY = 842502087 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  _hashStateZ = 0x8767 ;    // (int)(3579807591LL & 0xffff) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  _hashStateW = 273326509 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  _OnTrap   = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  _schedctl = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  _Stalled  = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  _TypeTag  = 0x2BAD ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  // Many of the following fields are effectively final - immutable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  // Note that nascent threads can't use the Native Monitor-Mutex
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // construct until the _MutexEvent is initialized ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  // we might instead use a stack of ParkEvents that we could provision on-demand.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  // The stack would act as a cache to avoid calls to ParkEvent::Allocate()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  // and ::Release()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  _ParkEvent   = ParkEvent::Allocate (this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  _SleepEvent  = ParkEvent::Allocate (this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  _MutexEvent  = ParkEvent::Allocate (this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  _MuxEvent    = ParkEvent::Allocate (this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
#ifdef CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  if (CheckUnhandledOops) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    _unhandled_oops = new UnhandledOops(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
#endif // CHECK_UNHANDLED_OOPS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  if (UseBiasedLocking) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
    assert((((uintptr_t) this) & (markOopDesc::biased_lock_alignment - 1)) == 0, "forced alignment of thread object failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
    assert(this == _real_malloc_address ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
           this == (void*) align_size_up((intptr_t) _real_malloc_address, markOopDesc::biased_lock_alignment),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
           "bug in forced alignment of thread objects");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
#endif /* ASSERT */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
void Thread::initialize_thread_local_storage() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  // Note: Make sure this method only calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // non-blocking operations. Otherwise, it might not work
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  // with the thread-startup/safepoint interaction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // During Java thread startup, safepoint code should allow this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  // method to complete because it may need to allocate memory to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  // store information for the new thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  // initialize structure dependent on thread local storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  ThreadLocalStorage::set_thread(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // set up any platform-specific state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  os::initialize_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
void Thread::record_stack_base_and_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  set_stack_base(os::current_stack_base());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  set_stack_size(os::current_stack_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
Thread::~Thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // Reclaim the objectmonitors from the omFreeList of the moribund thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  ObjectSynchronizer::omFlush (this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  // deallocate data structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  delete resource_area();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // since the handle marks are using the handle area, we have to deallocated the root
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // handle mark before deallocating the thread's handle area,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  assert(last_handle_mark() != NULL, "check we have an element");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  delete last_handle_mark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  assert(last_handle_mark() == NULL, "check we have reached the end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  // It's possible we can encounter a null _ParkEvent, etc., in stillborn threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  // We NULL out the fields for good hygiene.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  ParkEvent::Release (_ParkEvent)   ; _ParkEvent   = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  ParkEvent::Release (_SleepEvent)  ; _SleepEvent  = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  ParkEvent::Release (_MutexEvent)  ; _MutexEvent  = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  ParkEvent::Release (_MuxEvent)    ; _MuxEvent    = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  delete handle_area();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  // osthread() can be NULL, if creation of thread failed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  if (osthread() != NULL) os::free_thread(osthread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  delete _SR_lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  // clear thread local storage if the Thread is deleting itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  if (this == Thread::current()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
    ThreadLocalStorage::set_thread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    // In the case where we're not the current thread, invalidate all the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    // caches in case some code tries to get the current thread or the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    // thread that was destroyed, and gets stale information.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    ThreadLocalStorage::invalidate_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  CHECK_UNHANDLED_OOPS_ONLY(if (CheckUnhandledOops) delete unhandled_oops();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
// NOTE: dummy function for assertion purpose.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
void Thread::run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
// Private method to check for dangling thread pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
void check_for_dangling_thread_pointer(Thread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
 assert(!thread->is_Java_thread() || Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
         "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
// Tracing method for basic thread operations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
void Thread::trace(const char* msg, const Thread* const thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  if (!TraceThreadEvents) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  ThreadCritical tc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  const char *name = "non-Java thread";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  int prio = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  if (thread->is_Java_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
      && !thread->is_Compiler_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    // The Threads_lock must be held to get information about
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
    // this thread but may not be in some situations when
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
    // tracing  thread events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
    bool release_Threads_lock = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    if (!Threads_lock->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
      Threads_lock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
      release_Threads_lock = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
    JavaThread* jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
    name = (char *)jt->get_thread_name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
    oop thread_oop = jt->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    if (thread_oop != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
      prio = java_lang_Thread::priority(thread_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    if (release_Threads_lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
      Threads_lock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  tty->print_cr("Thread::%s " INTPTR_FORMAT " [%lx] %s (prio: %d)", msg, thread, thread->osthread()->thread_id(), name, prio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
ThreadPriority Thread::get_priority(const Thread* const thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  trace("get priority", thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
  ThreadPriority priority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  // Can return an error!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  (void)os::get_priority(thread, priority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  assert(MinPriority <= priority && priority <= MaxPriority, "non-Java priority found");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  return priority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
void Thread::set_priority(Thread* thread, ThreadPriority priority) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  trace("set priority", thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  debug_only(check_for_dangling_thread_pointer(thread);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  // Can return an error!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  (void)os::set_priority(thread, priority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
void Thread::start(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  trace("start", thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  // Start is different from resume in that its safety is guaranteed by context or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  // being called from a Java method synchronized on the Thread object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  if (!DisableStartThread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
    if (thread->is_Java_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
      // Initialize the thread state to RUNNABLE before starting this thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
      // Can not set it after the thread started because we do not know the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
      // exact thread state at that time. It could be in MONITOR_WAIT or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
      // in SLEEPING or some other state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
      java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
                                          java_lang_Thread::RUNNABLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
    os::start_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
// Enqueue a VM_Operation to do the job for us - sometime later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
void Thread::send_async_exception(oop java_thread, oop java_throwable) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  VM_ThreadStop* vm_stop = new VM_ThreadStop(java_thread, java_throwable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  VMThread::execute(vm_stop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
// Check if an external suspend request has completed (or has been
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
// cancelled). Returns true if the thread is externally suspended and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
// false otherwise.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
// The bits parameter returns information about the code path through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
// the routine. Useful for debugging:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
// set in is_ext_suspend_completed():
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
// 0x00000001 - routine was entered
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
// 0x00000010 - routine return false at end
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
// 0x00000100 - thread exited (return false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
// 0x00000200 - suspend request cancelled (return false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
// 0x00000400 - thread suspended (return true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
// 0x00001000 - thread is in a suspend equivalent state (return true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
// 0x00002000 - thread is native and walkable (return true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
// 0x00004000 - thread is native_trans and walkable (needed retry)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
// set in wait_for_ext_suspend_completion():
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
// 0x00010000 - routine was entered
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
// 0x00020000 - suspend request cancelled before loop (return false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
// 0x00040000 - thread suspended before loop (return true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
// 0x00080000 - suspend request cancelled in loop (return false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
// 0x00100000 - thread suspended in loop (return true)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
// 0x00200000 - suspend not completed during retry loop (return false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
// Helper class for tracing suspend wait debug bits.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
// 0x00000100 indicates that the target thread exited before it could
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
// self-suspend which is not a wait failure. 0x00000200, 0x00020000 and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
// 0x00080000 each indicate a cancelled suspend request so they don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
// count as wait failures either.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
#define DEBUG_FALSE_BITS (0x00000010 | 0x00200000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
class TraceSuspendDebugBits : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  JavaThread * jt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  bool         is_wait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  bool         called_by_wait;  // meaningful when !is_wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  uint32_t *   bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  TraceSuspendDebugBits(JavaThread *_jt, bool _is_wait, bool _called_by_wait,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
                        uint32_t *_bits) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    jt             = _jt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    is_wait        = _is_wait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    called_by_wait = _called_by_wait;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    bits           = _bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  ~TraceSuspendDebugBits() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    if (!is_wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
#if 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
      // By default, don't trace bits for is_ext_suspend_completed() calls.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
      // That trace is very chatty.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
      if (!called_by_wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
        // If tracing for is_ext_suspend_completed() is enabled, then only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
        // trace calls to it from wait_for_ext_suspend_completion()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
    if (AssertOnSuspendWaitFailure || TraceSuspendWaitFailures) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
      if (bits != NULL && (*bits & DEBUG_FALSE_BITS) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
        MutexLocker ml(Threads_lock);  // needed for get_thread_name()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
        ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
        tty->print_cr(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
            "Failed wait_for_ext_suspend_completion(thread=%s, debug_bits=%x)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
            jt->get_thread_name(), *bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
        guarantee(!AssertOnSuspendWaitFailure, "external suspend wait failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
#undef DEBUG_FALSE_BITS
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
bool JavaThread::is_ext_suspend_completed(bool called_by_wait, int delay, uint32_t *bits) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  TraceSuspendDebugBits tsdb(this, false /* !is_wait */, called_by_wait, bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  bool did_trans_retry = false;  // only do thread_in_native_trans retry once
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  bool do_trans_retry;           // flag to force the retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  *bits |= 0x00000001;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
    do_trans_retry = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
    if (is_exiting()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
      // Thread is in the process of exiting. This is always checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
      // first to reduce the risk of dereferencing a freed JavaThread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
      *bits |= 0x00000100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
    if (!is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
      // Suspend request is cancelled. This is always checked before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
      // is_ext_suspended() to reduce the risk of a rogue resume
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
      // confusing the thread that made the suspend request.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
      *bits |= 0x00000200;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    if (is_ext_suspended()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
      // thread is suspended
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
      *bits |= 0x00000400;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
    // Now that we no longer do hard suspends of threads running
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
    // native code, the target thread can be changing thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
    // while we are in this routine:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
    //   _thread_in_native -> _thread_in_native_trans -> _thread_blocked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    // We save a copy of the thread state as observed at this moment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    // and make our decision about suspend completeness based on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    // copy. This closes the race where the thread state is seen as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    // _thread_in_native_trans in the if-thread_blocked check, but is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    // seen as _thread_blocked in if-thread_in_native_trans check.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    JavaThreadState save_state = thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    if (save_state == _thread_blocked && is_suspend_equivalent()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      // If the thread's state is _thread_blocked and this blocking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      // condition is known to be equivalent to a suspend, then we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
      // consider the thread to be externally suspended. This means that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
      // the code that sets _thread_blocked has been modified to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      // self-suspension if the blocking condition releases. We also
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
      // used to check for CONDVAR_WAIT here, but that is now covered by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
      // the _thread_blocked with self-suspension check.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
      // Return true since we wouldn't be here unless there was still an
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
      // external suspend request.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
      *bits |= 0x00001000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    } else if (save_state == _thread_in_native && frame_anchor()->walkable()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
      // Threads running native code will self-suspend on native==>VM/Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
      // transitions. If its stack is walkable (should always be the case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
      // unless this function is called before the actual java_suspend()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
      // call), then the wait is done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
      *bits |= 0x00002000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
    } else if (!called_by_wait && !did_trans_retry &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
               save_state == _thread_in_native_trans &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
               frame_anchor()->walkable()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
      // The thread is transitioning from thread_in_native to another
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
      // thread state. check_safepoint_and_suspend_for_native_trans()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      // will force the thread to self-suspend. If it hasn't gotten
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
      // there yet we may have caught the thread in-between the native
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
      // code check above and the self-suspend. Lucky us. If we were
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      // called by wait_for_ext_suspend_completion(), then it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
      // will be doing the retries so we don't have to.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
      // Since we use the saved thread state in the if-statement above,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
      // there is a chance that the thread has already transitioned to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
      // _thread_blocked by the time we get here. In that case, we will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
      // make a single unnecessary pass through the logic below. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      // doesn't hurt anything since we still do the trans retry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
      *bits |= 0x00004000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
      // Once the thread leaves thread_in_native_trans for another
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      // thread state, we break out of this retry loop. We shouldn't
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
      // need this flag to prevent us from getting back here, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
      // sometimes paranoia is good.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
      did_trans_retry = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
      // We wait for the thread to transition to a more usable state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
      for (int i = 1; i <= SuspendRetryCount; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
        // We used to do an "os::yield_all(i)" call here with the intention
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
        // that yielding would increase on each retry. However, the parameter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
        // is ignored on Linux which means the yield didn't scale up. Waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
        // on the SR_lock below provides a much more predictable scale up for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
        // the delay. It also provides a simple/direct point to check for any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
        // safepoint requests from the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
        // temporarily drops SR_lock while doing wait with safepoint check
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
        // (if we're a JavaThread - the WatcherThread can also call this)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
        // and increase delay with each retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
        SR_lock()->wait(!Thread::current()->is_Java_thread(), i * delay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
        // check the actual thread state instead of what we saved above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
        if (thread_state() != _thread_in_native_trans) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
          // the thread has transitioned to another thread state so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
          // try all the checks (except this one) one more time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
          do_trans_retry = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
      } // end retry loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  } while (do_trans_retry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
  *bits |= 0x00000010;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
// Wait for an external suspend request to complete (or be cancelled).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
// Returns true if the thread is externally suspended and false otherwise.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
bool JavaThread::wait_for_ext_suspend_completion(int retries, int delay,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
       uint32_t *bits) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  TraceSuspendDebugBits tsdb(this, true /* is_wait */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
                             false /* !called_by_wait */, bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  // local flag copies to minimize SR_lock hold time
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  bool is_suspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  bool pending;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  uint32_t reset_bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  // set a marker so is_ext_suspend_completed() knows we are the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  *bits |= 0x00010000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  // We use reset_bits to reinitialize the bits value at the top of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
  // each retry loop. This allows the caller to make use of any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  // unused bits for their own marking purposes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  reset_bits = *bits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
    is_suspended = is_ext_suspend_completed(true /* called_by_wait */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
                                            delay, bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    pending = is_external_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  // must release SR_lock to allow suspension to complete
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  if (!pending) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    // A cancelled suspend request is the only false return from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
    // is_ext_suspend_completed() that keeps us from entering the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
    // retry loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
    *bits |= 0x00020000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  if (is_suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    *bits |= 0x00040000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  for (int i = 1; i <= retries; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
    *bits = reset_bits;  // reinit to only track last retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
    // We used to do an "os::yield_all(i)" call here with the intention
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
    // that yielding would increase on each retry. However, the parameter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    // is ignored on Linux which means the yield didn't scale up. Waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
    // on the SR_lock below provides a much more predictable scale up for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
    // the delay. It also provides a simple/direct point to check for any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
    // safepoint requests from the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
      MutexLocker ml(SR_lock());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
      // wait with safepoint check (if we're a JavaThread - the WatcherThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
      // can also call this)  and increase delay with each retry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
      SR_lock()->wait(!Thread::current()->is_Java_thread(), i * delay);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
      is_suspended = is_ext_suspend_completed(true /* called_by_wait */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
                                              delay, bits);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
      // It is possible for the external suspend request to be cancelled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      // (by a resume) before the actual suspend operation is completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      // Refresh our local copy to see if we still need to wait.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
      pending = is_external_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
    if (!pending) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
      // A cancelled suspend request is the only false return from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      // is_ext_suspend_completed() that keeps us from staying in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
      // retry loop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
      *bits |= 0x00080000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
    if (is_suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
      *bits |= 0x00100000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  } // end retry loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  // thread did not suspend after all our retries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
  *bits |= 0x00200000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
void JavaThread::record_jump(address target, address instr, const char* file, int line) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  // This should not need to be atomic as the only way for simultaneous
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  // updates is via interrupts. Even then this should be rare or non-existant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
  // and we don't care that much anyway.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
  int index = _jmp_ring_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  _jmp_ring_index = (index + 1 ) & (jump_ring_buffer_size - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  _jmp_ring[index]._target = (intptr_t) target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  _jmp_ring[index]._instruction = (intptr_t) instr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
  _jmp_ring[index]._file = file;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
  _jmp_ring[index]._line = line;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
#endif /* PRODUCT */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
// Called by flat profiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
// Callers have already called wait_for_ext_suspend_completion
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
// The assertion for that is currently too complex to put here:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
bool JavaThread::profile_last_Java_frame(frame* _fr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  bool gotframe = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  // self suspension saves needed state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  if (has_last_Java_frame() && _anchor.walkable()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
     *_fr = pd_last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
     gotframe = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  return gotframe;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
void Thread::interrupt(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  trace("interrupt", thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  debug_only(check_for_dangling_thread_pointer(thread);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  os::interrupt(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
bool Thread::is_interrupted(Thread* thread, bool clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  trace("is_interrupted", thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  debug_only(check_for_dangling_thread_pointer(thread);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  // Note:  If clear_interrupted==false, this simply fetches and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  // returns the value of the field osthread()->interrupted().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  return os::is_interrupted(thread, clear_interrupted);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
// GC Support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
bool Thread::claim_oops_do_par_case(int strong_roots_parity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  jint thread_parity = _oops_do_parity;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  if (thread_parity != strong_roots_parity) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    jint res = Atomic::cmpxchg(strong_roots_parity, &_oops_do_parity, thread_parity);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10546
diff changeset
   752
    if (res == thread_parity) {
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10546
diff changeset
   753
      return true;
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10546
diff changeset
   754
    } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
      guarantee(res == strong_roots_parity, "Or else what?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
      assert(SharedHeap::heap()->n_par_threads() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
             "Should only fail when parallel.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
  assert(SharedHeap::heap()->n_par_threads() > 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
         "Should only fail when parallel.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
   766
void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  active_handles()->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
  // Do oop for ThreadShadow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  f->do_oop((oop*)&_pending_exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
  handle_area()->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
   773
void Thread::nmethods_do(CodeBlobClosure* cf) {
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
   774
  // no nmethods in a generic thread...
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
void Thread::print_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  // get_priority assumes osthread initialized
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
  if (osthread() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    st->print("prio=%d tid=" INTPTR_FORMAT " ", get_priority(this), this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    osthread()->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  debug_only(if (WizardMode) print_owned_locks_on(st);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
// Thread::print_on_error() is called by fatal error handler. Don't use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
// any lock or allocate memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  if      (is_VM_thread())                  st->print("VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  else if (is_Compiler_thread())            st->print("CompilerThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  else if (is_Java_thread())                st->print("JavaThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
  else if (is_GC_task_thread())             st->print("GCTaskThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  else if (is_Watcher_thread())             st->print("WatcherThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  else if (is_ConcurrentGC_thread())        st->print("ConcurrentGCThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  else st->print("Thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
            _stack_base - _stack_size, _stack_base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  if (osthread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
    st->print(" [id=%d]", osthread()->thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
void Thread::print_owned_locks_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  Monitor *cur = _owned_locks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  if (cur == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
    st->print(" (no locks) ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
    st->print_cr(" Locks owned:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    while(cur) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
      cur->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
      cur = cur->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
static int ref_use_count  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
bool Thread::owns_locks_but_compiled_lock() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
  for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
    if (cur != Compile_lock) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
// The flag: potential_vm_operation notifies if this particular safepoint state could potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
// invoke the vm-thread (i.e., and oop allocation). In that case, we also have to make sure that
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
// no threads which allow_vm_block's are held
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
    // Check if current thread is allowed to block at a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
    if (!(_allow_safepoint_count == 0))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
      fatal("Possible safepoint reached by thread that does not allow it");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    if (is_Java_thread() && ((JavaThread*)this)->thread_state() != _thread_in_vm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
      fatal("LEAF method calling lock?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
    if (potential_vm_operation && is_Java_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
        && !Universe::is_bootstrapping()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
      // Make sure we do not hold any locks that the VM thread also uses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
      // This could potentially lead to deadlocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
      for(Monitor *cur = _owned_locks; cur; cur = cur->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
        // Threads_lock is special, since the safepoint synchronization will not start before this is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
        // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
        // since it is used to transfer control between JavaThreads and the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
        // Do not *exclude* any locks unless you are absolutly sure it is correct. Ask someone else first!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
        if ( (cur->allow_vm_block() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
              cur != Threads_lock &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
              cur != Compile_lock &&               // Temporary: should not be necessary when we get spearate compilation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
              cur != VMOperationRequest_lock &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
              cur != VMOperationQueue_lock) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
              cur->rank() == Mutex::special) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
          warning("Thread holding lock at safepoint that vm can block on: %s", cur->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
    if (GCALotAtAllSafepoints) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
      // We could enter a safepoint here and thus have a gc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
      InterfaceSupport::check_gc_alot();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
bool Thread::is_in_stack(address adr) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  assert(Thread::current() == this, "is_in_stack can only be called from current thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  address end = os::current_stack_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  if (stack_base() >= adr && adr >= end) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
// We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
// However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
// used for compilation in the future. If that change is made, the need for these methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
// should be revisited, and they should be removed if possible.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
bool Thread::is_lock_owned(address adr) const {
6183
4c74cfe14f20 6975078: assert(allocated_on_res_area() || allocated_on_C_heap() || allocated_on_arena()
kvn
parents: 5888
diff changeset
   888
  return on_local_stack(adr);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
bool Thread::set_as_starting_thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
 // NOTE: this must be called inside the main thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
  return os::create_main_thread((JavaThread*)this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   896
static void initialize_class(Symbol* class_name, TRAPS) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
  klassOop klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
  instanceKlass::cast(klass)->initialize(CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
// Creates the initial ThreadGroup
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
static Handle create_initial_thread_group(TRAPS) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   904
  klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ThreadGroup(), true, CHECK_NH);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  Handle system_instance = klass->allocate_instance_handle(CHECK_NH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
    JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
    JavaCalls::call_special(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
                            system_instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
                            klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   913
                            vmSymbols::object_initializer_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   914
                            vmSymbols::void_method_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
                            CHECK_NH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  Universe::set_system_thread_group(system_instance());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  Handle main_instance = klass->allocate_instance_handle(CHECK_NH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    Handle string = java_lang_String::create_from_str("main", CHECK_NH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
    JavaCalls::call_special(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
                            main_instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
                            klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   926
                            vmSymbols::object_initializer_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   927
                            vmSymbols::threadgroup_string_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
                            system_instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
                            string,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
                            CHECK_NH);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  return main_instance;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
// Creates the initial Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   937
  klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  java_lang_Thread::set_thread(thread_oop(), thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  java_lang_Thread::set_priority(thread_oop(), NormPriority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  thread->set_threadObj(thread_oop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  Handle string = java_lang_String::create_from_str("main", CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  JavaCalls::call_special(&result, thread_oop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
                                   klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   950
                                   vmSymbols::object_initializer_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   951
                                   vmSymbols::threadgroup_string_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
                                   thread_group,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
                                   string,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
                                   CHECK_NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  return thread_oop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
static void call_initializeSystemClass(TRAPS) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   959
  klassOop k =  SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  JavaValue result(T_VOID);
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   963
  JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   964
                                         vmSymbols::void_method_signature(), CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
7900
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   967
// General purpose hook into Java code, run once when the VM is initialized.
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   968
// The Java library method itself may be changed independently from the VM.
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   969
static void call_postVMInitHook(TRAPS) {
10546
e79347eebbc5 7086585: make Java field injection more flexible
never
parents: 10517
diff changeset
   970
  klassOop k = SystemDictionary::PostVMInitHook_klass();
7900
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   971
  instanceKlassHandle klass (THREAD, k);
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   972
  if (klass.not_null()) {
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   973
    JavaValue result(T_VOID);
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   974
    JavaCalls::call_static(&result, klass, vmSymbols::run_method_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   975
                                           vmSymbols::void_method_signature(),
7900
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   976
                                           CHECK);
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   977
  }
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   978
}
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
   979
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
static void reset_vm_info_property(TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  // the vm info string
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  ResourceMark rm(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  const char *vm_info = VM_Version::vm_info_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  // java.lang.System class
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   986
  klassOop k =  SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
  // setProperty arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  Handle key_str    = java_lang_String::create_from_str("java.vm.info", CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  Handle value_str  = java_lang_String::create_from_str(vm_info, CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
  // return value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  JavaValue r(T_OBJECT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  // public static String setProperty(String key, String value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  JavaCalls::call_static(&r,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
                         klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
   999
                         vmSymbols::setProperty_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1000
                         vmSymbols::string_string_string_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
                         key_str,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
                         value_str,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
                         CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
void JavaThread::allocate_threadObj(Handle thread_group, char* thread_name, bool daemon, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
  assert(thread_group.not_null(), "thread group should be specified");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  assert(threadObj() == NULL, "should only create Java thread object once");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1011
  klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
  instanceKlassHandle klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  instanceHandle thread_oop = klass->allocate_instance_handle(CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  java_lang_Thread::set_thread(thread_oop(), this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  java_lang_Thread::set_priority(thread_oop(), NormPriority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
  set_threadObj(thread_oop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  if (thread_name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    Handle name = java_lang_String::create_from_str(thread_name, CHECK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    // Thread gets assigned specified name and null target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    JavaCalls::call_special(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
                            thread_oop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
                            klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1026
                            vmSymbols::object_initializer_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1027
                            vmSymbols::threadgroup_string_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
                            thread_group, // Argument 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
                            name,         // Argument 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
                            THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    // Thread gets assigned name "Thread-nnn" and null target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    // (java.lang.Thread doesn't have a constructor taking only a ThreadGroup argument)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    JavaCalls::call_special(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
                            thread_oop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
                            klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1037
                            vmSymbols::object_initializer_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1038
                            vmSymbols::threadgroup_runnable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
                            thread_group, // Argument 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
                            Handle(),     // Argument 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
                            THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
  if (daemon) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
      java_lang_Thread::set_daemon(thread_oop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1053
  KlassHandle group(this, SystemDictionary::ThreadGroup_klass());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
  Handle threadObj(this, this->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
  JavaCalls::call_special(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
                         thread_group,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
                         group,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1059
                         vmSymbols::add_method_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1060
                         vmSymbols::thread_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
                         threadObj,          // Arg 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
                         THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
// NamedThread --  non-JavaThread subclasses with multiple
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
// uniquely named instances should derive from this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
NamedThread::NamedThread() : Thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  _name = NULL;
4489
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  1071
  _processed_thread = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
NamedThread::~NamedThread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  if (_name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
    FREE_C_HEAP_ARRAY(char, _name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    _name = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
void NamedThread::set_name(const char* format, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
  guarantee(_name == NULL, "Only get to set name once.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
  _name = NEW_C_HEAP_ARRAY(char, max_name_len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  guarantee(_name != NULL, "alloc failure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  va_list ap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  va_start(ap, format);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
  jio_vsnprintf(_name, max_name_len, format, ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
  va_end(ap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
// ======= WatcherThread ========
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
// The watcher thread exists to simulate timer interrupts.  It should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
// be replaced by an abstraction over whatever native support for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
// timer interrupts exists on the platform.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
WatcherThread* WatcherThread::_watcher_thread   = NULL;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1098
volatile bool  WatcherThread::_should_terminate = false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
WatcherThread::WatcherThread() : Thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  if (os::create_thread(this, os::watcher_thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
    _watcher_thread = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
    // Set the watcher thread to the highest OS priority which should not be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    // used, unless a Java thread with priority java.lang.Thread.MAX_PRIORITY
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
    // is created. The only normal thread using this priority is the reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    // handler thread, which runs for very short intervals only.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    // If the VMThread's priority is not lower than the WatcherThread profiling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    // will be inaccurate.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
    os::set_priority(this, MaxPriority);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
    if (!DisableStartThread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
      os::start_thread(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
void WatcherThread::run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
  assert(this == watcher_thread(), "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
  this->record_stack_base_and_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
  this->initialize_thread_local_storage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
  this->set_active_handles(JNIHandleBlock::allocate_block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  while(!_should_terminate) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
    assert(watcher_thread() == Thread::current(),  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
    assert(watcher_thread() == this,  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    // Calculate how long it'll be until the next PeriodicTask work
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    // should be done, and sleep that amount of time.
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1130
    size_t time_to_wait = PeriodicTask::time_to_wait();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1131
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1132
    // we expect this to timeout - we only ever get unparked when
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1133
    // we should terminate
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1134
    {
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1135
      OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1136
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1137
      jlong prev_time = os::javaTimeNanos();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1138
      for (;;) {
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1139
        int res= _SleepEvent->park(time_to_wait);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1140
        if (res == OS_TIMEOUT || _should_terminate)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1141
          break;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1142
        // spurious wakeup of some kind
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1143
        jlong now = os::javaTimeNanos();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1144
        time_to_wait -= (now - prev_time) / 1000000;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1145
        if (time_to_wait <= 0)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1146
          break;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1147
        prev_time = now;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1148
      }
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1149
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
    if (is_error_reported()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
      // A fatal error has happened, the error handler(VMError::report_and_die)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
      // should abort JVM after creating an error log file. However in some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
      // rare cases, the error handler itself might deadlock. Here we try to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
      // kill JVM if the fatal error handler fails to abort in 2 minutes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
      // This code is in WatcherThread because WatcherThread wakes up
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
      // periodically so the fatal error handler doesn't need to do anything;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
      // also because the WatcherThread is less likely to crash than other
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
      // threads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
      for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
        if (!ShowMessageBoxOnError
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
         && (OnError == NULL || OnError[0] == '\0')
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
         && Arguments::abort_hook() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
             os::sleep(this, 2 * 60 * 1000, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
             fdStream err(defaultStream::output_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
             err.print_raw_cr("# [ timer expired, abort... ]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
             // skip atexit/vm_exit/vm_abort hooks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
             os::die();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
        // Wake up 5 seconds later, the fatal handler may reset OnError or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
        // ShowMessageBoxOnError when it is ready to abort.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
        os::sleep(this, 5 * 1000, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
    PeriodicTask::real_time_tick(time_to_wait);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
    // If we have no more tasks left due to dynamic disenrollment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
    // shut down the thread since we don't currently support dynamic enrollment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    if (PeriodicTask::num_tasks() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
      _should_terminate = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
  // Signal that it is terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    _watcher_thread = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    Terminator_lock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
  // Thread destructor usually does this..
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
  ThreadLocalStorage::set_thread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
void WatcherThread::start() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
  if (watcher_thread() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    _should_terminate = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    // Create the single instance of WatcherThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    new WatcherThread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
void WatcherThread::stop() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
  // it is ok to take late safepoints here, if needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
  MutexLocker mu(Terminator_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
  _should_terminate = true;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1211
  OrderAccess::fence();  // ensure WatcherThread sees update in main loop
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1212
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1213
  Thread* watcher = watcher_thread();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1214
  if (watcher != NULL)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1215
    watcher->_SleepEvent->unpark();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1216
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  while(watcher_thread() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    // This wait should make safepoint checks, wait without a timeout,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
    // and wait as a suspend-equivalent condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
    // Note: If the FlatProfiler is running, then this thread is waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
    // for the WatcherThread to terminate and the WatcherThread, via the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
    // FlatProfiler task, is waiting for the external suspend request on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
    // this thread to complete. wait_for_ext_suspend_completion() will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
    // eventually timeout, but that takes time. Making this wait a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
    // suspend-equivalent condition solves that timeout problem.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
    Terminator_lock->wait(!Mutex::_no_safepoint_check_flag, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
                          Mutex::_as_suspend_equivalent_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
void WatcherThread::print_on(outputStream* st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
  st->print("\"%s\" ", name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
  Thread::print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
// ======= JavaThread ========
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
// A JavaThread is a normal Java thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
void JavaThread::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
  // Initialize fields
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1245
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1246
  // Set the claimed par_id to -1 (ie not claiming any par_ids)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1247
  set_claimed_par_id(-1);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1248
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  set_saved_exception_pc(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  set_threadObj(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
  _anchor.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
  set_entry_point(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  set_jni_functions(jni_functions());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
  set_callee_target(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
  set_vm_result(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  set_vm_result_2(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  set_vframe_array_head(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  set_vframe_array_last(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  set_deferred_locals(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
  set_deopt_mark(NULL);
6740
2bc601284215 6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents: 6273
diff changeset
  1261
  set_deopt_nmethod(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
  clear_must_deopt_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
  set_monitor_chunks(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
  set_next(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
  set_thread_state(_thread_new);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  _terminated = _not_terminated;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
  _privileged_stack_top = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  _array_for_gc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
  _suspend_equivalent = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
  _in_deopt_handler = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
  _doing_unsafe_access = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
  _stack_guard_state = stack_guard_unused;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
  _exception_oop = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
  _exception_pc  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
  _exception_handler_pc = 0;
7104
0c8b519af363 6990192: VM crashes in ciTypeFlow::get_block_for()
twisti
parents: 6769
diff changeset
  1276
  _is_method_handle_return = 0;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
  _jvmti_thread_state= NULL;
4761
bdb7375a1fee 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 4637
diff changeset
  1278
  _should_post_on_exceptions_flag = JNI_FALSE;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
  _jvmti_get_loaded_classes_closure = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  _interp_only_mode    = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
  _special_runtime_exit_condition = _no_async_condition;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
  _pending_async_exception = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
  _is_compiling = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
  _thread_stat = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
  _thread_stat = new ThreadStatistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
  _blocked_on_compilation = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
  _jni_active_critical = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
  _do_not_unlock_if_synchronized = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
  _cached_monitor_info = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  _parker = Parker::Allocate(this) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  _jmp_ring_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  for (int ji = 0 ; ji < jump_ring_buffer_size ; ji++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
    record_jump(NULL, NULL, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
#endif /* PRODUCT */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  set_thread_profiler(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  if (FlatProfiler::is_active()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
    // This is where we would decide to either give each thread it's own profiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    // or use one global one from FlatProfiler,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    // or up to some count of the number of profiled threads, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
    ThreadProfiler* pp = new ThreadProfiler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
    pp->engage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    set_thread_profiler(pp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
  // Setup safepoint state info for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
  ThreadSafepointState::create(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
  debug_only(_java_call_counter = 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  // JVMTI PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  _popframe_condition = popframe_inactive;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  _popframe_preserved_args = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
  _popframe_preserved_args_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  pd_initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1322
#ifndef SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1323
SATBMarkQueueSet JavaThread::_satb_mark_queue_set;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1324
DirtyCardQueueSet JavaThread::_dirty_card_queue_set;
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1325
#endif // !SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1326
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1327
JavaThread::JavaThread(bool is_attaching) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1328
  Thread()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1329
#ifndef SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1330
  , _satb_mark_queue(&_satb_mark_queue_set),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1331
  _dirty_card_queue(&_dirty_card_queue_set)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1332
#endif // !SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1333
{
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
  initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  _is_attaching = is_attaching;
4030
4c471254865e 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 3916
diff changeset
  1336
  assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
bool JavaThread::reguard_stack(address cur_sp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  if (_stack_guard_state != stack_guard_yellow_disabled) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
    return true; // Stack already guarded or guard pages not needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
  if (register_stack_overflow()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
    // For those architectures which have separate register and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
    // memory stacks, we must check the register stack to see if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
    // it has overflowed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
  // Java code never executes within the yellow zone: the latter is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
  // there to provoke an exception during stack banging.  If java code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
  // is executing there, either StackShadowPages should be larger, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
  // some exception code in c1, c2 or the interpreter isn't unwinding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
  // when it should.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
  guarantee(cur_sp > stack_yellow_zone_base(), "not enough space to reguard - increase StackShadowPages");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
  enable_stack_yellow_zone();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
bool JavaThread::reguard_stack(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  return reguard_stack(os::current_stack_pointer());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
void JavaThread::block_if_vm_exited() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  if (_terminated == _vm_exited) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
    // _vm_exited is set at safepoint, and Threads_lock is never released
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
    // we will block here forever
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
    Threads_lock->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
    ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
// Remove this ifdef when C1 is ported to the compiler interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
static void compiler_thread_entry(JavaThread* thread, TRAPS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1380
JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) :
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1381
  Thread()
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1382
#ifndef SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1383
  , _satb_mark_queue(&_satb_mark_queue_set),
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1384
  _dirty_card_queue(&_dirty_card_queue_set)
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1385
#endif // !SERIALGC
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  1386
{
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
  if (TraceThreadEvents) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
    tty->print_cr("creating thread %p", this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  _is_attaching = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  set_entry_point(entry_point);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
  // Create the native thread itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  // %note runtime_23
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  os::ThreadType thr_type = os::java_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
                                                     os::java_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  os::create_thread(this, thr_type, stack_sz);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
  // The _osthread may be NULL here because we ran out of memory (too many threads active).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
  // We need to throw and OutOfMemoryError - however we cannot do this here because the caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
  // may hold a lock and all locks must be unlocked before throwing the exception (throwing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
  // the exception consists of creating the exception object & initializing it, initialization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
  // will leave the VM via a JavaCall and then all locks must be unlocked).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
  // The thread is still suspended when we reach here. Thread must be explicit started
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  // by creator! Furthermore, the thread must also explicitly be added to the Threads list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
  // by calling Threads:add. The reason why this is not done here, is because the thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  // object must be fully initialized (take a look at JVM_Start)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
JavaThread::~JavaThread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
  if (TraceThreadEvents) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
      tty->print_cr("terminate thread %p", this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
  // JSR166 -- return the parker to the free list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
  Parker::Release(_parker);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
  _parker = NULL ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
  // Free any remaining  previous UnrollBlock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
  vframeArray* old_array = vframe_array_last();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
  if (old_array != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
    Deoptimization::UnrollBlock* old_info = old_array->unroll_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    old_array->set_unroll_block(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
    delete old_info;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
    delete old_array;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
  GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = deferred_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  if (deferred != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
    // This can only happen if thread is destroyed before deoptimization occurs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
    assert(deferred->length() != 0, "empty array!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
      jvmtiDeferredLocalVariableSet* dlv = deferred->at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
      deferred->remove_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
      // individual jvmtiDeferredLocalVariableSet are CHeapObj's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
      delete dlv;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
    } while (deferred->length() != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
    delete deferred;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
  // All Java related clean up happens in exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
  ThreadSafepointState::destroy(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  if (_thread_profiler != NULL) delete _thread_profiler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
  if (_thread_stat != NULL) delete _thread_stat;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
// The first routine called by a new Java thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
void JavaThread::run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
  // initialize thread-local alloc buffer related fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
  this->initialize_tlab();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
  // used to test validitity of stack trace backs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
  this->record_base_of_stack_pointer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
  // Record real stack base and size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  this->record_stack_base_and_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  // Initialize thread local storage; set before calling MutexLocker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
  this->initialize_thread_local_storage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
  this->create_stack_guard_pages();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1467
  this->cache_global_variables();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  1468
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
  // Thread is now sufficient initialized to be handled by the safepoint code as being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
  // in the VM. Change thread state from _thread_new to _thread_in_vm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
  ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
  assert(JavaThread::current() == this, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  assert(!Thread::current()->owns_locks(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
  DTRACE_THREAD_PROBE(start, this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  // This operation might block. We call that after all safepoint checks for a new thread has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
  // been completed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
  this->set_active_handles(JNIHandleBlock::allocate_block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
  if (JvmtiExport::should_post_thread_life()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
    JvmtiExport::post_thread_start(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
  // We call another function to do the rest so we are sure that the stack addresses used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
  // from there will be lower than the stack base just computed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
  thread_main_inner();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
  // Note, thread is no longer valid at this point!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
void JavaThread::thread_main_inner() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
  assert(JavaThread::current() == this, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
  assert(this->threadObj() != NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
8061
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1498
  // Execute thread entry point unless this thread has a pending exception
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1499
  // or has been stopped before starting.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
  // Note: Due to JVM_StopThread we can have pending exceptions already!
8061
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1501
  if (!this->has_pending_exception() &&
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1502
      !java_lang_Thread::is_stillborn(this->threadObj())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
    HandleMark hm(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
    this->entry_point()(this, this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
  DTRACE_THREAD_PROBE(stop, this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
  this->exit(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  delete this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
static void ensure_join(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
  // We do not need to grap the Threads_lock, since we are operating on ourself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
  Handle threadObj(thread, thread->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
  assert(threadObj.not_null(), "java thread object must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
  ObjectLocker lock(threadObj, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
  // Ignore pending exception (ThreadDeath), since we are exiting anyway
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
  thread->clear_pending_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
  // Thread is exiting. So set thread_status field in  java.lang.Thread class to TERMINATED.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
  java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
8061
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1523
  // Clear the native thread instance - this makes isAlive return false and allows the join()
07585870d15f 6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
dholmes
parents: 7900
diff changeset
  1524
  // to complete once we've done the notify_all below
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
  java_lang_Thread::set_thread(threadObj(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
  lock.notify_all(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
  // Ignore pending exception (ThreadDeath), since we are exiting anyway
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
  thread->clear_pending_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1531
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
// For any new cleanup additions, please check to see if they need to be applied to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
// cleanup_failed_attach_current_thread as well.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
  assert(this == JavaThread::current(),  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  if (!InitializeJavaLangSystem) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
  HandleMark hm(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
  Handle uncaught_exception(this, this->pending_exception());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
  this->clear_pending_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
  Handle threadObj(this, this->threadObj());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
  assert(threadObj.not_null(), "Java thread object should be created");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  if (get_thread_profiler() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
    get_thread_profiler()->disengage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
    get_thread_profiler()->print(get_thread_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  // FIXIT: This code should be moved into else part, when reliable 1.2/1.3 check is in place
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
    EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
  // FIXIT: The is_null check is only so it works better on JDK1.2 VM's. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
  // has to be fixed by a runtime query method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
  if (!destroy_vm || JDK_Version::is_jdk12x_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
    // JSR-166: change call from from ThreadGroup.uncaughtException to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    // java.lang.Thread.dispatchUncaughtException
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
    if (uncaught_exception.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
      Handle group(this, java_lang_Thread::threadGroup(threadObj()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
      Events::log("uncaught exception INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
        (address)uncaught_exception(), (address)threadObj(), (address)group());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
        EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
        // Check if the method Thread.dispatchUncaughtException() exists. If so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
        // call it.  Otherwise we have an older library without the JSR-166 changes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
        // so call ThreadGroup.uncaughtException()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
        KlassHandle recvrKlass(THREAD, threadObj->klass());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
        CallInfo callinfo;
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1573
        KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
        LinkResolver::resolve_virtual_call(callinfo, threadObj, recvrKlass, thread_klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1575
                                           vmSymbols::dispatchUncaughtException_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1576
                                           vmSymbols::throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
                                           KlassHandle(), false, false, THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
        CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
        methodHandle method = callinfo.selected_method();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
        if (method.not_null()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
          JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
          JavaCalls::call_virtual(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
                                  threadObj, thread_klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1584
                                  vmSymbols::dispatchUncaughtException_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1585
                                  vmSymbols::throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
                                  uncaught_exception,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
                                  THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
        } else {
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1589
          KlassHandle thread_group(THREAD, SystemDictionary::ThreadGroup_klass());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
          JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
          JavaCalls::call_virtual(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
                                  group, thread_group,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1593
                                  vmSymbols::uncaughtException_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1594
                                  vmSymbols::thread_throwable_void_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
                                  threadObj,           // Arg 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
                                  uncaught_exception,  // Arg 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
                                  THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
        }
8115
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1599
        if (HAS_PENDING_EXCEPTION) {
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1600
          ResourceMark rm(this);
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1601
          jio_fprintf(defaultStream::error_stream(),
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1602
                "\nException: %s thrown from the UncaughtExceptionHandler"
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1603
                " in thread \"%s\"\n",
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1604
                Klass::cast(pending_exception()->klass())->external_name(),
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1605
                get_thread_name());
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1606
          CLEAR_PENDING_EXCEPTION;
1b3ccddac0ab 6472925: OutOfMemoryError fails to generate stack trace as it now ought
coleenp
parents: 8076
diff changeset
  1607
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
    // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
    // the execution of the method. If that is not enough, then we don't really care. Thread.stop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
    // is deprecated anyhow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
    { int count = 3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
      while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
        EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
        JavaValue result(T_VOID);
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1618
        KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
        JavaCalls::call_virtual(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
                              threadObj, thread_klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1621
                              vmSymbols::exit_method_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  1622
                              vmSymbols::void_method_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
                              THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
        CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
    // notify JVMTI
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
    if (JvmtiExport::should_post_thread_life()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
      JvmtiExport::post_thread_end(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
    // We have notified the agents that we are exiting, before we go on,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
    // we must check for a pending external suspend request and honor it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
    // in order to not surprise the thread that made the suspend request.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
    while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
        MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
        if (!is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
          set_terminated(_thread_exiting);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
          ThreadService::current_thread_exiting(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
        // Implied else:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
        // Things get a little tricky here. We have a pending external
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
        // suspend request, but we are holding the SR_lock so we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
        // can't just self-suspend. So we temporarily drop the lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
        // and then self-suspend.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
      ThreadBlockInVM tbivm(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
      java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
      // We're done with this suspend request, but we have to loop around
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
      // and check again. Eventually we will get SR_lock without a pending
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
      // external suspend request and will be able to mark ourselves as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
      // exiting.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
    // no more external suspends are allowed at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
    // before_exit() has already posted JVMTI THREAD_END events
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
  // Notify waiters on thread object. This has to be done after exit() is called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
  // on the thread (if the thread is the last thread in a daemon ThreadGroup the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
  // group should have the destroyed bit set before waiters are notified).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  ensure_join(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  assert(!this->has_pending_exception(), "ensure_join should have cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
  // 6282335 JNI DetachCurrentThread spec states that all Java monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
  // held by this thread must be released.  A detach operation must only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  // get here if there are no Java frames on the stack.  Therefore, any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
  // owned monitors at this point MUST be JNI-acquired monitors which are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
  // pre-inflated and in the monitor cache.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
  // ensure_join() ignores IllegalThreadStateExceptions, and so does this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
  if (exit_type == jni_detach && JNIDetachReleasesMonitors) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
    assert(!this->has_last_Java_frame(), "detaching with Java frames?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
    ObjectSynchronizer::release_monitors_owned_by_thread(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
    assert(!this->has_pending_exception(), "release_monitors should have cleared");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
  // These things needs to be done while we are still a Java Thread. Make sure that thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
  // is in a consistent state, in case GC happens
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
  assert(_privileged_stack_top == NULL, "must be NULL when we get here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
  if (active_handles() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
    JNIHandleBlock* block = active_handles();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
    set_active_handles(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
    JNIHandleBlock::release_block(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  if (free_handle_block() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
    JNIHandleBlock* block = free_handle_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
    set_free_handle_block(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
    JNIHandleBlock::release_block(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  // These have to be removed while this is still a valid thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
  remove_stack_guard_pages();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
  if (UseTLAB) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
    tlab().make_parsable(true);  // retire TLAB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
7897
201a8b00ec91 6814943: getcpool001 catches more than one JvmtiThreadState problem
kamg
parents: 7724
diff changeset
  1706
  if (JvmtiEnv::environments_might_exist()) {
222
3d1795325749 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 1
diff changeset
  1707
    JvmtiExport::cleanup_thread(this);
3d1795325749 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 1
diff changeset
  1708
  }
3d1795325749 6453355: 4/4 new No_Safepoint_Verifier uses fail during GC
dcubed
parents: 1
diff changeset
  1709
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1710
#ifndef SERIALGC
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1711
  // We must flush G1-related buffers before removing a thread from
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1712
  // the list of active threads.
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1713
  if (UseG1GC) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1714
    flush_barrier_queues();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1715
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1716
#endif
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1717
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
  // Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
  Threads::remove(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1722
#ifndef SERIALGC
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1723
// Flush G1-related queues.
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1724
void JavaThread::flush_barrier_queues() {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1725
  satb_mark_queue().flush();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1726
  dirty_card_queue().flush();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1727
}
6768
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1728
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1729
void JavaThread::initialize_queues() {
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1730
  assert(!SafepointSynchronize::is_at_safepoint(),
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1731
         "we should not be at a safepoint");
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1732
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1733
  ObjPtrQueue& satb_queue = satb_mark_queue();
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1734
  SATBMarkQueueSet& satb_queue_set = satb_mark_queue_set();
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1735
  // The SATB queue should have been constructed with its active
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1736
  // field set to false.
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1737
  assert(!satb_queue.is_active(), "SATB queue should not be active");
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1738
  assert(satb_queue.is_empty(), "SATB queue should be empty");
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1739
  // If we are creating the thread during a marking cycle, we should
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1740
  // set the active field of the SATB queue to true.
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1741
  if (satb_queue_set.is_active()) {
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1742
    satb_queue.set_active(true);
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1743
  }
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1744
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1745
  DirtyCardQueue& dirty_queue = dirty_card_queue();
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1746
  // The dirty card queue should have been constructed with its
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1747
  // active field set to true.
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1748
  assert(dirty_queue.is_active(), "dirty card queue should be active");
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1749
}
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  1750
#endif // !SERIALGC
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1751
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
void JavaThread::cleanup_failed_attach_current_thread() {
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1753
  if (get_thread_profiler() != NULL) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1754
    get_thread_profiler()->disengage();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1755
    ResourceMark rm;
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1756
    get_thread_profiler()->print(get_thread_name());
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1757
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1758
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1759
  if (active_handles() != NULL) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1760
    JNIHandleBlock* block = active_handles();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1761
    set_active_handles(NULL);
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1762
    JNIHandleBlock::release_block(block);
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1763
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1764
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1765
  if (free_handle_block() != NULL) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1766
    JNIHandleBlock* block = free_handle_block();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1767
    set_free_handle_block(NULL);
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1768
    JNIHandleBlock::release_block(block);
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1769
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1770
5041
5bce37d77dde 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 4761
diff changeset
  1771
  // These have to be removed while this is still a valid thread.
5bce37d77dde 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 4761
diff changeset
  1772
  remove_stack_guard_pages();
5bce37d77dde 6914050: jvm assertion "guard pages must be in use" in -Xcomp mode
coleenp
parents: 4761
diff changeset
  1773
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1774
  if (UseTLAB) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1775
    tlab().make_parsable(true);  // retire TLAB, if any
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1776
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1777
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1778
#ifndef SERIALGC
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1779
  if (UseG1GC) {
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1780
    flush_barrier_queues();
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1781
  }
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1782
#endif
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1783
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1784
  Threads::remove(this);
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1785
  delete this;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
1560
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1789
1b328492b7f8 6770608: G1: Mutator thread can flush barrier and satb queues during safepoint
iveresov
parents: 1415
diff changeset
  1790
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
JavaThread* JavaThread::active() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  Thread* thread = ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
  assert(thread != NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
  if (thread->is_Java_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
    return (JavaThread*) thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
    assert(thread->is_VM_thread(), "this must be a vm thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
    VM_Operation* op = ((VMThread*) thread)->vm_operation();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    JavaThread *ret=op == NULL ? NULL : (JavaThread *)op->calling_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
    assert(ret->is_Java_thread(), "must be a Java thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
    return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
bool JavaThread::is_lock_owned(address adr) const {
2526
39a58a50be35 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 2336
diff changeset
  1806
  if (Thread::is_lock_owned(adr)) return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
  for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
    if (chunk->contains(adr)) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
void JavaThread::add_monitor_chunk(MonitorChunk* chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  chunk->set_next(monitor_chunks());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
  set_monitor_chunks(chunk);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
void JavaThread::remove_monitor_chunk(MonitorChunk* chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
  guarantee(monitor_chunks() != NULL, "must be non empty");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  if (monitor_chunks() == chunk) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
    set_monitor_chunks(chunk->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
    MonitorChunk* prev = monitor_chunks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
    while (prev->next() != chunk) prev = prev->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
    prev->set_next(chunk->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
// JVM support.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
// Note: this function shouldn't block if it's called in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
// _thread_in_native_trans state (such as from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
// check_special_condition_for_native_trans()).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
void JavaThread::check_and_handle_async_exceptions(bool check_unsafe_error) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
  if (has_last_Java_frame() && has_async_condition()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
    // If we are at a polling page safepoint (not a poll return)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
    // then we must defer async exception because live registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
    // will be clobbered by the exception path. Poll return is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
    // ok because the call we a returning from already collides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
    // with exception handling registers and so there is no issue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
    // (The exception handling path kills call result registers but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
    //  this is ok since the exception kills the result anyway).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
    if (is_at_poll_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
      // if the code we are returning to has deoptimized we must defer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
      // the exception otherwise live registers get clobbered on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
      // exception path before deoptimization is able to retrieve them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
      RegisterMap map(this, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
      frame caller_fr = last_frame().sender(&map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
      assert(caller_fr.is_compiled_frame(), "what?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
      if (caller_fr.is_deoptimized_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
        if (TraceExceptions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1858
          ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1859
          tty->print_cr("deferred async exception at compiled safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1860
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1861
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1862
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1863
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1864
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
  JavaThread::AsyncRequests condition = clear_special_runtime_exit_condition();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
  if (condition == _no_async_condition) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
    // Conditions have changed since has_special_runtime_exit_condition()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
    // was called:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
    // - if we were here only because of an external suspend request,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
    //   then that was taken care of above (or cancelled) so we are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
    // - if we were here because of another async request, then it has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
    //   been cleared between the has_special_runtime_exit_condition()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
    //   and now so again we are done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
  // Check for pending async. exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1879
  if (_pending_async_exception != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1880
    // Only overwrite an already pending exception, if it is not a threadDeath.
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1881
    if (!has_pending_exception() || !pending_exception()->is_a(SystemDictionary::ThreadDeath_klass())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1882
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1883
      // We cannot call Exceptions::_throw(...) here because we cannot block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1884
      set_pending_exception(_pending_async_exception, __FILE__, __LINE__);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1886
      if (TraceExceptions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
        ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
        tty->print("Async. exception installed at runtime exit (" INTPTR_FORMAT ")", this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
        if (has_last_Java_frame() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
          frame f = last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
          tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", f.pc(), f.sp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
        tty->print_cr(" of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
      _pending_async_exception = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
      clear_has_async_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  if (check_unsafe_error &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
      condition == _async_unsafe_access_error && !has_pending_exception()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
    condition = _no_async_condition;  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
    switch (thread_state()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
    case _thread_in_vm:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
        JavaThread* THREAD = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
        THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
    case _thread_in_native:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
        ThreadInVMfromNative tiv(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
        JavaThread* THREAD = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
        THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
    case _thread_in_Java:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
        ThreadInVMfromJava tiv(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
        JavaThread* THREAD = this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
        THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in a recent unsafe memory access operation in compiled Java code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  assert(condition == _no_async_condition || has_pending_exception() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
         (!check_unsafe_error && condition == _async_unsafe_access_error),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
         "must have handled the async condition, if no exception");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
void JavaThread::handle_special_runtime_exit_condition(bool check_asyncs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
  // Check for pending external suspend. Internal suspend requests do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  // not use handle_special_runtime_exit_condition().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  // If JNIEnv proxies are allowed, don't self-suspend if the target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  // thread is not the current thread. In older versions of jdbx, jdbx
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
  // threads could call into the VM with another thread's JNIEnv so we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  // can be here operating on behalf of a suspended thread (4432884).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
  bool do_self_suspend = is_external_suspend_with_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
  if (do_self_suspend && (!AllowJNIEnvProxy || this == JavaThread::current())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
    // Because thread is external suspended the safepoint code will count
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
    // thread as at a safepoint. This can be odd because we can be here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
    // as _thread_in_Java which would normally transition to _thread_blocked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
    // at a safepoint. We would like to mark the thread as _thread_blocked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
    // before calling java_suspend_self like all other callers of it but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
    // we must then observe proper safepoint protocol. (We can't leave
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
    // _thread_blocked with a safepoint in progress). However we can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
    // here as _thread_in_native_trans so we can't use a normal transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
    // constructor/destructor pair because they assert on that type of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
    // transition. We could do something like:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
    // JavaThreadState state = thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    // set_thread_state(_thread_in_vm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    // {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    //   ThreadBlockInVM tbivm(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    //   java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
    // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
    // set_thread_state(_thread_in_vm_trans);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
    // if (safepoint) block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
    // set_thread_state(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
    // but that is pretty messy. Instead we just go with the way the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
    // code has worked before and note that this is the only path to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
    // java_suspend_self that doesn't put the thread in _thread_blocked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
    // mode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
    frame_anchor()->make_walkable(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
    java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
    // We might be here for reasons in addition to the self-suspend request
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
    // so check for other async requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  if (check_asyncs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    check_and_handle_async_exceptions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
void JavaThread::send_thread_stop(oop java_throwable)  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  assert(Thread::current()->is_VM_thread(), "should be in the vm thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
  assert(Threads_lock->is_locked(), "Threads_lock should be locked by safepoint code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
  assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1985
  // Do not throw asynchronous exceptions against the compiler thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1986
  // (the compiler thread should not be a Java thread -- fix in 1.4.2)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1987
  if (is_Compiler_thread()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1989
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1990
    // Actually throw the Throwable against the target Thread - however
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1991
    // only if there is no thread death exception installed already.
4571
80b553bddc26 6914300: ciEnv should export all well known classes
never
parents: 4564
diff changeset
  1992
    if (_pending_async_exception == NULL || !_pending_async_exception->is_a(SystemDictionary::ThreadDeath_klass())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1993
      // If the topmost frame is a runtime stub, then we are calling into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1994
      // OptoRuntime from compiled code. Some runtime stubs (new, monitor_exit..)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
      // must deoptimize the caller before continuing, as the compiled  exception handler table
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
      // may not be valid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
      if (has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
        frame f = last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
        if (f.is_runtime_frame() || f.is_safepoint_blob_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
          // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
          RegisterMap reg_map(this, UseBiasedLocking);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
          frame compiled_frame = f.sender(&reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
          if (compiled_frame.can_be_deoptimized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
            Deoptimization::deoptimize(this, compiled_frame, &reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
      // Set async. pending exception in thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
      set_pending_async_exception(java_throwable);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
      if (TraceExceptions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
       ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
       tty->print_cr("Pending Async. exception installed of type: %s", instanceKlass::cast(_pending_async_exception->klass())->external_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
      // for AbortVMOnException flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
      NOT_PRODUCT(Exceptions::debug_check_abort(instanceKlass::cast(_pending_async_exception->klass())->external_name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  // Interrupt thread so it will wake up from a potential wait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
  Thread::interrupt(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
// External suspension mechanism.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
// Tell the VM to suspend a thread when ever it knows that it does not hold on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
// to any VM_locks and it is at a transition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
// Self-suspension will happen on the transition out of the vm.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
// Catch "this" coming in from JNIEnv pointers when the thread has been freed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
// Guarantees on return:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
//   + Target thread will not execute any new bytecode (that's why we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
//     force a safepoint)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
//   + Target thread will not enter any new monitors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
void JavaThread::java_suspend() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
  { MutexLocker mu(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
    if (!Threads::includes(this) || is_exiting() || this->threadObj() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
       return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
  { MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
    if (!is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
      // a racing resume has cancelled us; bail out now
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
    // suspend is done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
    uint32_t debug_bits = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
    // Warning: is_ext_suspend_completed() may temporarily drop the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
    // SR_lock to allow the thread to reach a stable thread state if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
    // it is currently in a transient thread state.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
    if (is_ext_suspend_completed(false /* !called_by_wait */,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2057
                                 SuspendRetryDelay, &debug_bits) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2060
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
  VM_ForceSafepoint vm_suspend;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
  VMThread::execute(&vm_suspend);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
// Part II of external suspension.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
// A JavaThread self suspends when it detects a pending external suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
// request. This is usually on transitions. It is also done in places
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
// where continuing to the next transition would surprise the caller,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
// e.g., monitor entry.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
// Returns the number of times that the thread self-suspended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
// Note: DO NOT call java_suspend_self() when you just want to block current
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
//       thread. java_suspend_self() is the second stage of cooperative
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
//       suspension for external suspend requests and should only be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
//       to complete an external suspend request.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
int JavaThread::java_suspend_self() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
  int ret = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
  // we are in the process of exiting so don't suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
  if (is_exiting()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
     clear_external_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
     return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2088
  assert(_anchor.walkable() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
    (is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2090
    "must have walkable stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2092
  MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
3826
67b89f5a5cac 6876794: 4/4 sp07t002 hangs very intermittently
dcubed
parents: 3261
diff changeset
  2094
  assert(!this->is_ext_suspended(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
    "a thread trying to self-suspend should not already be suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
  if (this->is_suspend_equivalent()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
    // If we are self-suspending as a result of the lifting of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
    // suspend equivalent condition, then the suspend_equivalent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
    // flag is not cleared until we set the ext_suspended flag so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
    // that wait_for_ext_suspend_completion() returns consistent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
    // results.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
    this->clear_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
  // A racing resume may have cancelled us before we grabbed SR_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
  // above. Or another external suspend request could be waiting for us
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  // by the time we return from SR_lock()->wait(). The thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
  // that requested the suspension may already be trying to walk our
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  // stack and if we return now, we can change the stack out from under
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
  // it. This would be a "bad thing (TM)" and cause the stack walker
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  // to crash. We stay self-suspended until there are no more pending
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
  // external suspend requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
  while (is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    ret++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
    this->set_ext_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
    // _ext_suspended flag is cleared by java_resume()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
    while (is_ext_suspended()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
      this->SR_lock()->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
  return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
// verify the JavaThread has not yet been published in the Threads::list, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
// hence doesn't need protection from concurrent access at this stage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
void JavaThread::verify_not_published() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
  if (!Threads_lock->owned_by_self()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
   MutexLockerEx ml(Threads_lock,  Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
   assert( !Threads::includes(this),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
           "java thread shouldn't have been published yet!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
   assert( !Threads::includes(this),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
           "java thread shouldn't have been published yet!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2141
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2143
// Slow path when the native==>VM/Java barriers detect a safepoint is in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
// progress or when _suspend_flags is non-zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
// Current thread needs to self-suspend if there is a suspend request and/or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
// block if a safepoint is in progress.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
// Async exception ISN'T checked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
// Note only the ThreadInVMfromNative transition can call this function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
// directly and when thread state is _thread_in_native_trans
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
void JavaThread::check_safepoint_and_suspend_for_native_trans(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
  assert(thread->thread_state() == _thread_in_native_trans, "wrong state");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
  JavaThread *curJT = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
  bool do_self_suspend = thread->is_external_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
  assert(!curJT->has_last_Java_frame() || curJT->frame_anchor()->walkable(), "Unwalkable stack in native->vm transition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2158
  // If JNIEnv proxies are allowed, don't self-suspend if the target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2159
  // thread is not the current thread. In older versions of jdbx, jdbx
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
  // threads could call into the VM with another thread's JNIEnv so we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2161
  // can be here operating on behalf of a suspended thread (4432884).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2162
  if (do_self_suspend && (!AllowJNIEnvProxy || curJT == thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2163
    JavaThreadState state = thread->thread_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2164
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2165
    // We mark this thread_blocked state as a suspend-equivalent so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
    // that a caller to is_ext_suspend_completed() won't be confused.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
    // The suspend-equivalent state is cleared by java_suspend_self().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
    thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
    // If the safepoint code sees the _thread_in_native_trans state, it will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
    // wait until the thread changes to other thread state. There is no
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
    // guarantee on how soon we can obtain the SR_lock and complete the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
    // self-suspend request. It would be a bad idea to let safepoint wait for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
    // too long. Temporarily change the state to _thread_blocked to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
    // let the VM thread know that this thread is ready for GC. The problem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
    // of changing thread state is that safepoint could happen just after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
    // java_suspend_self() returns after being resumed, and VM thread will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
    // see the _thread_blocked state. We must check for safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
    // after restoring the state and make sure we won't leave while a safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
    // is in progress.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    thread->set_thread_state(_thread_blocked);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
    thread->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
    thread->set_thread_state(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
    // Make sure new state is seen by VM thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
    if (os::is_MP()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
      if (UseMembar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
        // Force a fence between the write above and read below
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
        OrderAccess::fence();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
        // Must use this rather than serialization page in particular on Windows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
        InterfaceSupport::serialize_memory(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
  if (SafepointSynchronize::do_call_back()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    // If we are safepointing, then block the caller which may not be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
    // the same as the target thread (see above).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
    SafepointSynchronize::block(curJT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
  if (thread->is_deopt_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
    thread->clear_deopt_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    RegisterMap map(thread, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
    frame f = thread->last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    while ( f.id() != thread->must_deopt_id() && ! f.is_first_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
      f = f.sender(&map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
    if (f.id() == thread->must_deopt_id()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
      thread->clear_must_deopt_id();
6269
10e06287c0b0 6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents: 6184
diff changeset
  2211
      f.deoptimize(thread);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
      fatal("missed deoptimization!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
// Slow path when the native==>VM/Java barriers detect a safepoint is in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
// progress or when _suspend_flags is non-zero.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
// Current thread needs to self-suspend if there is a suspend request and/or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
// block if a safepoint is in progress.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
// Also check for pending async exception (not including unsafe access error).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
// Note only the native==>VM/Java barriers can call this function and when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
// thread state is _thread_in_native_trans.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
void JavaThread::check_special_condition_for_native_trans(JavaThread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
  check_safepoint_and_suspend_for_native_trans(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
  if (thread->has_async_exception()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
    // We are in _thread_in_native_trans state, don't handle unsafe
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
    // access error since that may block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
    thread->check_and_handle_async_exceptions(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
// We need to guarantee the Threads_lock here, since resumes are not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
// allowed during safepoint synchronization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
// Can only resume from an external suspension
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
void JavaThread::java_resume() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
  assert_locked_or_safepoint(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
  // Sanity check: thread is gone, has started exiting or the thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
  // was not externally suspended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
  if (!Threads::includes(this) || is_exiting() || !is_external_suspend()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
  MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  clear_external_suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  if (is_ext_suspended()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
    clear_ext_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
    SR_lock()->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
void JavaThread::create_stack_guard_pages() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
  address low_addr = stack_base() - stack_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
  size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  int allocate = os::allocate_stack_guard_pages();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
  // warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 5041
diff changeset
  2265
  if (allocate && !os::create_stack_guard_pages((char *) low_addr, len)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
    warning("Attempt to allocate stack guard pages failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
  if (os::guard_memory((char *) low_addr, len)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
    _stack_guard_state = stack_guard_enabled;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
    warning("Attempt to protect stack guard pages failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
    if (os::uncommit_memory((char *) low_addr, len)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
      warning("Attempt to deallocate stack guard pages failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
void JavaThread::remove_stack_guard_pages() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  if (_stack_guard_state == stack_guard_unused) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
  address low_addr = stack_base() - stack_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
  if (os::allocate_stack_guard_pages()) {
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 5041
diff changeset
  2286
    if (os::remove_stack_guard_pages((char *) low_addr, len)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
      _stack_guard_state = stack_guard_unused;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
      warning("Attempt to deallocate stack guard pages failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
    if (_stack_guard_state == stack_guard_unused) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
    if (os::unguard_memory((char *) low_addr, len)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
      _stack_guard_state = stack_guard_unused;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
        warning("Attempt to unprotect stack guard pages failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
void JavaThread::enable_stack_yellow_zone() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
  assert(_stack_guard_state != stack_guard_enabled, "already enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
  // The base notation is from the stacks point of view, growing downward.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
  // We need to adjust it to work correctly with guard_memory()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  address base = stack_yellow_zone_base() - stack_yellow_zone_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  guarantee(base < stack_base(),"Error calculating stack yellow zone");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  guarantee(base < os::current_stack_pointer(),"Error calculating stack yellow zone");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  if (os::guard_memory((char *) base, stack_yellow_zone_size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
    _stack_guard_state = stack_guard_enabled;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
    warning("Attempt to guard stack yellow zone failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
  enable_register_stack_guard();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
void JavaThread::disable_stack_yellow_zone() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
  assert(_stack_guard_state != stack_guard_yellow_disabled, "already disabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
  // Simply return if called for a thread that does not use guard pages.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  if (_stack_guard_state == stack_guard_unused) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
  // The base notation is from the stacks point of view, growing downward.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
  // We need to adjust it to work correctly with guard_memory()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
  address base = stack_yellow_zone_base() - stack_yellow_zone_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
  if (os::unguard_memory((char *)base, stack_yellow_zone_size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
    _stack_guard_state = stack_guard_yellow_disabled;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
    warning("Attempt to unguard stack yellow zone failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
  disable_register_stack_guard();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
void JavaThread::enable_stack_red_zone() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
  // The base notation is from the stacks point of view, growing downward.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
  // We need to adjust it to work correctly with guard_memory()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
  address base = stack_red_zone_base() - stack_red_zone_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
  guarantee(base < stack_base(),"Error calculating stack red zone");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
  guarantee(base < os::current_stack_pointer(),"Error calculating stack red zone");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
  if(!os::guard_memory((char *) base, stack_red_zone_size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
    warning("Attempt to guard stack red zone failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
void JavaThread::disable_stack_red_zone() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
  // The base notation is from the stacks point of view, growing downward.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  // We need to adjust it to work correctly with guard_memory()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
  assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
  address base = stack_red_zone_base() - stack_red_zone_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
  if (!os::unguard_memory((char *)base, stack_red_zone_size())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
    warning("Attempt to unguard stack red zone failed.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
void JavaThread::frames_do(void f(frame*, const RegisterMap* map)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
  // ignore is there is no stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
  if (!has_last_Java_frame()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
  // traverse the stack frames. Starts from top frame.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
  for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
    frame* fr = fst.current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
    f(fr, fst.register_map());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
// Deoptimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
// Function for testing deoptimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
void JavaThread::deoptimize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
  // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
  StackFrameStream fst(this, UseBiasedLocking);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
  bool deopt = false;           // Dump stack only if a deopt actually happens.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
  bool only_at = strlen(DeoptimizeOnlyAt) > 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
  // Iterate over all frames in the thread and deoptimize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
  for(; !fst.is_done(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
    if(fst.current()->can_be_deoptimized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
      if (only_at) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
        // Deoptimize only at particular bcis.  DeoptimizeOnlyAt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
        // consists of comma or carriage return separated numbers so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
        // search for the current bci in that string.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
        address pc = fst.current()->pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
        nmethod* nm =  (nmethod*) fst.current()->cb();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
        ScopeDesc* sd = nm->scope_desc_at( pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
        char buffer[8];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
        jio_snprintf(buffer, sizeof(buffer), "%d", sd->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
        size_t len = strlen(buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
        const char * found = strstr(DeoptimizeOnlyAt, buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
        while (found != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
          if ((found[len] == ',' || found[len] == '\n' || found[len] == '\0') &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
              (found == DeoptimizeOnlyAt || found[-1] == ',' || found[-1] == '\n')) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
            // Check that the bci found is bracketed by terminators.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
          found = strstr(found + 1, buffer);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
        if (!found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
          continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      if (DebugDeoptimization && !deopt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
        deopt = true; // One-time only print before deopt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
        tty->print_cr("[BEFORE Deoptimization]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
        trace_frames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
        trace_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
  if (DebugDeoptimization && deopt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
    tty->print_cr("[AFTER Deoptimization]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
    trace_frames();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
// Make zombies
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
void JavaThread::make_zombies() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
  for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
    if (fst.current()->can_be_deoptimized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
      // it is a Java nmethod
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
      nmethod* nm = CodeCache::find_nmethod(fst.current()->pc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
      nm->make_not_entrant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
void JavaThread::deoptimized_wrt_marked_nmethods() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
  if (!has_last_Java_frame()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  // BiasedLocking needs an updated RegisterMap for the revoke monitors pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
  StackFrameStream fst(this, UseBiasedLocking);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
  for(; !fst.is_done(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
    if (fst.current()->should_be_deoptimized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
      Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
// GC support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
static void frame_gc_epilogue(frame* f, const RegisterMap* map) { f->gc_epilogue(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
void JavaThread::gc_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
  frames_do(frame_gc_epilogue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
static void frame_gc_prologue(frame* f, const RegisterMap* map) { f->gc_prologue(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
void JavaThread::gc_prologue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
  frames_do(frame_gc_prologue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
4489
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2466
// If the caller is a NamedThread, then remember, in the current scope,
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2467
// the given JavaThread in its _processed_thread field.
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2468
class RememberProcessedThread: public StackObj {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2469
  NamedThread* _cur_thr;
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2470
public:
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2471
  RememberProcessedThread(JavaThread* jthr) {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2472
    Thread* thread = Thread::current();
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2473
    if (thread->is_Named_thread()) {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2474
      _cur_thr = (NamedThread *)thread;
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2475
      _cur_thr->set_processed_thread(jthr);
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2476
    } else {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2477
      _cur_thr = NULL;
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2478
    }
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2479
  }
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2480
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2481
  ~RememberProcessedThread() {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2482
    if (_cur_thr) {
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2483
      _cur_thr->set_processed_thread(NULL);
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2484
    }
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2485
  }
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2486
};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2488
void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
4637
af4d405aacc1 6896647: card marks can be deferred too long
ysr
parents: 4573
diff changeset
  2489
  // Verify that the deferred card marks have been flushed.
af4d405aacc1 6896647: card marks can be deferred too long
ysr
parents: 4573
diff changeset
  2490
  assert(deferred_card_mark().is_empty(), "Should be empty during GC");
4030
4c471254865e 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 3916
diff changeset
  2491
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  // The ThreadProfiler oops_do is done from FlatProfiler::oops_do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
  // since there may be more than one thread using each ThreadProfiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
  // Traverse the GCHandles
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2496
  Thread::oops_do(f, cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
  assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
          (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
  if (has_last_Java_frame()) {
4489
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2502
    // Record JavaThread to GC thread
514173c9a0c2 6361589: Print out stack trace for target thread of GC crash
minqi
parents: 4485
diff changeset
  2503
    RememberProcessedThread rpt(this);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
    // Traverse the privileged stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
    if (_privileged_stack_top != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
      _privileged_stack_top->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
    // traverse the registered growable array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
    if (_array_for_gc != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
      for (int index = 0; index < _array_for_gc->length(); index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
        f->do_oop(_array_for_gc->adr_at(index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
    // Traverse the monitor chunks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
    for (MonitorChunk* chunk = monitor_chunks(); chunk != NULL; chunk = chunk->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
      chunk->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
    // Traverse the execution stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
    for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2524
      fst.current()->oops_do(f, cf, fst.register_map());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  // callee_target is never live across a gc point so NULL it here should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
  // it still contain a methdOop.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
  set_callee_target(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  assert(vframe_array_head() == NULL, "deopt in progress at a safepoint!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
  // If we have deferred set_locals there might be oops waiting to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
  // written
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
  GrowableArray<jvmtiDeferredLocalVariableSet*>* list = deferred_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  if (list != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
    for (int i = 0; i < list->length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
      list->at(i)->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
  // Traverse instance variables at the end since the GC may be moving things
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
  // around using this function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
  f->do_oop((oop*) &_threadObj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
  f->do_oop((oop*) &_vm_result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
  f->do_oop((oop*) &_vm_result_2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
  f->do_oop((oop*) &_exception_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  f->do_oop((oop*) &_pending_async_exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  if (jvmti_thread_state() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    jvmti_thread_state()->oops_do(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2556
void JavaThread::nmethods_do(CodeBlobClosure* cf) {
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2557
  Thread::nmethods_do(cf);  // (super method is a no-op)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
  assert( (!has_last_Java_frame() && java_call_counter() == 0) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
          (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
  if (has_last_Java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
    // Traverse the execution stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
    for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2565
      fst.current()->nmethods_do(cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
// Printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
const char* _get_thread_state_name(JavaThreadState _thread_state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
  switch (_thread_state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
  case _thread_uninitialized:     return "_thread_uninitialized";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
  case _thread_new:               return "_thread_new";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
  case _thread_new_trans:         return "_thread_new_trans";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
  case _thread_in_native:         return "_thread_in_native";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
  case _thread_in_native_trans:   return "_thread_in_native_trans";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
  case _thread_in_vm:             return "_thread_in_vm";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
  case _thread_in_vm_trans:       return "_thread_in_vm_trans";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
  case _thread_in_Java:           return "_thread_in_Java";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
  case _thread_in_Java_trans:     return "_thread_in_Java_trans";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
  case _thread_blocked:           return "_thread_blocked";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
  case _thread_blocked_trans:     return "_thread_blocked_trans";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
  default:                        return "unknown thread state";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
void JavaThread::print_thread_state_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
  st->print_cr("   JavaThread state: %s", _get_thread_state_name(_thread_state));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
void JavaThread::print_thread_state() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
  print_thread_state_on(tty);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
// Called by Threads::print() for VM_PrintThreads operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
void JavaThread::print_on(outputStream *st) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
  st->print("\"%s\" ", get_thread_name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
  oop thread_oop = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
  if (thread_oop != NULL && java_lang_Thread::is_daemon(thread_oop))  st->print("daemon ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
  Thread::print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
  // print guess for valid stack memory region (assume 4K pages); helps lock debugging
2526
39a58a50be35 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 2336
diff changeset
  2604
  st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
  if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
    st->print_cr("   java.lang.Thread.State: %s", java_lang_Thread::thread_status_name(thread_oop));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
  print_thread_state_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
  _safepoint_state->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
// Called by fatal error handler. The difference between this and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
// JavaThread::print() is that we can't grab lock or allocate memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
  st->print("JavaThread \"%s\"",  get_thread_name_string(buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  oop thread_obj = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  if (thread_obj != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
     if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
  st->print(" [");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  st->print("%s", _get_thread_state_name(_thread_state));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  if (osthread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
    st->print(", id=%d", osthread()->thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
  st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
            _stack_base - _stack_size, _stack_base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
  st->print("]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
// Verification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
static void frame_verify(frame* f, const RegisterMap *map) { f->verify(map); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
void JavaThread::verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
  // Verify oops in the thread.
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  2639
  oops_do(&VerifyOopClosure::verify_oop, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  // Verify the stack frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
  frames_do(frame_verify);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
// CR 6300358 (sub-CR 2137150)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
// Most callers of this method assume that it can't return NULL but a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
// thread may not have a name whilst it is in the process of attaching to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
// the VM - see CR 6412693, and there are places where a JavaThread can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
// seen prior to having it's threadObj set (eg JNI attaching threads and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
// if vm exit occurs during initialization). These cases can all be accounted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
// for such that this method never returns NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
const char* JavaThread::get_thread_name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
  // early safepoints can hit while current thread does not yet have TLS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
  if (!SafepointSynchronize::is_at_safepoint()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
    Thread *cur = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    if (!(cur->is_Java_thread() && cur == this)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
      // Current JavaThreads are allowed to get their own name without
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
      // the Threads_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
      assert_locked_or_safepoint(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
#endif // ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
    return get_thread_name_string();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
// Returns a non-NULL representation of this thread's name, or a suitable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
// descriptive string if there is no set name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
const char* JavaThread::get_thread_name_string(char* buf, int buflen) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
  const char* name_str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  oop thread_obj = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  if (thread_obj != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
    typeArrayOop name = java_lang_Thread::name(thread_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
    if (name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
      if (buf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
        name_str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
      else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
        name_str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length(), buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
    else if (is_attaching()) { // workaround for 6412693 - see 6404306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
      name_str = "<no-name - thread is attaching>";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
      name_str = Thread::name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
    name_str = Thread::name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
  assert(name_str != NULL, "unexpected NULL thread name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
  return name_str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
const char* JavaThread::get_threadgroup_name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
  debug_only(if (JavaThread::current() != this) assert_locked_or_safepoint(Threads_lock);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  oop thread_obj = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  if (thread_obj != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
    oop thread_group = java_lang_Thread::threadGroup(thread_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
    if (thread_group != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
      typeArrayOop name = java_lang_ThreadGroup::name(thread_group);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
      // ThreadGroup.name can be null
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
      if (name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
        const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
        return str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
const char* JavaThread::get_parent_name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  debug_only(if (JavaThread::current() != this) assert_locked_or_safepoint(Threads_lock);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
  oop thread_obj = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  if (thread_obj != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
    oop thread_group = java_lang_Thread::threadGroup(thread_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
    if (thread_group != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
      oop parent = java_lang_ThreadGroup::parent(thread_group);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
      if (parent != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
        typeArrayOop name = java_lang_ThreadGroup::name(parent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
        // ThreadGroup.name can be null
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
        if (name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
          const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
          return str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
ThreadPriority JavaThread::java_priority() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  oop thr_oop = threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
  if (thr_oop == NULL) return NormPriority; // Bootstrapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
  ThreadPriority priority = java_lang_Thread::priority(thr_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
  assert(MinPriority <= priority && priority <= MaxPriority, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  return priority;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
void JavaThread::prepare(jobject jni_thread, ThreadPriority prio) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
  assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
  // Link Java Thread object <-> C++ Thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
  // Get the C++ thread object (an oop) from the JNI handle (a jthread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
  // and put it into a new Handle.  The Handle "thread_oop" can then
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  // be used to pass the C++ thread object to other methods.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  // Set the Java level thread object (jthread) field of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  // new thread (a JavaThread *) to C++ thread object using the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  // "thread_oop" handle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
  // Set the thread field (a JavaThread *) of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  // oop representing the java_lang_Thread to the new thread (a JavaThread *).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
  Handle thread_oop(Thread::current(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
                    JNIHandles::resolve_non_null(jni_thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
  assert(instanceKlass::cast(thread_oop->klass())->is_linked(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
    "must be initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
  set_threadObj(thread_oop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
  java_lang_Thread::set_thread(thread_oop(), this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
  if (prio == NoPriority) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
    prio = java_lang_Thread::priority(thread_oop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
    assert(prio != NoPriority, "A valid priority should be present");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
  // Push the Java priority down to the native thread; needs Threads_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
  Thread::set_priority(this, prio);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
  // Add the new thread to the Threads list and set it in motion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
  // We must have threads lock in order to call Threads::add.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
  // It is crucial that we do not block before the thread is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
  // added to the Threads list for if a GC happens, then the java_thread oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
  // will not be visited by GC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
  Threads::add(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
oop JavaThread::current_park_blocker() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
  // Support for JSR-166 locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
  oop thread_oop = threadObj();
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  2784
  if (thread_oop != NULL &&
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  2785
      JDK_Version::current().supports_thread_park_blocker()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
    return java_lang_Thread::park_blocker(thread_oop);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
void JavaThread::print_stack_on(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
  if (!has_last_Java_frame()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
  RegisterMap reg_map(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
  vframe* start_vf = last_java_vframe(&reg_map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
  int count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
  for (vframe* f = start_vf; f; f = f->sender() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
    if (f->is_java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
      javaVFrame* jvf = javaVFrame::cast(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
      java_lang_Throwable::print_stack_element(st, jvf->method(), jvf->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
      // Print out lock information
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
      if (JavaMonitorsInStackTrace) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
        jvf->print_lock_info_on(st, count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
      // Ignore non-Java frames
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
    // Bail-out case for too deep stacks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
    count++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
    if (MaxJavaStackTraceDepth == count) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
// JVMTI PopFrame support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
void JavaThread::popframe_preserve_args(ByteSize size_in_bytes, void* start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
  assert(_popframe_preserved_args == NULL, "should not wipe out old PopFrame preserved arguments");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
  if (in_bytes(size_in_bytes) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
    _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
    _popframe_preserved_args_size = in_bytes(size_in_bytes);
5883
8dc4bdc132d5 6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents: 5707
diff changeset
  2826
    Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
void* JavaThread::popframe_preserved_args() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  return _popframe_preserved_args;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
ByteSize JavaThread::popframe_preserved_args_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
  return in_ByteSize(_popframe_preserved_args_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
WordSize JavaThread::popframe_preserved_args_size_in_words() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
  int sz = in_bytes(popframe_preserved_args_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  assert(sz % wordSize == 0, "argument size must be multiple of wordSize");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
  return in_WordSize(sz / wordSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
void JavaThread::popframe_free_preserved_args() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  assert(_popframe_preserved_args != NULL, "should not free PopFrame preserved arguments twice");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
  _popframe_preserved_args = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
  _popframe_preserved_args_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
void JavaThread::trace_frames() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  tty->print_cr("[Describe stack]");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  int frame_no = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
  for(StackFrameStream fst(this); !fst.is_done(); fst.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
    tty->print("  %d. ", frame_no++);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
    fst.current()->print_value_on(tty,this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
    tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
10517
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2863
class PrintAndVerifyOopClosure: public OopClosure {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2864
 protected:
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2865
  template <class T> inline void do_oop_work(T* p) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2866
    oop obj = oopDesc::load_decode_heap_oop(p);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2867
    if (obj == NULL) return;
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2868
    tty->print(INTPTR_FORMAT ": ", p);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2869
    if (obj->is_oop_or_null()) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2870
      if (obj->is_objArray()) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2871
        tty->print_cr("valid objArray: " INTPTR_FORMAT, (oopDesc*) obj);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2872
      } else {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2873
        obj->print();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2874
      }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2875
    } else {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2876
      tty->print_cr("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2877
    }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2878
    tty->cr();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2879
  }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2880
 public:
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2881
  virtual void do_oop(oop* p) { do_oop_work(p); }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2882
  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2883
};
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2884
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2885
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2886
static void oops_print(frame* f, const RegisterMap *map) {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2887
  PrintAndVerifyOopClosure print;
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2888
  f->print_value();
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2889
  f->oops_do(&print, NULL, (RegisterMap*)map);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2890
}
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2891
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2892
// Print our all the locations that contain oops and whether they are
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2893
// valid or not.  This useful when trying to find the oldest frame
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2894
// where an oop has gone bad since the frame walk is from youngest to
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2895
// oldest.
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2896
void JavaThread::trace_oops() {
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2897
  tty->print_cr("[Trace oops]");
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2898
  frames_do(oops_print);
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2899
}
f92c9ff3a15f 7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents: 10508
diff changeset
  2900
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
9946
b3d5b50e2289 7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents: 9942
diff changeset
  2902
#ifdef ASSERT
9437
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2903
// Print or validate the layout of stack frames
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2904
void JavaThread::print_frame_layout(int depth, bool validate_only) {
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2905
  ResourceMark rm;
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2906
  PRESERVE_EXCEPTION_MARK;
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2907
  FrameValues values;
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2908
  int frame_no = 0;
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2909
  for(StackFrameStream fst(this, false); !fst.is_done(); fst.next()) {
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2910
    fst.current()->describe(values, ++frame_no);
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2911
    if (depth == frame_no) break;
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2912
  }
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2913
  if (validate_only) {
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2914
    values.validate();
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2915
  } else {
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2916
    tty->print_cr("[Describe stack layout]");
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2917
    values.print();
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2918
  }
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2919
}
9946
b3d5b50e2289 7045513: JSR 292 inlining causes crashes in methodHandleWalk.cpp
never
parents: 9942
diff changeset
  2920
#endif
9437
9981851b4b8c 7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents: 8883
diff changeset
  2921
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
void JavaThread::trace_stack_from(vframe* start_vf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  int vframe_no = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  for (vframe* f = start_vf; f; f = f->sender() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
    if (f->is_java_frame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
      javaVFrame::cast(f)->print_activation(vframe_no++);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
      f->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
    if (vframe_no > StackPrintLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
      tty->print_cr("...<more frames>...");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
void JavaThread::trace_stack() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2940
  if (!has_last_Java_frame()) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2941
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2942
  HandleMark   hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2943
  RegisterMap reg_map(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2944
  trace_stack_from(last_java_vframe(&reg_map));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2945
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2948
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2949
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2951
javaVFrame* JavaThread::last_java_vframe(RegisterMap *reg_map) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2952
  assert(reg_map != NULL, "a map must be given");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2953
  frame f = last_frame();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
  for (vframe* vf = vframe::new_vframe(&f, reg_map, this); vf; vf = vf->sender() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
    if (vf->is_java_frame()) return javaVFrame::cast(vf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
klassOop JavaThread::security_get_caller_class(int depth) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
  vframeStream vfst(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
  vfst.security_get_caller_frame(depth);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
  if (!vfst.at_end()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
    return vfst.method()->method_holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
static void compiler_thread_entry(JavaThread* thread, TRAPS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2971
  assert(thread->is_Compiler_thread(), "must be compiler thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
  CompileBroker::compiler_thread_loop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
// Create a CompilerThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
: JavaThread(&compiler_thread_entry) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  _env   = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
  _log   = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  _task  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
  _queue = queue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
  _counters = counters;
5707
6c66849ed24e 6958292: C1: Enable parallel compilation
iveresov
parents: 5547
diff changeset
  2983
  _buffer_blob = NULL;
9942
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2984
  _scanned_nmethod = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
  _ideal_graph_printer = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
9942
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2991
void CompilerThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2992
  JavaThread::oops_do(f, cf);
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2993
  if (_scanned_nmethod != NULL && cf != NULL) {
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2994
    // Safepoints can occur when the sweeper is scanning an nmethod so
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2995
    // process it here to make sure it isn't unloaded in the middle of
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2996
    // a scan.
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2997
    cf->do_code_blob(_scanned_nmethod);
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2998
  }
2e86734ba620 6996747: SIGSEGV in nmethod::cleanup_inline_caches / CompiledIC::verify
never
parents: 9437
diff changeset
  2999
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
// ======= Threads ========
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
// The Threads class links together all active threads, and provides
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
// operations over all threads.  It is protected by its own Mutex
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
// lock, which is also used in other contexts to protect thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
// operations from having the thread being operated on from exiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
// and going away unexpectedly (e.g., safepoint synchronization)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
JavaThread* Threads::_thread_list = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3010
int         Threads::_number_of_threads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3011
int         Threads::_number_of_non_daemon_threads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3012
int         Threads::_return_code = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3013
size_t      JavaThread::_stack_size_at_create = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
// All JavaThreads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
#define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
void os_stream();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
// All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
void Threads::threads_do(ThreadClosure* tc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
  assert_locked_or_safepoint(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
  // ALL_JAVA_THREADS iterates through all JavaThreads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
    tc->do_thread(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
  // Someday we could have a table or list of all non-JavaThreads.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
  // For now, just manually iterate through them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
  tc->do_thread(VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
  Universe::heap()->gc_threads_do(tc);
1127
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3031
  WatcherThread *wt = WatcherThread::watcher_thread();
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3032
  // Strictly speaking, the following NULL check isn't sufficient to make sure
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3033
  // the data for WatcherThread is still valid upon being examined. However,
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3034
  // considering that WatchThread terminates when the VM is on the way to
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3035
  // exit at safepoint, the chance of the above is extremely small. The right
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3036
  // way to prevent termination of WatcherThread would be to acquire
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3037
  // Terminator_lock, but we can't do that without violating the lock rank
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3038
  // checking in some cases.
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3039
  if (wt != NULL)
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3040
    tc->do_thread(wt);
7245ad3ee7ea 6740526: sun/management/HotspotThreadMBean/GetInternalThreads.java test failed
xlu
parents: 994
diff changeset
  3041
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
  // If CompilerThreads ever become non-JavaThreads, add them here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  3047
  extern void JDK_Version_init();
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  3048
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
  // Check version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
  if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
  // Initialize the output stream module
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
  ostream_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
  // Process java launcher properties.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
  Arguments::process_sun_java_launcher_properties(args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
  // Initialize the os module before using TLS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
  os::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
  // Initialize system properties.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
  Arguments::init_system_properties();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  3064
  // So that JDK version can be used as a discrimintor when parsing arguments
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  3065
  JDK_Version_init();
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 670
diff changeset
  3066
6961
a32b2fc66321 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 6273
diff changeset
  3067
  // Update/Initialize System properties after JDK version number is known
a32b2fc66321 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 6273
diff changeset
  3068
  Arguments::init_version_specific_system_properties();
a32b2fc66321 6988363: Rebrand vm vendor property settings (jdk7 only)
zgu
parents: 6273
diff changeset
  3069
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
  // Parse arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
  jint parse_result = Arguments::parse(args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
  if (parse_result != JNI_OK) return parse_result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
  if (PauseAtStartup) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
    os::pause();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
  HS_DTRACE_PROBE(hotspot, vm__init__begin);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
  // Record VM creation timing statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
  TraceVmCreationTime create_vm_timer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
  create_vm_timer.start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
  // Timing (must come after argument parsing)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
  TraceTime timer("Create VM", TraceStartupTime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
  // Initialize the os module after parsing the args
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
  jint os_init_2_result = os::init_2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
  if (os_init_2_result != JNI_OK) return os_init_2_result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
  // Initialize output stream logging
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
  ostream_init_log();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
  // Convert -Xrun to -agentlib: if there is no JVM_OnLoad
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
  // Must be before create_vm_init_agents()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
  if (Arguments::init_libraries_at_startup()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
    convert_vm_init_libraries_to_agents();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
  // Launch -agentlib/-agentpath and converted -Xrun agents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
  if (Arguments::init_agents_at_startup()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
    create_vm_init_agents();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
  // Initialize Threads state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
  _thread_list = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
  _number_of_threads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  _number_of_non_daemon_threads = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  // Initialize TLS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
  ThreadLocalStorage::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
  // Initialize global data structures and create system classes in heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  vm_init_globals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  // Attach the main thread to this os thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
  JavaThread* main_thread = new JavaThread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
  main_thread->set_thread_state(_thread_in_vm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
  // must do this before set_active_handles and initialize_thread_local_storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
  // Note: on solaris initialize_thread_local_storage() will (indirectly)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
  // change the stack size recorded here to one based on the java thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
  // stacksize. This adjusted size is what is used to figure the placement
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
  // of the guard pages.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
  main_thread->record_stack_base_and_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  main_thread->initialize_thread_local_storage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
  main_thread->set_active_handles(JNIHandleBlock::allocate_block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
  if (!main_thread->set_as_starting_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
    vm_shutdown_during_initialization(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
      "Failed necessary internal allocation. Out of swap space");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
    delete main_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
    return JNI_ENOMEM;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
  // Enable guard page *after* os::create_main_thread(), otherwise it would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  // crash Linux VM, see notes in os_linux.cpp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
  main_thread->create_stack_guard_pages();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  3141
  // Initialize Java-Level synchronization subsystem
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  3142
  ObjectMonitor::Initialize() ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
  // Initialize global modules
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
  jint status = init_globals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
  if (status != JNI_OK) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
    delete main_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
    *canTryAgain = false; // don't let caller call JNI_CreateJavaVM again
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
    return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3152
  // Should be done after the heap is fully created
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3153
  main_thread->cache_global_variables();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3154
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
  HandleMark hm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
  { MutexLocker mu(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
    Threads::add(main_thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
  // Any JVMTI raw monitors entered in onload will transition into
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
  // real raw monitor. VM is setup enough here for raw monitor enter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
  JvmtiExport::transition_pending_onload_raw_monitors();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
  if (VerifyBeforeGC &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
      Universe::heap()->total_collections() >= VerifyGCStartAt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
    Universe::heap()->prepare_for_verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
    Universe::verify();   // make sure we're starting with a clean slate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
  // Create the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
  { TraceTime timer("Start VMThread", TraceStartupTime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
    VMThread::create();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
    Thread* vmthread = VMThread::vm_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
    if (!os::create_thread(vmthread, os::vm_thread))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
      vm_exit_during_initialization("Cannot create VM thread. Out of system resources.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
    // Wait for the VM thread to become ready, and VMThread::run to initialize
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
    // Monitors can have spurious returns, must always check another state flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
      MutexLocker ml(Notify_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
      os::start_thread(vmthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
      while (vmthread->active_handles() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
        Notify_lock->wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
  assert (Universe::is_fully_initialized(), "not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
  EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
  // At this point, the Universe is initialized, but we have not executed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
  // any byte code.  Now is a good time (the only time) to dump out the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
  // internal state of the JVM for sharing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
  if (DumpSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
    Universe::heap()->preload_and_dump(CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
    ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
  // Always call even when there are not JVMTI environments yet, since environments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  // may be attached late and JVMTI must track phases of VM execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
  JvmtiExport::enter_start_phase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
  // Notify JVMTI agents that VM has started (JNI is up) - nop if no agents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
  JvmtiExport::post_vm_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
    TraceTime timer("Initialize java.lang classes", TraceStartupTime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
    if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
      create_vm_init_libraries();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
    if (InitializeJavaLangString) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3217
      initialize_class(vmSymbols::java_lang_String(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
      warning("java.lang.String not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
191
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3222
    if (AggressiveOpts) {
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3223
      {
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3224
        // Forcibly initialize java/util/HashMap and mutate the private
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3225
        // static final "frontCacheEnabled" field before we start creating instances
191
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3226
#ifdef ASSERT
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3227
        klassOop tmp_k = SystemDictionary::find(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3228
        assert(tmp_k == NULL, "java/util/HashMap should not be loaded yet");
191
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3229
#endif
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3230
        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_util_HashMap(), Handle(), Handle(), CHECK_0);
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3231
        KlassHandle k = KlassHandle(THREAD, k_o);
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3232
        guarantee(k.not_null(), "Must find java/util/HashMap");
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3233
        instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3234
        ik->initialize(CHECK_0);
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3235
        fieldDescriptor fd;
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3236
        // Possible we might not find this field; if so, don't break
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3237
        if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8476
diff changeset
  3238
          k()->java_mirror()->bool_field_put(fd.offset(), true);
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3239
        }
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3240
      }
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3241
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3242
      if (UseStringCache) {
2336
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3243
        // Forcibly initialize java/lang/StringValue and mutate the private
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3244
        // static final "stringCacheEnabled" field before we start creating instances
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3245
        klassOop k_o = SystemDictionary::resolve_or_null(vmSymbols::java_lang_StringValue(), Handle(), Handle(), CHECK_0);
2336
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3246
        // Possible that StringValue isn't present: if so, silently don't break
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3247
        if (k_o != NULL) {
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3248
          KlassHandle k = KlassHandle(THREAD, k_o);
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3249
          instanceKlassHandle ik = instanceKlassHandle(THREAD, k());
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3250
          ik->initialize(CHECK_0);
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3251
          fieldDescriptor fd;
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3252
          // Possible we might not find this field: if so, silently don't break
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3253
          if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8476
diff changeset
  3254
            k()->java_mirror()->bool_field_put(fd.offset(), true);
2336
427ce3320578 6810653: Change String cache class used by Hotspot from String to StringValue
phh
parents: 1560
diff changeset
  3255
          }
618
9641c2c8f977 6714404: Add UseStringCache switch to enable String caching under AggressiveOpts
kvn
parents: 235
diff changeset
  3256
        }
191
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3257
      }
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3258
    }
314312979e7a 6621621: HashMap front cache should be enabled only with AggressiveOpts
phh
parents: 1
diff changeset
  3259
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
    // Initialize java_lang.System (needed before creating the thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
    if (InitializeJavaLangSystem) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3262
      initialize_class(vmSymbols::java_lang_System(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3263
      initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
      Handle thread_group = create_initial_thread_group(CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
      Universe::set_main_thread_group(thread_group());
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3266
      initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
      oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
      main_thread->set_threadObj(thread_object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
      // Set thread status to running since main thread has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
      // been started and running.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
      java_lang_Thread::set_thread_status(thread_object,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
                                          java_lang_Thread::RUNNABLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
      // The VM preresolve methods to these classes. Make sure that get initialized
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3275
      initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3276
      initialize_class(vmSymbols::java_lang_ref_Finalizer(),  CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
      // The VM creates & returns objects of this class. Make sure it's initialized.
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3278
      initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
      call_initializeSystemClass(CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
      warning("java.lang.System not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
    // an instance of OutOfMemory exception has been allocated earlier
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
    if (InitializeJavaLangExceptionsErrors) {
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3286
      initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3287
      initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3288
      initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3289
      initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3290
      initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3291
      initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3292
      initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
      warning("java.lang.OutOfMemoryError has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
      warning("java.lang.NullPointerException has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
      warning("java.lang.ClassCastException has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
      warning("java.lang.ArrayStoreException has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
      warning("java.lang.ArithmeticException has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
      warning("java.lang.StackOverflowError has not been initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
    }
8883
5569135acca3 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 8725
diff changeset
  3301
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
  // See        : bugid 4211085.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
  // Background : the static initializer of java.lang.Compiler tries to read
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
  //              property"java.compiler" and read & write property "java.vm.info".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
  //              When a security manager is installed through the command line
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
  //              option "-Djava.security.manager", the above properties are not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
  //              readable and the static initializer for java.lang.Compiler fails
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
  //              resulting in a NoClassDefFoundError.  This can happen in any
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
  //              user code which calls methods in java.lang.Compiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
  // Hack :       the hack is to pre-load and initialize this class, so that only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
  //              system domains are on the stack when the properties are read.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
  //              Currently even the AWT code has calls to methods in java.lang.Compiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
  //              On the classic VM, java.lang.Compiler is loaded very early to load the JIT.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
  // Future Fix : the best fix is to grant everyone permissions to read "java.compiler" and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
  //              read and write"java.vm.info" in the default policy file. See bugid 4211383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
  //              Once that is done, we should remove this hack.
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3318
  initialize_class(vmSymbols::java_lang_Compiler(), CHECK_0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  // More hackery - the static initializer of java.lang.Compiler adds the string "nojit" to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  // the java.vm.info property if no jit gets loaded through java.lang.Compiler (the hotspot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  // compiler does not get loaded through java.lang.Compiler).  "java -version" with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
  // hotspot vm says "nojit" all the time which is confusing.  So, we reset it here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
  // This should also be taken out as soon as 4211383 gets fixed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  reset_vm_info_property(CHECK_0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  quicken_jni_functions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  // Set flag that basic initialization has completed. Used by exceptions and various
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
  // debug stuff, that does not work until all basic classes have been initialized.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
  set_init_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
  HS_DTRACE_PROBE(hotspot, vm__init__end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
  // record VM initialization completion time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
  Management::record_vm_init_completed();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
  // Compute system loader. Note that this has to occur after set_init_completed, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
  // valid exceptions may be thrown in the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
  // Note that we do not use CHECK_0 here since we are inside an EXCEPTION_MARK and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
  // set_init_completed has just been called, causing exceptions not to be shortcut
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  // anymore. We call vm_exit_during_initialization directly instead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
  SystemDictionary::compute_java_system_loader(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
  if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
    vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
#ifndef SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  // Support for ConcurrentMarkSweep. This should be cleaned up
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3350
  // and better encapsulated. The ugly nested if test would go away
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3351
  // once things are properly refactored. XXX YSR
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3352
  if (UseConcMarkSweepGC || UseG1GC) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3353
    if (UseConcMarkSweepGC) {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3354
      ConcurrentMarkSweepThread::makeSurrogateLockerThread(THREAD);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3355
    } else {
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3356
      ConcurrentMarkThread::makeSurrogateLockerThread(THREAD);
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 235
diff changeset
  3357
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
    if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
      vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
#endif // SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
  // Always call even when there are not JVMTI environments yet, since environments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
  // may be attached late and JVMTI must track phases of VM execution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
  JvmtiExport::enter_live_phase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
  // Signal Dispatcher needs to be started before VMInit event is posted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
  os::signal_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
  // Start Attach Listener if +StartAttachListener or it can't be started lazily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  if (!DisableAttachMechanism) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
    if (StartAttachListener || AttachListener::init_at_startup()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
      AttachListener::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
  // Launch -Xrun agents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
  // Must be done in the JVMTI live phase so that for backward compatibility the JDWP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
  // back-end can launch with -Xdebug -Xrunjdwp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
  if (!EagerXrunInit && Arguments::init_libraries_at_startup()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
    create_vm_init_libraries();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
  // Notify JVMTI agents that VM initialization is complete - nop if no agents.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
  JvmtiExport::post_vm_initialized();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
10022
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9992
diff changeset
  3388
  if (CleanChunkPoolAsync) {
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9992
diff changeset
  3389
    Chunk::start_chunk_pool_cleaner_task();
377345fb5fb5 7061204: clean the chunk table synchronously in embedded builds
jcoomes
parents: 9992
diff changeset
  3390
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
  // initialize compiler(s)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
  CompileBroker::compilation_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
  Management::initialize(THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
  if (HAS_PENDING_EXCEPTION) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
    // management agent fails to start possibly due to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
    // configuration problem and is responsible for printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
    // stack trace if appropriate. Simply exit VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
    vm_exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
  if (Arguments::has_profile())       FlatProfiler::engage(main_thread, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
  if (Arguments::has_alloc_profile()) AllocationProfiler::engage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
  if (MemProfiling)                   MemProfiler::engage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  StatSampler::engage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
  if (CheckJNICalls)                  JniPeriodicChecker::engage();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
  BiasedLocking::init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
7900
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3411
  if (JDK_Version::current().post_vm_init_hook_enabled()) {
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3412
    call_postVMInitHook(THREAD);
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3413
    // The Java side of PostVMInitHook.run must deal with all
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3414
    // exceptions and provide means of diagnosis.
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3415
    if (HAS_PENDING_EXCEPTION) {
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3416
      CLEAR_PENDING_EXCEPTION;
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3417
    }
4c7fc6332f7e 6994753: Implement optional hook to a Java method at VM startup.
kevinw
parents: 7897
diff changeset
  3418
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
  // Start up the WatcherThread if there are any periodic tasks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
  // NOTE:  All PeriodicTasks should be registered by now. If they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
  //   aren't, late joiners might appear to start slowly (we might
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
  //   take a while to process their first tick).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  if (PeriodicTask::num_tasks() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
    WatcherThread::start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3428
  // Give os specific code one last chance to start
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3429
  os::init_3();
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5888
diff changeset
  3430
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
  create_vm_timer.end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
  return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
// type for the Agent_OnLoad and JVM_OnLoad entry points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
  typedef jint (JNICALL *OnLoadEntry_t)(JavaVM *, char *, void *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
// Find a command line agent library and return its entry point for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
//         -agentlib:  -agentpath:   -Xrun
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
// num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
static OnLoadEntry_t lookup_on_load(AgentLibrary* agent, const char *on_load_symbols[], size_t num_symbol_entries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  OnLoadEntry_t on_load_entry = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  void *library = agent->os_lib();  // check if we have looked it up before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  if (library == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
    char buffer[JVM_MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
    char ebuf[1024];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
    const char *name = agent->name();
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3450
    const char *msg = "Could not find agent library ";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
    if (agent->is_absolute_path()) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3453
      library = os::dll_load(name, ebuf, sizeof ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
      if (library == NULL) {
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3455
        const char *sub_msg = " in absolute path, with error: ";
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3456
        size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3457
        char *buf = NEW_C_HEAP_ARRAY(char, len);
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3458
        jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
        // If we can't find the agent, exit.
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3460
        vm_exit_during_initialization(buf, NULL);
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3461
        FREE_C_HEAP_ARRAY(char, buf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
      // Try to load the agent from the standard dll directory
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3465
      os::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3466
      library = os::dll_load(buffer, ebuf, sizeof ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
#ifdef KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
      // Download instrument dll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
      if (library == NULL && strcmp(name, "instrument") == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
        char *props = Arguments::get_kernel_properties();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
        char *home  = Arguments::get_java_home();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
        const char *fmt   = "%s/bin/java %s -Dkernel.background.download=false"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
                      " sun.jkernel.DownloadManager -download client_jvm";
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3474
        size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3475
        char *cmd = NEW_C_HEAP_ARRAY(char, length);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
        jio_snprintf(cmd, length, fmt, home, props);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
        int status = os::fork_and_exec(cmd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
        FreeHeap(props);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
        if (status == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
          warning(cmd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
          vm_exit_during_initialization("fork_and_exec failed: %s",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
                                         strerror(errno));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
        }
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3484
        FREE_C_HEAP_ARRAY(char, cmd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
        // when this comes back the instrument.dll should be where it belongs.
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3486
        library = os::dll_load(buffer, ebuf, sizeof ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
#endif // KERNEL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
      if (library == NULL) { // Try the local directory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
        char ns[1] = {0};
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3491
        os::dll_build_name(buffer, sizeof(buffer), ns, name);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3492
        library = os::dll_load(buffer, ebuf, sizeof ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
        if (library == NULL) {
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3494
          const char *sub_msg = " on the library path, with error: ";
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3495
          size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3496
          char *buf = NEW_C_HEAP_ARRAY(char, len);
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3497
          jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
          // If we can't find the agent, exit.
6189
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3499
          vm_exit_during_initialization(buf, NULL);
9dcd5f57dcc3 6378314: Bad warning message when agent library not found. local directory is not searched.
rasbold
parents: 6176
diff changeset
  3500
          FREE_C_HEAP_ARRAY(char, buf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
    agent->set_os_lib(library);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
  // Find the OnLoad function.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  for (size_t symbol_index = 0; symbol_index < num_symbol_entries; symbol_index++) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3509
    on_load_entry = CAST_TO_FN_PTR(OnLoadEntry_t, os::dll_lookup(library, on_load_symbols[symbol_index]));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
    if (on_load_entry != NULL) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
  return on_load_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
// Find the JVM_OnLoad entry point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
static OnLoadEntry_t lookup_jvm_on_load(AgentLibrary* agent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
  const char *on_load_symbols[] = JVM_ONLOAD_SYMBOLS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  return lookup_on_load(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
// Find the Agent_OnLoad entry point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
static OnLoadEntry_t lookup_agent_on_load(AgentLibrary* agent) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  const char *on_load_symbols[] = AGENT_ONLOAD_SYMBOLS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  return lookup_on_load(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
// For backwards compatibility with -Xrun
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
// Convert libraries with no JVM_OnLoad, but which have Agent_OnLoad to be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
// treated like -agentpath:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
// Must be called before agent libraries are created
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
void Threads::convert_vm_init_libraries_to_agents() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  AgentLibrary* agent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  AgentLibrary* next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
  for (agent = Arguments::libraries(); agent != NULL; agent = next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
    next = agent->next();  // cache the next agent now as this agent may get moved off this list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
    OnLoadEntry_t on_load_entry = lookup_jvm_on_load(agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
    // If there is an JVM_OnLoad function it will get called later,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
    // otherwise see if there is an Agent_OnLoad
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
    if (on_load_entry == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
      on_load_entry = lookup_agent_on_load(agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
      if (on_load_entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
        // switch it to the agent list -- so that Agent_OnLoad will be called,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
        // JVM_OnLoad won't be attempted and Agent_OnUnload will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
        Arguments::convert_library_to_agent(agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
        vm_exit_during_initialization("Could not find JVM_OnLoad or Agent_OnLoad function in the library", agent->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
// Create agents for -agentlib:  -agentpath:  and converted -Xrun
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
// Invokes Agent_OnLoad
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
// Called very early -- before JavaThreads exist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
void Threads::create_vm_init_agents() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
  extern struct JavaVM_ main_vm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
  AgentLibrary* agent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
  JvmtiExport::enter_onload_phase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
  for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
    OnLoadEntry_t  on_load_entry = lookup_agent_on_load(agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
    if (on_load_entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
      // Invoke the Agent_OnLoad function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
      jint err = (*on_load_entry)(&main_vm, agent->options(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
      if (err != JNI_OK) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
        vm_exit_during_initialization("agent library failed to init", agent->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
      vm_exit_during_initialization("Could not find Agent_OnLoad function in the agent library", agent->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
  JvmtiExport::enter_primordial_phase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
  typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
void Threads::shutdown_vm_agents() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
  // Send any Agent_OnUnload notifications
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
  const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
  extern struct JavaVM_ main_vm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
  for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
    // Find the Agent_OnUnload function.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
    for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
      Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t,
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  3591
               os::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index]));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
      // Invoke the Agent_OnUnload function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
      if (unload_entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
        JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
        ThreadToNativeFromVM ttn(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
        HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
        (*unload_entry)(&main_vm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
// Called for after the VM is initialized for -Xrun libraries which have not been converted to agent libraries
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
// Invokes JVM_OnLoad
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
void Threads::create_vm_init_libraries() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
  extern struct JavaVM_ main_vm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
  AgentLibrary* agent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  for (agent = Arguments::libraries(); agent != NULL; agent = agent->next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
    OnLoadEntry_t on_load_entry = lookup_jvm_on_load(agent);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
    if (on_load_entry != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
      // Invoke the JVM_OnLoad function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
      JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
      ThreadToNativeFromVM ttn(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
      HandleMark hm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
      jint err = (*on_load_entry)(&main_vm, agent->options(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
      if (err != JNI_OK) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
        vm_exit_during_initialization("-Xrun library failed to init", agent->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
      vm_exit_during_initialization("Could not find JVM_OnLoad function in -Xrun library", agent->name());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
// Last thread running calls java.lang.Shutdown.shutdown()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
void JavaThread::invoke_shutdown_hooks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
  HandleMark hm(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
  // We could get here with a pending exception, if so clear it now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  if (this->has_pending_exception()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
    this->clear_pending_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
  EXCEPTION_MARK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
  klassOop k =
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3640
    SystemDictionary::resolve_or_null(vmSymbols::java_lang_Shutdown(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
                                      THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
  if (k != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
    // SystemDictionary::resolve_or_null will return null if there was
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
    // an exception.  If we cannot load the Shutdown class, just don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
    // call Shutdown.shutdown() at all.  This will mean the shutdown hooks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
    // and finalizers (if runFinalizersOnExit is set) won't be run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
    // Note that if a shutdown hook was registered or runFinalizersOnExit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
    // was called, the Shutdown class would have already been loaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
    // (Runtime.addShutdownHook and runFinalizersOnExit will load it).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
    instanceKlassHandle shutdown_klass (THREAD, k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
    JavaValue result(T_VOID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
    JavaCalls::call_static(&result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
                           shutdown_klass,
8076
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3654
                           vmSymbols::shutdown_method_name(),
96d498ec7ae1 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 8061
diff changeset
  3655
                           vmSymbols::void_method_signature(),
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
                           THREAD);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
  CLEAR_PENDING_EXCEPTION;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
// Threads::destroy_vm() is normally called from jni_DestroyJavaVM() when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
// the program falls off the end of main(). Another VM exit path is through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
// vm_exit() when the program calls System.exit() to return a value or when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
// there is a serious error in VM. The two shutdown paths are not exactly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
// the same, but they share Shutdown.shutdown() at Java level and before_exit()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
// and VM_Exit op at VM level.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
// Shutdown sequence:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
//   + Wait until we are the last non-daemon thread to execute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
//     <-- every thing is still working at this moment -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
//   + Call java.lang.Shutdown.shutdown(), which will invoke Java level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
//        shutdown hooks, run finalizers if finalization-on-exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
//   + Call before_exit(), prepare for VM exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
//      > run VM level shutdown hooks (they are registered through JVM_OnExit(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
//        currently the only user of this mechanism is File.deleteOnExit())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
//      > stop flat profiler, StatSampler, watcher thread, CMS threads,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
//        post thread end and vm death events to JVMTI,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
//        stop signal thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
//   + Call JavaThread::exit(), it will:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
//      > release JNI handle blocks, remove stack guard pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
//      > remove this thread from Threads list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
//     <-- no more Java code from this thread after this point -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
//   + Stop VM thread, it will bring the remaining VM to a safepoint and stop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
//     the compiler threads at safepoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
//     <-- do not use anything that could get blocked by Safepoint -->
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
//   + Disable tracing at JNI/JVM barriers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
//   + Set _vm_exited flag for threads that are still running native code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
//   + Delete this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
//   + Call exit_globals()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
//      > deletes tty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
//      > deletes PerfMemory resources
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
//   + Return to caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
bool Threads::destroy_vm() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  JavaThread* thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
  // Wait until we are the last non-daemon thread to execute
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  { MutexLocker nu(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
    while (Threads::number_of_non_daemon_threads() > 1 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
      // This wait should make safepoint checks, wait without a timeout,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
      // and wait as a suspend-equivalent condition.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
      // Note: If the FlatProfiler is running and this thread is waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
      // for another non-daemon thread to finish, then the FlatProfiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
      // is waiting for the external suspend request on this thread to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
      // complete. wait_for_ext_suspend_completion() will eventually
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
      // timeout, but that takes time. Making this wait a suspend-
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
      // equivalent condition solves that timeout problem.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
      //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
      Threads_lock->wait(!Mutex::_no_safepoint_check_flag, 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
                         Mutex::_as_suspend_equivalent_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
  // Hang forever on exit if we are reporting an error.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
  if (ShowMessageBoxOnError && is_error_reported()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
    os::infinite_sleep();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
  }
8476
7e34c2d4cf9b 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 8118
diff changeset
  3718
  os::wait_for_keypress_at_exit();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
  if (JDK_Version::is_jdk12x_version()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
    // We are the last thread running, so check if finalizers should be run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
    // For 1.3 or later this is done in thread->invoke_shutdown_hooks()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
    HandleMark rm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
    Universe::run_finalizers_on_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
    // run Java level shutdown hooks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
    thread->invoke_shutdown_hooks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
  before_exit(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
  thread->exit(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
  // Stop VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
    // 4945125 The vm thread comes to a safepoint during exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
    // GC vm_operations can get caught at the safepoint, and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
    // heap is unparseable if they are caught. Grab the Heap_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
    // to prevent this. The GC vm_operations will not be able to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
    // queue until after the vm thread is dead.
9992
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3741
    // After this point, we'll never emerge out of the safepoint before
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3742
    // the VM exits, so concurrent GC threads do not need to be explicitly
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3743
    // stopped; they remain inactive until the process exits.
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3744
    // Note: some concurrent G1 threads may be running during a safepoint,
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3745
    // but these will not be accessing the heap, just some G1-specific side
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3746
    // data structures that are not accessed by any other threads but them
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3747
    // after this point in a terminal safepoint.
0d82cce3e655 7051430: CMS: ongoing CMS cycle should terminate abruptly to allow prompt JVM termination at exit
ysr
parents: 9946
diff changeset
  3748
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
    MutexLocker ml(Heap_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
    VMThread::wait_for_vm_thread_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
    assert(SafepointSynchronize::is_at_safepoint(), "VM thread should exit at Safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
    VMThread::destroy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
  // clean up ideal graph printers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
#if defined(COMPILER2) && !defined(PRODUCT)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
  IdealGraphPrinter::clean_up();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
  // Now, all Java threads are gone except daemon threads. Daemon threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
  // running Java code or in VM are stopped by the Safepoint. However,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
  // daemon threads executing native code are still running.  But they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
  // will be stopped at native=>Java/VM barriers. Note that we can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  // simply kill or suspend them, as it is inherently deadlock-prone.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
  // disable function tracing at JNI/JVM barriers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
  TraceJNICalls = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
  TraceJVMCalls = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
  TraceRuntimeCalls = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
  VM_Exit::set_vm_exited();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
  notify_vm_shutdown();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
  delete thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
  // exit_globals() will delete tty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
  exit_globals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
jboolean Threads::is_supported_jni_version_including_1_1(jint version) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
  if (version == JNI_VERSION_1_1) return JNI_TRUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
  return is_supported_jni_version(version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
jboolean Threads::is_supported_jni_version(jint version) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
  if (version == JNI_VERSION_1_2) return JNI_TRUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
  if (version == JNI_VERSION_1_4) return JNI_TRUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
  if (version == JNI_VERSION_1_6) return JNI_TRUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
  return JNI_FALSE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
void Threads::add(JavaThread* p, bool force_daemon) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
  // The threads lock must be owned at this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
  assert_locked_or_safepoint(Threads_lock);
6768
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  3804
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  3805
  // See the comment for this method in thread.hpp for its purpose and
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  3806
  // why it is called here.
71338ecb7813 6980838: G1: guarantee(false) failed: thread has an unexpected active value in its SATB queue
tonyp
parents: 6764
diff changeset
  3807
  p->initialize_queues();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
  p->set_next(_thread_list);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
  _thread_list = p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
  _number_of_threads++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
  oop threadObj = p->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
  bool daemon = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
  // Bootstrapping problem: threadObj can be null for initial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
  // JavaThread (or for threads attached via JNI)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
  if ((!force_daemon) && (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
    _number_of_non_daemon_threads++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
    daemon = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
  ThreadService::add_thread(p, daemon);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
  // Possible GC point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
  Events::log("Thread added: " INTPTR_FORMAT, p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
void Threads::remove(JavaThread* p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
  // Extra scope needed for Thread_lock, so we can check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
  // that we do not remove thread without safepoint code notice
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
  { MutexLocker ml(Threads_lock);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
    assert(includes(p), "p must be present");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
    JavaThread* current = _thread_list;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
    JavaThread* prev    = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
    while (current != p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
      prev    = current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
      current = current->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
    if (prev) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
      prev->set_next(current->next());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
      _thread_list = p->next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
    _number_of_threads--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
    oop threadObj = p->threadObj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
    bool daemon = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
    if (threadObj == NULL || !java_lang_Thread::is_daemon(threadObj)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
      _number_of_non_daemon_threads--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
      daemon = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
      // Only one thread left, do a notify on the Threads_lock so a thread waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
      // on destroy_vm will wake up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
      if (number_of_non_daemon_threads() == 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
        Threads_lock->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
    ThreadService::remove_thread(p, daemon);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
    // Make sure that safepoint code disregard this thread. This is needed since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3861
    // the thread might mess around with locks after this point. This can cause it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
    // to do callbacks into the safepoint code. However, the safepoint code is not aware
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
    // of this thread since it is removed from the queue.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
    p->set_terminated_value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
  } // unlock Threads_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
  // Since Events::log uses a lock, we grab it outside the Threads_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
  Events::log("Thread exited: " INTPTR_FORMAT, p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
// Threads_lock must be held when this is called (or must be called during a safepoint)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
bool Threads::includes(JavaThread* p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
  assert(Threads_lock->is_locked(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
  ALL_JAVA_THREADS(q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
    if (q == p ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
// Operations on the Threads list for GC.  These are not explicitly locked,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
// but the garbage collector must provide a safe context for them to run.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
// In particular, these things should never be called when the Threads_lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
// is held by some other thread. (Note: the Safepoint abstraction also
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
// uses the Threads_lock to gurantee this property. It also makes sure that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
// all threads gets blocked when exiting or starting).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3889
void Threads::oops_do(OopClosure* f, CodeBlobClosure* cf) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
  ALL_JAVA_THREADS(p) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3891
    p->oops_do(f, cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
  }
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3893
  VMThread::vm_thread()->oops_do(f, cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3896
void Threads::possibly_parallel_oops_do(OopClosure* f, CodeBlobClosure* cf) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
  // Introduce a mechanism allowing parallel threads to claim threads as
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
  // root groups.  Overhead should be small enough to use all the time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3899
  // even in sequential code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3900
  SharedHeap* sh = SharedHeap::heap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
  bool is_par = (sh->n_par_threads() > 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3902
  int cp = SharedHeap::heap()->strong_roots_parity();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
    if (p->claim_oops_do(is_par, cp)) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3905
      p->oops_do(f, cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3907
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3908
  VMThread* vmt = VMThread::vm_thread();
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10546
diff changeset
  3909
  if (vmt->claim_oops_do(is_par, cp)) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3910
    vmt->oops_do(f, cf);
10670
4ea0e7d2ffbc 6484982: G1: process references during evacuation pauses
johnc
parents: 10546
diff changeset
  3911
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3912
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3913
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
#ifndef SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3915
// Used by ParallelScavenge
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3916
void Threads::create_thread_roots_tasks(GCTaskQueue* q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3917
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3918
    q->enqueue(new ThreadRootsTask(p));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3919
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
  q->enqueue(new ThreadRootsTask(VMThread::vm_thread()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
// Used by Parallel Old
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
void Threads::create_thread_roots_marking_tasks(GCTaskQueue* q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
    q->enqueue(new ThreadRootsMarkingTask(p));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
  q->enqueue(new ThreadRootsMarkingTask(VMThread::vm_thread()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
#endif // SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3932
void Threads::nmethods_do(CodeBlobClosure* cf) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
  ALL_JAVA_THREADS(p) {
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3934
    p->nmethods_do(cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
  }
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  3936
  VMThread::vm_thread()->nmethods_do(cf);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
void Threads::gc_epilogue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3941
    p->gc_epilogue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3942
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
void Threads::gc_prologue() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
    p->gc_prologue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
void Threads::deoptimized_wrt_marked_nmethods() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
    p->deoptimized_wrt_marked_nmethods();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3958
// Get count Java threads that are waiting to enter the specified monitor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3959
GrowableArray<JavaThread*>* Threads::get_pending_threads(int count,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
  address monitor, bool doLock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
  assert(doLock || SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
    "must grab Threads_lock or be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
  GrowableArray<JavaThread*>* result = new GrowableArray<JavaThread*>(count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
  int i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
    MutexLockerEx ml(doLock ? Threads_lock : NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
    ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
      if (p->is_Compiler_thread()) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
      address pending = (address)p->current_pending_monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
      if (pending == monitor) {             // found a match
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
        if (i < count) result->append(p);   // save the first count matches
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3974
        i++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3975
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
JavaThread *Threads::owning_thread_from_monitor_owner(address owner, bool doLock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
  assert(doLock ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
         Threads_lock->owned_by_self() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
         SafepointSynchronize::is_at_safepoint(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
         "must grab Threads_lock or be at safepoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
  // NULL owner means not locked so we can skip the search
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
  if (owner == NULL) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
    MutexLockerEx ml(doLock ? Threads_lock : NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
    ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
      // first, see if owner is the address of a Java thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
      if (owner == (address)p) return p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3996
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3998
  assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
  if (UseHeavyMonitors) return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4001
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4002
  // If we didn't find a matching Java thread and we didn't force use of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4003
  // heavyweight monitors, then the owner is the stack address of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
  // Lock Word in the owning Java thread's stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4006
  JavaThread* the_owner = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4007
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4008
    MutexLockerEx ml(doLock ? Threads_lock : NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
    ALL_JAVA_THREADS(q) {
2526
39a58a50be35 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 2336
diff changeset
  4010
      if (q->is_lock_owned(owner)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
        the_owner = q;
2526
39a58a50be35 6699669: Hotspot server leaves synchronized block with monitor in bad state
xlu
parents: 2336
diff changeset
  4012
        break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4013
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4014
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4015
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
  assert(the_owner != NULL, "Did not find owning Java thread for lock word address");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
  return the_owner;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4018
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4020
// Threads::print_on() is called at safepoint by VM_PrintThreads operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4021
void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4022
  char buf[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4023
  st->print_cr(os::local_time_string(buf, sizeof(buf)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
  st->print_cr("Full thread dump %s (%s %s):",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
                Abstract_VM_Version::vm_name(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
                Abstract_VM_Version::vm_release(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
                Abstract_VM_Version::vm_info_string()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
               );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
#ifndef SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
  // Dump concurrent locks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
  ConcurrentLocksDump concurrent_locks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
  if (print_concurrent_locks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
    concurrent_locks.dump_at_safepoint();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
#endif // SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
    ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
    p->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
    if (print_stacks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
      if (internal_format) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
        p->trace_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
        p->print_stack_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
#ifndef SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
    if (print_concurrent_locks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
      concurrent_locks.print_locks_on(p, st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
#endif // SERIALGC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
  VMThread::vm_thread()->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4059
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4060
  Universe::heap()->print_gc_threads_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
  WatcherThread* wt = WatcherThread::watcher_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4062
  if (wt != NULL) wt->print_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4063
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4064
  CompileBroker::print_compiler_threads_on(st);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4065
  st->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
// Threads::print_on_error() is called by fatal error handler. It's possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
// that VM is not at safepoint and/or current thread is inside signal handler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
// Don't print stack trace, as the stack may not be walkable. Don't allocate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
// memory (even in resource area), it might deadlock the error handler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
void Threads::print_on_error(outputStream* st, Thread* current, char* buf, int buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
  bool found_current = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
  st->print_cr("Java Threads: ( => current thread )");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
  ALL_JAVA_THREADS(thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
    bool is_current = (current == thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
    found_current = found_current || is_current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
    st->print("%s", is_current ? "=>" : "  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
    st->print(PTR_FORMAT, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
    st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4083
    thread->print_on_error(st, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4085
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
  st->print_cr("Other Threads:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
  if (VMThread::vm_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
    bool is_current = (current == VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
    found_current = found_current || is_current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
    st->print("%s", current == VMThread::vm_thread() ? "=>" : "  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
    st->print(PTR_FORMAT, VMThread::vm_thread());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
    st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
    VMThread::vm_thread()->print_on_error(st, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
  WatcherThread* wt = WatcherThread::watcher_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
  if (wt != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4101
    bool is_current = (current == wt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
    found_current = found_current || is_current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
    st->print("%s", is_current ? "=>" : "  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
    st->print(PTR_FORMAT, wt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
    st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
    wt->print_on_error(st, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
  if (!found_current) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
    st->print("=>" PTR_FORMAT " (exited) ", current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
    current->print_on_error(st, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
    st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4118
// Internal SpinLock and Mutex
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4119
// Based on ParkEvent
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4120
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4121
// Ad-hoc mutual exclusion primitives: SpinLock and Mux
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
//
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4123
// We employ SpinLocks _only for low-contention, fixed-length
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4124
// short-duration critical sections where we're concerned
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4125
// about native mutex_t or HotSpot Mutex:: latency.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4126
// The mux construct provides a spin-then-block mutual exclusion
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4127
// mechanism.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4128
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4129
// Testing has shown that contention on the ListLock guarding gFreeList
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4130
// is common.  If we implement ListLock as a simple SpinLock it's common
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4131
// for the JVM to devolve to yielding with little progress.  This is true
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4132
// despite the fact that the critical sections protected by ListLock are
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4133
// extremely short.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
//
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4135
// TODO-FIXME: ListLock should be of type SpinLock.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4136
// We should make this a 1st-class type, integrated into the lock
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4137
// hierarchy as leaf-locks.  Critically, the SpinLock structure
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4138
// should have sufficient padding to avoid false-sharing and excessive
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4139
// cache-coherency traffic.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4140
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4141
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4142
typedef volatile int SpinLockT ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4143
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4144
void Thread::SpinAcquire (volatile int * adr, const char * LockName) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4145
  if (Atomic::cmpxchg (1, adr, 0) == 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4146
     return ;   // normal fast-path return
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4147
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4148
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4149
  // Slow-path : We've encountered contention -- Spin/Yield/Block strategy.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4150
  TEVENT (SpinAcquire - ctx) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4151
  int ctr = 0 ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4152
  int Yields = 0 ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
  for (;;) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4154
     while (*adr != 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4155
        ++ctr ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4156
        if ((ctr & 0xFFF) == 0 || !os::is_MP()) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4157
           if (Yields > 5) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4158
             // Consider using a simple NakedSleep() instead.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4159
             // Then SpinAcquire could be called by non-JVM threads
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4160
             Thread::current()->_ParkEvent->park(1) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4161
           } else {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4162
             os::NakedYield() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4163
             ++Yields ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4164
           }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4165
        } else {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4166
           SpinPause() ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
        }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4168
     }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4169
     if (Atomic::cmpxchg (1, adr, 0) == 0) return ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4173
void Thread::SpinRelease (volatile int * adr) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4174
  assert (*adr != 0, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4175
  OrderAccess::fence() ;      // guarantee at least release consistency.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4176
  // Roach-motel semantics.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4177
  // It's safe if subsequent LDs and STs float "up" into the critical section,
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4178
  // but prior LDs and STs within the critical section can't be allowed
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4179
  // to reorder or float past the ST that releases the lock.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4180
  *adr = 0 ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4183
// muxAcquire and muxRelease:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4184
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4185
// *  muxAcquire and muxRelease support a single-word lock-word construct.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4186
//    The LSB of the word is set IFF the lock is held.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4187
//    The remainder of the word points to the head of a singly-linked list
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4188
//    of threads blocked on the lock.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4189
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4190
// *  The current implementation of muxAcquire-muxRelease uses its own
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4191
//    dedicated Thread._MuxEvent instance.  If we're interested in
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4192
//    minimizing the peak number of extant ParkEvent instances then
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4193
//    we could eliminate _MuxEvent and "borrow" _ParkEvent as long
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4194
//    as certain invariants were satisfied.  Specifically, care would need
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4195
//    to be taken with regards to consuming unpark() "permits".
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4196
//    A safe rule of thumb is that a thread would never call muxAcquire()
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4197
//    if it's enqueued (cxq, EntryList, WaitList, etc) and will subsequently
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4198
//    park().  Otherwise the _ParkEvent park() operation in muxAcquire() could
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4199
//    consume an unpark() permit intended for monitorenter, for instance.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4200
//    One way around this would be to widen the restricted-range semaphore
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4201
//    implemented in park().  Another alternative would be to provide
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4202
//    multiple instances of the PlatformEvent() for each thread.  One
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4203
//    instance would be dedicated to muxAcquire-muxRelease, for instance.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4204
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4205
// *  Usage:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4206
//    -- Only as leaf locks
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4207
//    -- for short-term locking only as muxAcquire does not perform
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4208
//       thread state transitions.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4209
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4210
// Alternatives:
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4211
// *  We could implement muxAcquire and muxRelease with MCS or CLH locks
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4212
//    but with parking or spin-then-park instead of pure spinning.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4213
// *  Use Taura-Oyama-Yonenzawa locks.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4214
// *  It's possible to construct a 1-0 lock if we encode the lockword as
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4215
//    (List,LockByte).  Acquire will CAS the full lockword while Release
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4216
//    will STB 0 into the LockByte.  The 1-0 scheme admits stranding, so
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4217
//    acquiring threads use timers (ParkTimed) to detect and recover from
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4218
//    the stranding window.  Thread/Node structures must be aligned on 256-byte
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4219
//    boundaries by using placement-new.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4220
// *  Augment MCS with advisory back-link fields maintained with CAS().
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4221
//    Pictorially:  LockWord -> T1 <-> T2 <-> T3 <-> ... <-> Tn <-> Owner.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4222
//    The validity of the backlinks must be ratified before we trust the value.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4223
//    If the backlinks are invalid the exiting thread must back-track through the
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4224
//    the forward links, which are always trustworthy.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4225
// *  Add a successor indication.  The LockWord is currently encoded as
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4226
//    (List, LOCKBIT:1).  We could also add a SUCCBIT or an explicit _succ variable
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4227
//    to provide the usual futile-wakeup optimization.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4228
//    See RTStt for details.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4229
// *  Consider schedctl.sc_nopreempt to cover the critical section.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4230
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4231
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4232
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4233
typedef volatile intptr_t MutexT ;      // Mux Lock-word
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4234
enum MuxBits { LOCKBIT = 1 } ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4235
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4236
void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4237
  intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4238
  if (w == 0) return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4239
  if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4240
     return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4241
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4242
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4243
  TEVENT (muxAcquire - Contention) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4244
  ParkEvent * const Self = Thread::current()->_MuxEvent ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4245
  assert ((intptr_t(Self) & LOCKBIT) == 0, "invariant") ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
  for (;;) {
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4247
     int its = (os::is_MP() ? 100 : 0) + 1 ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4248
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4249
     // Optional spin phase: spin-then-park strategy
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4250
     while (--its >= 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4251
       w = *Lock ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4252
       if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4253
          return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4254
       }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4255
     }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4256
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4257
     Self->reset() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4258
     Self->OnList = intptr_t(Lock) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4259
     // The following fence() isn't _strictly necessary as the subsequent
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4260
     // CAS() both serializes execution and ratifies the fetched *Lock value.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4261
     OrderAccess::fence();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4262
     for (;;) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4263
        w = *Lock ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4264
        if ((w & LOCKBIT) == 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4265
            if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4266
                Self->OnList = 0 ;   // hygiene - allows stronger asserts
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4267
                return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4268
            }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4269
            continue ;      // Interference -- *Lock changed -- Just retry
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
        }
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4271
        assert (w & LOCKBIT, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4272
        Self->ListNext = (ParkEvent *) (w & ~LOCKBIT );
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4273
        if (Atomic::cmpxchg_ptr (intptr_t(Self)|LOCKBIT, Lock, w) == w) break ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4274
     }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4275
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4276
     while (Self->OnList != 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4277
        Self->park() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4278
     }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
6975
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4282
void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4283
  intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4284
  if (w == 0) return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4285
  if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4286
    return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4287
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4288
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4289
  TEVENT (muxAcquire - Contention) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4290
  ParkEvent * ReleaseAfter = NULL ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4291
  if (ev == NULL) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4292
    ev = ReleaseAfter = ParkEvent::Allocate (NULL) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4293
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4294
  assert ((intptr_t(ev) & LOCKBIT) == 0, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4295
  for (;;) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4296
    guarantee (ev->OnList == 0, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4297
    int its = (os::is_MP() ? 100 : 0) + 1 ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4298
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4299
    // Optional spin phase: spin-then-park strategy
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4300
    while (--its >= 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4301
      w = *Lock ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4302
      if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4303
        if (ReleaseAfter != NULL) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4304
          ParkEvent::Release (ReleaseAfter) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4305
        }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4306
        return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4307
      }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4308
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4309
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4310
    ev->reset() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4311
    ev->OnList = intptr_t(Lock) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4312
    // The following fence() isn't _strictly necessary as the subsequent
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4313
    // CAS() both serializes execution and ratifies the fetched *Lock value.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4314
    OrderAccess::fence();
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4315
    for (;;) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4316
      w = *Lock ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4317
      if ((w & LOCKBIT) == 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4318
        if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4319
          ev->OnList = 0 ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4320
          // We call ::Release while holding the outer lock, thus
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4321
          // artificially lengthening the critical section.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4322
          // Consider deferring the ::Release() until the subsequent unlock(),
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4323
          // after we've dropped the outer lock.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4324
          if (ReleaseAfter != NULL) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4325
            ParkEvent::Release (ReleaseAfter) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4326
          }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4327
          return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4328
        }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4329
        continue ;      // Interference -- *Lock changed -- Just retry
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4330
      }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4331
      assert (w & LOCKBIT, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4332
      ev->ListNext = (ParkEvent *) (w & ~LOCKBIT );
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4333
      if (Atomic::cmpxchg_ptr (intptr_t(ev)|LOCKBIT, Lock, w) == w) break ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4334
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4335
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4336
    while (ev->OnList != 0) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4337
      ev->park() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4338
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4339
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4340
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4341
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4342
// Release() must extract a successor from the list and then wake that thread.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4343
// It can "pop" the front of the list or use a detach-modify-reattach (DMR) scheme
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4344
// similar to that used by ParkEvent::Allocate() and ::Release().  DMR-based
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4345
// Release() would :
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4346
// (A) CAS() or swap() null to *Lock, releasing the lock and detaching the list.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4347
// (B) Extract a successor from the private list "in-hand"
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4348
// (C) attempt to CAS() the residual back into *Lock over null.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4349
//     If there were any newly arrived threads and the CAS() would fail.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4350
//     In that case Release() would detach the RATs, re-merge the list in-hand
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4351
//     with the RATs and repeat as needed.  Alternately, Release() might
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4352
//     detach and extract a successor, but then pass the residual list to the wakee.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4353
//     The wakee would be responsible for reattaching and remerging before it
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4354
//     competed for the lock.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4355
//
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4356
// Both "pop" and DMR are immune from ABA corruption -- there can be
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4357
// multiple concurrent pushers, but only one popper or detacher.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4358
// This implementation pops from the head of the list.  This is unfair,
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4359
// but tends to provide excellent throughput as hot threads remain hot.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4360
// (We wake recently run threads first).
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4361
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4362
void Thread::muxRelease (volatile intptr_t * Lock)  {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4363
  for (;;) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4364
    const intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4365
    assert (w & LOCKBIT, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4366
    if (w == LOCKBIT) return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4367
    ParkEvent * List = (ParkEvent *) (w & ~LOCKBIT) ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4368
    assert (List != NULL, "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4369
    assert (List->OnList == intptr_t(Lock), "invariant") ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4370
    ParkEvent * nxt = List->ListNext ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4371
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4372
    // The following CAS() releases the lock and pops the head element.
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4373
    if (Atomic::cmpxchg_ptr (intptr_t(nxt), Lock, w) != w) {
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4374
      continue ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4375
    }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4376
    List->OnList = 0 ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4377
    OrderAccess::fence() ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4378
    List->unpark () ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4379
    return ;
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4380
  }
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4381
}
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4382
dc9b63952682 6988353: refactor contended sync subsystem
acorn
parents: 6968
diff changeset
  4383
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
void Threads::verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  ALL_JAVA_THREADS(p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
    p->verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
  VMThread* thread = VMThread::vm_thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
  if (thread != NULL) thread->verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
}