Merge

Mon, 28 Feb 2011 15:35:45 -0800

author
rottenha
date
Mon, 28 Feb 2011 15:35:45 -0800
changeset 2586
23ae54207126
parent 2578
658d198b2e04
parent 2584
da091bb67459
child 2587
cef8c988e7b8

Merge

src/os/solaris/vm/os_solaris.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/java.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/linux/vm/os_linux.cpp	Fri Feb 25 12:46:49 2011 -0800
     1.2 +++ b/src/os/linux/vm/os_linux.cpp	Mon Feb 28 15:35:45 2011 -0800
     1.3 @@ -2213,7 +2213,7 @@
     1.4    if (rp == NULL)
     1.5      return;
     1.6  
     1.7 -  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
     1.8 +  if (Arguments::created_by_gamma_launcher()) {
     1.9      // Support for the gamma launcher.  Typical value for buf is
    1.10      // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
    1.11      // the right place in the string, then assume we are installed in a JDK and
     2.1 --- a/src/os/posix/vm/os_posix.cpp	Fri Feb 25 12:46:49 2011 -0800
     2.2 +++ b/src/os/posix/vm/os_posix.cpp	Mon Feb 28 15:35:45 2011 -0800
     2.3 @@ -59,3 +59,12 @@
     2.4    VMError::report_coredump_status(buffer, success);
     2.5  }
     2.6  
     2.7 +bool os::is_debugger_attached() {
     2.8 +  // not implemented
     2.9 +  return false;
    2.10 +}
    2.11 +
    2.12 +void os::wait_for_keypress_at_exit(void) {
    2.13 +  // don't do anything on posix platforms
    2.14 +  return;
    2.15 +}
     3.1 --- a/src/os/solaris/vm/os_solaris.cpp	Fri Feb 25 12:46:49 2011 -0800
     3.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Mon Feb 28 15:35:45 2011 -0800
     3.3 @@ -2511,7 +2511,7 @@
     3.4    assert(ret != 0, "cannot locate libjvm");
     3.5    realpath((char *)dlinfo.dli_fname, buf);
     3.6  
     3.7 -  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
     3.8 +  if (Arguments::created_by_gamma_launcher()) {
     3.9      // Support for the gamma launcher.  Typical value for buf is
    3.10      // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
    3.11      // the right place in the string, then assume we are installed in a JDK and
     4.1 --- a/src/os/windows/vm/os_windows.cpp	Fri Feb 25 12:46:49 2011 -0800
     4.2 +++ b/src/os/windows/vm/os_windows.cpp	Mon Feb 28 15:35:45 2011 -0800
     4.3 @@ -1788,7 +1788,7 @@
     4.4    }
     4.5  
     4.6    buf[0] = '\0';
     4.7 -  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
     4.8 +  if (Arguments::created_by_gamma_launcher()) {
     4.9       // Support for the gamma launcher. Check for an
    4.10       // JAVA_HOME environment variable
    4.11       // and fix up the path so it looks like
    4.12 @@ -3418,6 +3418,19 @@
    4.13  }
    4.14  
    4.15  
    4.16 +bool os::is_debugger_attached() {
    4.17 +  return IsDebuggerPresent() ? true : false;
    4.18 +}
    4.19 +
    4.20 +
    4.21 +void os::wait_for_keypress_at_exit(void) {
    4.22 +  if (PauseAtExit) {
    4.23 +    fprintf(stderr, "Press any key to continue...\n");
    4.24 +    fgetc(stdin);
    4.25 +  }
    4.26 +}
    4.27 +
    4.28 +
    4.29  int os::message_box(const char* title, const char* message) {
    4.30    int result = MessageBox(NULL, message, title,
    4.31                            MB_YESNO | MB_ICONERROR | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY);
     5.1 --- a/src/share/vm/prims/jvmtiExport.cpp	Fri Feb 25 12:46:49 2011 -0800
     5.2 +++ b/src/share/vm/prims/jvmtiExport.cpp	Mon Feb 28 15:35:45 2011 -0800
     5.3 @@ -1805,6 +1805,10 @@
     5.4  
     5.5  void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
     5.6    JavaThread* thread = JavaThread::current();
     5.7 +  // In theory everyone coming thru here is in_vm but we need to be certain
     5.8 +  // because a callee will do a vm->native transition
     5.9 +  ThreadInVMfromUnknown __tiv;
    5.10 +
    5.11    EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED,
    5.12                   ("JVMTI [%s] method dynamic code generated event triggered",
    5.13                   JvmtiTrace::safe_get_thread_name(thread)));
    5.14 @@ -1826,19 +1830,18 @@
    5.15  }
    5.16  
    5.17  void JvmtiExport::post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) {
    5.18 -  // In theory everyone coming thru here is in_vm but we need to be certain
    5.19 -  // because a callee will do a vm->native transition
    5.20 -  ThreadInVMfromUnknown __tiv;
    5.21    jvmtiPhase phase = JvmtiEnv::get_phase();
    5.22    if (phase == JVMTI_PHASE_PRIMORDIAL || phase == JVMTI_PHASE_START) {
    5.23      post_dynamic_code_generated_internal(name, code_begin, code_end);
    5.24 -    return;
    5.25 +  } else {
    5.26 +    // It may not be safe to post the event from this thread.  Defer all
    5.27 +    // postings to the service thread so that it can perform them in a safe
    5.28 +    // context and in-order.
    5.29 +    MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    5.30 +    JvmtiDeferredEvent event = JvmtiDeferredEvent::dynamic_code_generated_event(
    5.31 +        name, code_begin, code_end);
    5.32 +    JvmtiDeferredEventQueue::enqueue(event);
    5.33    }
    5.34 -
    5.35 -  // Blocks until everything now in the queue has been posted
    5.36 -  JvmtiDeferredEventQueue::flush_queue(Thread::current());
    5.37 -
    5.38 -  post_dynamic_code_generated_internal(name, code_begin, code_end);
    5.39  }
    5.40  
    5.41  
     6.1 --- a/src/share/vm/prims/jvmtiExport.hpp	Fri Feb 25 12:46:49 2011 -0800
     6.2 +++ b/src/share/vm/prims/jvmtiExport.hpp	Mon Feb 28 15:35:45 2011 -0800
     6.3 @@ -140,12 +140,12 @@
     6.4                                        char sig_type, jvalue *value);
     6.5  
     6.6  
     6.7 - private:
     6.8    // posts a DynamicCodeGenerated event (internal/private implementation).
     6.9    // The public post_dynamic_code_generated* functions make use of the
    6.10 -  // internal implementation.
    6.11 +  // internal implementation.  Also called from JvmtiDeferredEvent::post()
    6.12    static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN;
    6.13  
    6.14 + private:
    6.15  
    6.16    // GenerateEvents support to allow posting of CompiledMethodLoad and
    6.17    // DynamicCodeGenerated events for a given environment.
     7.1 --- a/src/share/vm/prims/jvmtiImpl.cpp	Fri Feb 25 12:46:49 2011 -0800
     7.2 +++ b/src/share/vm/prims/jvmtiImpl.cpp	Mon Feb 28 15:35:45 2011 -0800
     7.3 @@ -918,7 +918,7 @@
     7.4  JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event(
     7.5      nmethod* nm) {
     7.6    JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD);
     7.7 -  event.set_compiled_method_load(nm);
     7.8 +  event._event_data.compiled_method_load = nm;
     7.9    nmethodLocker::lock_nmethod(nm); // will be unlocked when posted
    7.10    return event;
    7.11  }
    7.12 @@ -926,23 +926,39 @@
    7.13  JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event(
    7.14      jmethodID id, const void* code) {
    7.15    JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD);
    7.16 -  event.set_compiled_method_unload(id, code);
    7.17 +  event._event_data.compiled_method_unload.method_id = id;
    7.18 +  event._event_data.compiled_method_unload.code_begin = code;
    7.19 +  return event;
    7.20 +}
    7.21 +JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event(
    7.22 +      const char* name, const void* code_begin, const void* code_end) {
    7.23 +  JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED);
    7.24 +  event._event_data.dynamic_code_generated.name = name;
    7.25 +  event._event_data.dynamic_code_generated.code_begin = code_begin;
    7.26 +  event._event_data.dynamic_code_generated.code_end = code_end;
    7.27    return event;
    7.28  }
    7.29  
    7.30  void JvmtiDeferredEvent::post() {
    7.31 +  assert(ServiceThread::is_service_thread(Thread::current()),
    7.32 +         "Service thread must post enqueued events");
    7.33    switch(_type) {
    7.34 -    case TYPE_COMPILED_METHOD_LOAD:
    7.35 -      JvmtiExport::post_compiled_method_load(compiled_method_load());
    7.36 -      nmethodLocker::unlock_nmethod(compiled_method_load());
    7.37 +    case TYPE_COMPILED_METHOD_LOAD: {
    7.38 +      nmethod* nm = _event_data.compiled_method_load;
    7.39 +      JvmtiExport::post_compiled_method_load(nm);
    7.40 +      nmethodLocker::unlock_nmethod(nm);
    7.41        break;
    7.42 +    }
    7.43      case TYPE_COMPILED_METHOD_UNLOAD:
    7.44        JvmtiExport::post_compiled_method_unload(
    7.45 -        compiled_method_unload_method_id(),
    7.46 -        compiled_method_unload_code_begin());
    7.47 +        _event_data.compiled_method_unload.method_id,
    7.48 +        _event_data.compiled_method_unload.code_begin);
    7.49        break;
    7.50 -    case TYPE_FLUSH:
    7.51 -      JvmtiDeferredEventQueue::flush_complete(flush_state_addr());
    7.52 +    case TYPE_DYNAMIC_CODE_GENERATED:
    7.53 +      JvmtiExport::post_dynamic_code_generated_internal(
    7.54 +        _event_data.dynamic_code_generated.name,
    7.55 +        _event_data.dynamic_code_generated.code_begin,
    7.56 +        _event_data.dynamic_code_generated.code_end);
    7.57        break;
    7.58      default:
    7.59        ShouldNotReachHere();
    7.60 @@ -1065,54 +1081,4 @@
    7.61    }
    7.62  }
    7.63  
    7.64 -enum {
    7.65 -  // Random - used for debugging
    7.66 -  FLUSHING  = 0x50403020,
    7.67 -  FLUSHED   = 0x09080706
    7.68 -};
    7.69 -
    7.70 -void JvmtiDeferredEventQueue::flush_queue(Thread* thread) {
    7.71 -
    7.72 -  volatile int flush_state = FLUSHING;
    7.73 -
    7.74 -  JvmtiDeferredEvent flush(JvmtiDeferredEvent::TYPE_FLUSH);
    7.75 -  flush.set_flush_state_addr((int*)&flush_state);
    7.76 -
    7.77 -  if (ServiceThread::is_service_thread(thread)) {
    7.78 -    // If we are the service thread we have to post all preceding events
    7.79 -    // Use the flush event as a token to indicate when we can stop
    7.80 -    JvmtiDeferredEvent event;
    7.81 -    {
    7.82 -      MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    7.83 -      enqueue(flush);
    7.84 -      event = dequeue();
    7.85 -    }
    7.86 -    while (!event.is_flush_event() ||
    7.87 -           event.flush_state_addr() != &flush_state) {
    7.88 -      event.post();
    7.89 -      {
    7.90 -        MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    7.91 -        event = dequeue();
    7.92 -      }
    7.93 -    }
    7.94 -  } else {
    7.95 -    // Wake up the service thread so it will process events.  When it gets
    7.96 -    // to the flush event it will set 'flush_complete' and notify us.
    7.97 -    MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
    7.98 -    enqueue(flush);
    7.99 -    while (flush_state != FLUSHED) {
   7.100 -      assert(flush_state == FLUSHING || flush_state == FLUSHED,
   7.101 -             "only valid values for this");
   7.102 -      Service_lock->wait(Mutex::_no_safepoint_check_flag);
   7.103 -    }
   7.104 -  }
   7.105 -}
   7.106 -
   7.107 -void JvmtiDeferredEventQueue::flush_complete(int* state_addr) {
   7.108 -  assert(state_addr != NULL && *state_addr == FLUSHING, "must be");
   7.109 -  MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
   7.110 -  *state_addr = FLUSHED;
   7.111 -  Service_lock->notify_all();
   7.112 -}
   7.113 -
   7.114  #endif // ndef KERNEL
     8.1 --- a/src/share/vm/prims/jvmtiImpl.hpp	Fri Feb 25 12:46:49 2011 -0800
     8.2 +++ b/src/share/vm/prims/jvmtiImpl.hpp	Mon Feb 28 15:35:45 2011 -0800
     8.3 @@ -451,7 +451,7 @@
     8.4      TYPE_NONE,
     8.5      TYPE_COMPILED_METHOD_LOAD,
     8.6      TYPE_COMPILED_METHOD_UNLOAD,
     8.7 -    TYPE_FLUSH // pseudo-event used to implement flush_queue()
     8.8 +    TYPE_DYNAMIC_CODE_GENERATED
     8.9    } Type;
    8.10  
    8.11    Type _type;
    8.12 @@ -461,49 +461,15 @@
    8.13        jmethodID method_id;
    8.14        const void* code_begin;
    8.15      } compiled_method_unload;
    8.16 -    int* flush_state_addr;
    8.17 +    struct {
    8.18 +      const char* name;
    8.19 +      const void* code_begin;
    8.20 +      const void* code_end;
    8.21 +    } dynamic_code_generated;
    8.22    } _event_data;
    8.23  
    8.24    JvmtiDeferredEvent(Type t) : _type(t) {}
    8.25  
    8.26 -  void set_compiled_method_load(nmethod* nm) {
    8.27 -    assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be");
    8.28 -    _event_data.compiled_method_load = nm;
    8.29 -  }
    8.30 -
    8.31 -  nmethod* compiled_method_load() const {
    8.32 -    assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be");
    8.33 -    return _event_data.compiled_method_load;
    8.34 -  }
    8.35 -
    8.36 -  void set_compiled_method_unload(jmethodID id, const void* code) {
    8.37 -    assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be");
    8.38 -    _event_data.compiled_method_unload.method_id = id;
    8.39 -    _event_data.compiled_method_unload.code_begin = code;
    8.40 -  }
    8.41 -
    8.42 -  jmethodID compiled_method_unload_method_id() const {
    8.43 -    assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be");
    8.44 -    return _event_data.compiled_method_unload.method_id;
    8.45 -  }
    8.46 -
    8.47 -  const void* compiled_method_unload_code_begin() const {
    8.48 -    assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be");
    8.49 -    return _event_data.compiled_method_unload.code_begin;
    8.50 -  }
    8.51 -
    8.52 -  bool is_flush_event() const { return _type == TYPE_FLUSH; }
    8.53 -
    8.54 -  int* flush_state_addr() const {
    8.55 -    assert(is_flush_event(), "must be");
    8.56 -    return _event_data.flush_state_addr;
    8.57 -  }
    8.58 -
    8.59 -  void set_flush_state_addr(int* flag) {
    8.60 -    assert(is_flush_event(), "must be");
    8.61 -    _event_data.flush_state_addr = flag;
    8.62 -  }
    8.63 -
    8.64   public:
    8.65  
    8.66    JvmtiDeferredEvent() : _type(TYPE_NONE) {}
    8.67 @@ -513,6 +479,9 @@
    8.68      KERNEL_RETURN_(JvmtiDeferredEvent());
    8.69    static JvmtiDeferredEvent compiled_method_unload_event(
    8.70        jmethodID id, const void* code) KERNEL_RETURN_(JvmtiDeferredEvent());
    8.71 +  static JvmtiDeferredEvent dynamic_code_generated_event(
    8.72 +      const char* name, const void* begin, const void* end)
    8.73 +          KERNEL_RETURN_(JvmtiDeferredEvent());
    8.74  
    8.75    // Actually posts the event.
    8.76    void post() KERNEL_RETURN;
    8.77 @@ -548,25 +517,12 @@
    8.78    // Transfers events from the _pending_list to the _queue.
    8.79    static void process_pending_events() KERNEL_RETURN;
    8.80  
    8.81 -  static void flush_complete(int* flush_state) KERNEL_RETURN;
    8.82 -
    8.83   public:
    8.84    // Must be holding Service_lock when calling these
    8.85    static bool has_events() KERNEL_RETURN_(false);
    8.86    static void enqueue(const JvmtiDeferredEvent& event) KERNEL_RETURN;
    8.87    static JvmtiDeferredEvent dequeue() KERNEL_RETURN_(JvmtiDeferredEvent());
    8.88  
    8.89 -  // This call blocks until all events enqueued prior to this call
    8.90 -  // have been posted.  The Service_lock is acquired and waited upon.
    8.91 -  //
    8.92 -  // Implemented by creating a "flush" event and placing it in the queue.
    8.93 -  // When the flush event is "posted" it will call flush_complete(), which
    8.94 -  // will release the caller.
    8.95 -  //
    8.96 -  // Can be called by any thread (maybe even the service thread itself).
    8.97 -  // Not necessary for the caller to be a JavaThread.
    8.98 -  static void flush_queue(Thread* current) KERNEL_RETURN;
    8.99 -
   8.100    // Used to enqueue events without using a lock, for times (such as during
   8.101    // safepoint) when we can't or don't want to lock the Service_lock.
   8.102    //
     9.1 --- a/src/share/vm/runtime/arguments.cpp	Fri Feb 25 12:46:49 2011 -0800
     9.2 +++ b/src/share/vm/runtime/arguments.cpp	Mon Feb 28 15:35:45 2011 -0800
     9.3 @@ -78,6 +78,7 @@
     9.4  const char*  Arguments::_java_vendor_url_bug    = DEFAULT_VENDOR_URL_BUG;
     9.5  const char*  Arguments::_sun_java_launcher      = DEFAULT_JAVA_LAUNCHER;
     9.6  int    Arguments::_sun_java_launcher_pid        = -1;
     9.7 +bool   Arguments::_created_by_gamma_launcher    = false;
     9.8  
     9.9  // These parameters are reset in method parse_vm_init_args(JavaVMInitArgs*)
    9.10  bool   Arguments::_AlwaysCompileLoopMethods     = AlwaysCompileLoopMethods;
    9.11 @@ -1656,6 +1657,9 @@
    9.12  
    9.13  void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) {
    9.14    _sun_java_launcher = strdup(launcher);
    9.15 +  if (strcmp("gamma", _sun_java_launcher) == 0) {
    9.16 +    _created_by_gamma_launcher = true;
    9.17 +  }
    9.18  }
    9.19  
    9.20  bool Arguments::created_by_java_launcher() {
    9.21 @@ -1663,6 +1667,10 @@
    9.22    return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0;
    9.23  }
    9.24  
    9.25 +bool Arguments::created_by_gamma_launcher() {
    9.26 +  return _created_by_gamma_launcher;
    9.27 +}
    9.28 +
    9.29  //===========================================================================================================
    9.30  // Parsing of main arguments
    9.31  
    9.32 @@ -3155,6 +3163,16 @@
    9.33      }
    9.34    }
    9.35  
    9.36 +  // set PauseAtExit if the gamma launcher was used and a debugger is attached
    9.37 +  // but only if not already set on the commandline
    9.38 +  if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) {
    9.39 +    bool set = false;
    9.40 +    CommandLineFlags::wasSetOnCmdline("PauseAtExit", &set);
    9.41 +    if (!set) {
    9.42 +      FLAG_SET_DEFAULT(PauseAtExit, true);
    9.43 +    }
    9.44 +  }
    9.45 +
    9.46    return JNI_OK;
    9.47  }
    9.48  
    10.1 --- a/src/share/vm/runtime/arguments.hpp	Fri Feb 25 12:46:49 2011 -0800
    10.2 +++ b/src/share/vm/runtime/arguments.hpp	Mon Feb 28 15:35:45 2011 -0800
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -257,6 +257,9 @@
   10.11    // sun.java.launcher.pid, private property
   10.12    static int    _sun_java_launcher_pid;
   10.13  
   10.14 +  // was this VM created by the gamma launcher
   10.15 +  static bool   _created_by_gamma_launcher;
   10.16 +
   10.17    // Option flags
   10.18    static bool   _has_profile;
   10.19    static bool   _has_alloc_profile;
   10.20 @@ -444,6 +447,8 @@
   10.21    static const char* sun_java_launcher()    { return _sun_java_launcher; }
   10.22    // Was VM created by a Java launcher?
   10.23    static bool created_by_java_launcher();
   10.24 +  // Was VM created by the gamma Java launcher?
   10.25 +  static bool created_by_gamma_launcher();
   10.26    // -Dsun.java.launcher.pid
   10.27    static int sun_java_launcher_pid()        { return _sun_java_launcher_pid; }
   10.28  
    11.1 --- a/src/share/vm/runtime/globals.hpp	Fri Feb 25 12:46:49 2011 -0800
    11.2 +++ b/src/share/vm/runtime/globals.hpp	Mon Feb 28 15:35:45 2011 -0800
    11.3 @@ -3733,6 +3733,9 @@
    11.4            "The file to create and for whose removal to await when pausing " \
    11.5            "at startup. (default: ./vm.paused.<pid>)")                       \
    11.6                                                                              \
    11.7 +  diagnostic(bool, PauseAtExit, false,                                      \
    11.8 +          "Pause and wait for keypress on exit if a debugger is attached")  \
    11.9 +                                                                            \
   11.10    product(bool, ExtendedDTraceProbes,    false,                             \
   11.11            "Enable performance-impacting dtrace probes")                     \
   11.12                                                                              \
    12.1 --- a/src/share/vm/runtime/java.cpp	Fri Feb 25 12:46:49 2011 -0800
    12.2 +++ b/src/share/vm/runtime/java.cpp	Mon Feb 28 15:35:45 2011 -0800
    12.3 @@ -551,6 +551,7 @@
    12.4  
    12.5  void vm_direct_exit(int code) {
    12.6    notify_vm_shutdown();
    12.7 +  os::wait_for_keypress_at_exit();
    12.8    ::exit(code);
    12.9  }
   12.10  
   12.11 @@ -577,11 +578,13 @@
   12.12  void vm_shutdown()
   12.13  {
   12.14    vm_perform_shutdown_actions();
   12.15 +  os::wait_for_keypress_at_exit();
   12.16    os::shutdown();
   12.17  }
   12.18  
   12.19  void vm_abort(bool dump_core) {
   12.20    vm_perform_shutdown_actions();
   12.21 +  os::wait_for_keypress_at_exit();
   12.22    os::abort(dump_core);
   12.23    ShouldNotReachHere();
   12.24  }
    13.1 --- a/src/share/vm/runtime/os.hpp	Fri Feb 25 12:46:49 2011 -0800
    13.2 +++ b/src/share/vm/runtime/os.hpp	Mon Feb 28 15:35:45 2011 -0800
    13.3 @@ -492,6 +492,12 @@
    13.4    static void print_location(outputStream* st, intptr_t x, bool verbose = false);
    13.5    static size_t lasterror(char *buf, size_t len);
    13.6  
    13.7 +  // Determines whether the calling process is being debugged by a user-mode debugger.
    13.8 +  static bool is_debugger_attached();
    13.9 +
   13.10 +  // wait for a key press if PauseAtExit is set
   13.11 +  static void wait_for_keypress_at_exit(void);
   13.12 +
   13.13    // The following two functions are used by fatal error handler to trace
   13.14    // native (C) frames. They are not part of frame.hpp/frame.cpp because
   13.15    // frame.hpp/cpp assume thread is JavaThread, and also because different
    14.1 --- a/src/share/vm/runtime/thread.cpp	Fri Feb 25 12:46:49 2011 -0800
    14.2 +++ b/src/share/vm/runtime/thread.cpp	Mon Feb 28 15:35:45 2011 -0800
    14.3 @@ -3644,6 +3644,7 @@
    14.4    if (ShowMessageBoxOnError && is_error_reported()) {
    14.5      os::infinite_sleep();
    14.6    }
    14.7 +  os::wait_for_keypress_at_exit();
    14.8  
    14.9    if (JDK_Version::is_jdk12x_version()) {
   14.10      // We are the last thread running, so check if finalizers should be run.
    15.1 --- a/src/share/vm/utilities/vmError.cpp	Fri Feb 25 12:46:49 2011 -0800
    15.2 +++ b/src/share/vm/utilities/vmError.cpp	Mon Feb 28 15:35:45 2011 -0800
    15.3 @@ -802,7 +802,7 @@
    15.4      first_error_tid = mytid;
    15.5      set_error_reported();
    15.6  
    15.7 -    if (ShowMessageBoxOnError) {
    15.8 +    if (ShowMessageBoxOnError || PauseAtExit) {
    15.9        show_message_box(buffer, sizeof(buffer));
   15.10  
   15.11        // User has asked JVM to abort. Reset ShowMessageBoxOnError so the

mercurial