8023014: CodeSweeperSweepNoFlushTest.java fails with HS crash

Thu, 10 Oct 2013 15:44:12 +0200

author
anoll
date
Thu, 10 Oct 2013 15:44:12 +0200
changeset 5919
469216acdb28
parent 5915
8b80b262e501
child 5920
ed2c74787eb5

8023014: CodeSweeperSweepNoFlushTest.java fails with HS crash
Summary: Ensure ensure correct initialization of compiler runtime
Reviewed-by: kvn, twisti

src/share/vm/c1/c1_Compiler.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_Compiler.hpp file | annotate | diff | comparison | revisions
src/share/vm/code/codeBlob.cpp file | annotate | diff | comparison | revisions
src/share/vm/code/codeBlob.hpp file | annotate | diff | comparison | revisions
src/share/vm/compiler/abstractCompiler.cpp file | annotate | diff | comparison | revisions
src/share/vm/compiler/abstractCompiler.hpp file | annotate | diff | comparison | revisions
src/share/vm/compiler/compileBroker.cpp file | annotate | diff | comparison | revisions
src/share/vm/compiler/compileBroker.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/c2compiler.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/c2compiler.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/runtime.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/runtime.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/vmStructs.cpp file | annotate | diff | comparison | revisions
src/share/vm/shark/sharkCompiler.cpp file | annotate | diff | comparison | revisions
src/share/vm/shark/sharkCompiler.hpp file | annotate | diff | comparison | revisions
test/compiler/startup/SmallCodeCacheStartup.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/c1/c1_Compiler.cpp	Fri Oct 11 10:14:02 2013 -0700
     1.2 +++ b/src/share/vm/c1/c1_Compiler.cpp	Thu Oct 10 15:44:12 2013 +0200
     1.3 @@ -42,26 +42,16 @@
     1.4  #include "runtime/interfaceSupport.hpp"
     1.5  #include "runtime/sharedRuntime.hpp"
     1.6  
     1.7 -volatile int Compiler::_runtimes = uninitialized;
     1.8  
     1.9 -Compiler::Compiler() {
    1.10 -}
    1.11 +Compiler::Compiler () {}
    1.12  
    1.13 -
    1.14 -Compiler::~Compiler() {
    1.15 -  Unimplemented();
    1.16 -}
    1.17 -
    1.18 -
    1.19 -void Compiler::initialize_all() {
    1.20 +void Compiler::init_c1_runtime() {
    1.21    BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
    1.22    Arena* arena = new (mtCompiler) Arena();
    1.23    Runtime1::initialize(buffer_blob);
    1.24    FrameMap::initialize();
    1.25    // initialize data structures
    1.26    ValueType::initialize(arena);
    1.27 -  // Instruction::initialize();
    1.28 -  // BlockBegin::initialize();
    1.29    GraphBuilder::initialize();
    1.30    // note: to use more than one instance of LinearScan at a time this function call has to
    1.31    //       be moved somewhere outside of this constructor:
    1.32 @@ -70,32 +60,33 @@
    1.33  
    1.34  
    1.35  void Compiler::initialize() {
    1.36 -  if (_runtimes != initialized) {
    1.37 -    initialize_runtimes( initialize_all, &_runtimes);
    1.38 +  // Buffer blob must be allocated per C1 compiler thread at startup
    1.39 +  BufferBlob* buffer_blob = init_buffer_blob();
    1.40 +
    1.41 +  if (should_perform_init()) {
    1.42 +    if (buffer_blob == NULL) {
    1.43 +      // When we come here we are in state 'initializing'; entire C1 compilation
    1.44 +      // can be shut down.
    1.45 +      set_state(failed);
    1.46 +    } else {
    1.47 +      init_c1_runtime();
    1.48 +      set_state(initialized);
    1.49 +    }
    1.50    }
    1.51 -  mark_initialized();
    1.52  }
    1.53  
    1.54 -
    1.55 -BufferBlob* Compiler::get_buffer_blob(ciEnv* env) {
    1.56 +BufferBlob* Compiler::init_buffer_blob() {
    1.57    // Allocate buffer blob once at startup since allocation for each
    1.58    // compilation seems to be too expensive (at least on Intel win32).
    1.59 -  BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
    1.60 -  if (buffer_blob != NULL) {
    1.61 -    return buffer_blob;
    1.62 -  }
    1.63 +  assert (CompilerThread::current()->get_buffer_blob() == NULL, "Should initialize only once");
    1.64  
    1.65    // setup CodeBuffer.  Preallocate a BufferBlob of size
    1.66    // NMethodSizeLimit plus some extra space for constants.
    1.67    int code_buffer_size = Compilation::desired_max_code_buffer_size() +
    1.68      Compilation::desired_max_constant_size();
    1.69  
    1.70 -  buffer_blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
    1.71 -                                   code_buffer_size);
    1.72 -  if (buffer_blob == NULL) {
    1.73 -    CompileBroker::handle_full_code_cache();
    1.74 -    env->record_failure("CodeCache is full");
    1.75 -  } else {
    1.76 +  BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size);
    1.77 +  if (buffer_blob != NULL) {
    1.78      CompilerThread::current()->set_buffer_blob(buffer_blob);
    1.79    }
    1.80  
    1.81 @@ -104,15 +95,8 @@
    1.82  
    1.83  
    1.84  void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) {
    1.85 -  BufferBlob* buffer_blob = Compiler::get_buffer_blob(env);
    1.86 -  if (buffer_blob == NULL) {
    1.87 -    return;
    1.88 -  }
    1.89 -
    1.90 -  if (!is_initialized()) {
    1.91 -    initialize();
    1.92 -  }
    1.93 -
    1.94 +  BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
    1.95 +  assert(buffer_blob != NULL, "Must exist");
    1.96    // invoke compilation
    1.97    {
    1.98      // We are nested here because we need for the destructor
     2.1 --- a/src/share/vm/c1/c1_Compiler.hpp	Fri Oct 11 10:14:02 2013 -0700
     2.2 +++ b/src/share/vm/c1/c1_Compiler.hpp	Thu Oct 10 15:44:12 2013 +0200
     2.3 @@ -30,11 +30,9 @@
     2.4  // There is one instance of the Compiler per CompilerThread.
     2.5  
     2.6  class Compiler: public AbstractCompiler {
     2.7 -
     2.8   private:
     2.9 -
    2.10 - // Tracks whether runtime has been initialized
    2.11 - static volatile int _runtimes;
    2.12 +  static void init_c1_runtime();
    2.13 +  BufferBlob* init_buffer_blob();
    2.14  
    2.15   public:
    2.16    // Creation
    2.17 @@ -46,19 +44,12 @@
    2.18  
    2.19    virtual bool is_c1()                           { return true; };
    2.20  
    2.21 -  BufferBlob* get_buffer_blob(ciEnv* env);
    2.22 -
    2.23    // Missing feature tests
    2.24    virtual bool supports_native()                 { return true; }
    2.25    virtual bool supports_osr   ()                 { return true; }
    2.26  
    2.27 -  // Customization
    2.28 -  virtual bool needs_adapters         ()         { return false; }
    2.29 -  virtual bool needs_stubs            ()         { return false; }
    2.30 -
    2.31    // Initialization
    2.32    virtual void initialize();
    2.33 -  static  void initialize_all();
    2.34  
    2.35    // Compilation entry point for methods
    2.36    virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
     3.1 --- a/src/share/vm/code/codeBlob.cpp	Fri Oct 11 10:14:02 2013 -0700
     3.2 +++ b/src/share/vm/code/codeBlob.cpp	Thu Oct 10 15:44:12 2013 +0200
     3.3 @@ -245,8 +245,8 @@
     3.4  }
     3.5  
     3.6  
     3.7 -void* BufferBlob::operator new(size_t s, unsigned size) throw() {
     3.8 -  void* p = CodeCache::allocate(size);
     3.9 +void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() {
    3.10 +  void* p = CodeCache::allocate(size, is_critical);
    3.11    return p;
    3.12  }
    3.13  
    3.14 @@ -277,7 +277,10 @@
    3.15    unsigned int size = allocation_size(cb, sizeof(AdapterBlob));
    3.16    {
    3.17      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    3.18 -    blob = new (size) AdapterBlob(size, cb);
    3.19 +    // The parameter 'true' indicates a critical memory allocation.
    3.20 +    // This means that CodeCacheMinimumFreeSpace is used, if necessary
    3.21 +    const bool is_critical = true;
    3.22 +    blob = new (size, is_critical) AdapterBlob(size, cb);
    3.23    }
    3.24    // Track memory usage statistic after releasing CodeCache_lock
    3.25    MemoryService::track_code_cache_memory_usage();
    3.26 @@ -299,7 +302,10 @@
    3.27    size += round_to(buffer_size, oopSize);
    3.28    {
    3.29      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    3.30 -    blob = new (size) MethodHandlesAdapterBlob(size);
    3.31 +    // The parameter 'true' indicates a critical memory allocation.
    3.32 +    // This means that CodeCacheMinimumFreeSpace is used, if necessary
    3.33 +    const bool is_critical = true;
    3.34 +    blob = new (size, is_critical) MethodHandlesAdapterBlob(size);
    3.35    }
    3.36    // Track memory usage statistic after releasing CodeCache_lock
    3.37    MemoryService::track_code_cache_memory_usage();
     4.1 --- a/src/share/vm/code/codeBlob.hpp	Fri Oct 11 10:14:02 2013 -0700
     4.2 +++ b/src/share/vm/code/codeBlob.hpp	Thu Oct 10 15:44:12 2013 +0200
     4.3 @@ -209,7 +209,7 @@
     4.4    BufferBlob(const char* name, int size);
     4.5    BufferBlob(const char* name, int size, CodeBuffer* cb);
     4.6  
     4.7 -  void* operator new(size_t s, unsigned size) throw();
     4.8 +  void* operator new(size_t s, unsigned size, bool is_critical = false) throw();
     4.9  
    4.10   public:
    4.11    // Creation
    4.12 @@ -253,7 +253,6 @@
    4.13  class MethodHandlesAdapterBlob: public BufferBlob {
    4.14  private:
    4.15    MethodHandlesAdapterBlob(int size)                 : BufferBlob("MethodHandles adapters", size) {}
    4.16 -  MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {}
    4.17  
    4.18  public:
    4.19    // Creation
     5.1 --- a/src/share/vm/compiler/abstractCompiler.cpp	Fri Oct 11 10:14:02 2013 -0700
     5.2 +++ b/src/share/vm/compiler/abstractCompiler.cpp	Thu Oct 10 15:44:12 2013 +0200
     5.3 @@ -24,41 +24,42 @@
     5.4  
     5.5  #include "precompiled.hpp"
     5.6  #include "compiler/abstractCompiler.hpp"
     5.7 +#include "compiler/compileBroker.hpp"
     5.8  #include "runtime/mutexLocker.hpp"
     5.9 -void AbstractCompiler::initialize_runtimes(initializer f, volatile int* state) {
    5.10 -  if (*state != initialized) {
    5.11  
    5.12 -    // We are thread in native here...
    5.13 -    CompilerThread* thread = CompilerThread::current();
    5.14 -    bool do_initialization = false;
    5.15 -    {
    5.16 -      ThreadInVMfromNative tv(thread);
    5.17 -      ResetNoHandleMark rnhm;
    5.18 -      MutexLocker only_one(CompileThread_lock, thread);
    5.19 -      if ( *state == uninitialized) {
    5.20 -        do_initialization = true;
    5.21 -        *state = initializing;
    5.22 -      } else {
    5.23 -        while (*state == initializing ) {
    5.24 -          CompileThread_lock->wait();
    5.25 -        }
    5.26 +bool AbstractCompiler::should_perform_init() {
    5.27 +  if (_compiler_state != initialized) {
    5.28 +    MutexLocker only_one(CompileThread_lock);
    5.29 +
    5.30 +    if (_compiler_state == uninitialized) {
    5.31 +      _compiler_state = initializing;
    5.32 +      return true;
    5.33 +    } else {
    5.34 +      while (_compiler_state == initializing) {
    5.35 +        CompileThread_lock->wait();
    5.36        }
    5.37      }
    5.38 -    if (do_initialization) {
    5.39 -      // We can not hold any locks here since JVMTI events may call agents
    5.40 +  }
    5.41 +  return false;
    5.42 +}
    5.43  
    5.44 -      // Compiler(s) run as native
    5.45 +bool AbstractCompiler::should_perform_shutdown() {
    5.46 +  // Since this method can be called by multiple threads, the lock ensures atomicity of
    5.47 +  // decrementing '_num_compiler_threads' and the following operations.
    5.48 +  MutexLocker only_one(CompileThread_lock);
    5.49 +  _num_compiler_threads--;
    5.50 +  assert (CompileBroker::is_compilation_disabled_forever(), "Must be set, otherwise thread waits forever");
    5.51  
    5.52 -      (*f)();
    5.53 +  // Only the last thread will perform shutdown operations
    5.54 +  if (_num_compiler_threads == 0) {
    5.55 +    return true;
    5.56 +  }
    5.57 +  return false;
    5.58 +}
    5.59  
    5.60 -      // To in_vm so we can use the lock
    5.61 -
    5.62 -      ThreadInVMfromNative tv(thread);
    5.63 -      ResetNoHandleMark rnhm;
    5.64 -      MutexLocker only_one(CompileThread_lock, thread);
    5.65 -      assert(*state == initializing, "wrong state");
    5.66 -      *state = initialized;
    5.67 -      CompileThread_lock->notify_all();
    5.68 -    }
    5.69 -  }
    5.70 +void AbstractCompiler::set_state(int state) {
    5.71 +  // Ensure that ste is only set by one thread at a time
    5.72 +  MutexLocker only_one(CompileThread_lock);
    5.73 +  _compiler_state =  state;
    5.74 +  CompileThread_lock->notify_all();
    5.75  }
     6.1 --- a/src/share/vm/compiler/abstractCompiler.hpp	Fri Oct 11 10:14:02 2013 -0700
     6.2 +++ b/src/share/vm/compiler/abstractCompiler.hpp	Thu Oct 10 15:44:12 2013 +0200
     6.3 @@ -27,22 +27,25 @@
     6.4  
     6.5  #include "ci/compilerInterface.hpp"
     6.6  
     6.7 -typedef void (*initializer)(void);
     6.8 -
     6.9  class AbstractCompiler : public CHeapObj<mtCompiler> {
    6.10   private:
    6.11 -  bool _is_initialized; // Mark whether compiler object is initialized
    6.12 +  volatile int _num_compiler_threads;
    6.13  
    6.14   protected:
    6.15 +  volatile int _compiler_state;
    6.16    // Used for tracking global state of compiler runtime initialization
    6.17 -  enum { uninitialized, initializing, initialized };
    6.18 +  enum { uninitialized, initializing, initialized, failed, shut_down };
    6.19  
    6.20 -  // This method will call the initialization method "f" once (per compiler class/subclass)
    6.21 -  // and do so without holding any locks
    6.22 -  void initialize_runtimes(initializer f, volatile int* state);
    6.23 +  // This method returns true for the first compiler thread that reaches that methods.
    6.24 +  // This thread will initialize the compiler runtime.
    6.25 +  bool should_perform_init();
    6.26  
    6.27   public:
    6.28 -  AbstractCompiler() : _is_initialized(false)    {}
    6.29 +  AbstractCompiler() : _compiler_state(uninitialized), _num_compiler_threads(0) {}
    6.30 +
    6.31 +  // This function determines the compiler thread that will perform the
    6.32 +  // shutdown of the corresponding compiler runtime.
    6.33 +  bool should_perform_shutdown();
    6.34  
    6.35    // Name of this compiler
    6.36    virtual const char* name() = 0;
    6.37 @@ -74,17 +77,18 @@
    6.38  #endif // TIERED
    6.39  
    6.40    // Customization
    6.41 -  virtual bool needs_stubs            ()         = 0;
    6.42 +  virtual void initialize () = 0;
    6.43  
    6.44 -  void mark_initialized()                        { _is_initialized = true; }
    6.45 -  bool is_initialized()                          { return _is_initialized; }
    6.46 +  void set_num_compiler_threads(int num) { _num_compiler_threads = num;  }
    6.47 +  int num_compiler_threads()             { return _num_compiler_threads; }
    6.48  
    6.49 -  virtual void initialize()                      = 0;
    6.50 -
    6.51 +  // Get/set state of compiler objects
    6.52 +  bool is_initialized()           { return _compiler_state == initialized; }
    6.53 +  bool is_failed     ()           { return _compiler_state == failed;}
    6.54 +  void set_state     (int state);
    6.55 +  void set_shut_down ()           { set_state(shut_down); }
    6.56    // Compilation entry point for methods
    6.57 -  virtual void compile_method(ciEnv* env,
    6.58 -                              ciMethod* target,
    6.59 -                              int entry_bci) {
    6.60 +  virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
    6.61      ShouldNotReachHere();
    6.62    }
    6.63  
     7.1 --- a/src/share/vm/compiler/compileBroker.cpp	Fri Oct 11 10:14:02 2013 -0700
     7.2 +++ b/src/share/vm/compiler/compileBroker.cpp	Thu Oct 10 15:44:12 2013 +0200
     7.3 @@ -186,7 +186,7 @@
     7.4  CompileQueue* CompileBroker::_c1_method_queue    = NULL;
     7.5  CompileTask*  CompileBroker::_task_free_list     = NULL;
     7.6  
     7.7 -GrowableArray<CompilerThread*>* CompileBroker::_method_threads = NULL;
     7.8 +GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL;
     7.9  
    7.10  
    7.11  class CompilationLog : public StringEventLog {
    7.12 @@ -587,9 +587,6 @@
    7.13  
    7.14  
    7.15  
    7.16 -// ------------------------------------------------------------------
    7.17 -// CompileQueue::add
    7.18 -//
    7.19  // Add a CompileTask to a CompileQueue
    7.20  void CompileQueue::add(CompileTask* task) {
    7.21    assert(lock()->owned_by_self(), "must own lock");
    7.22 @@ -626,6 +623,16 @@
    7.23    lock()->notify_all();
    7.24  }
    7.25  
    7.26 +void CompileQueue::delete_all() {
    7.27 +  assert(lock()->owned_by_self(), "must own lock");
    7.28 +  if (_first != NULL) {
    7.29 +    for (CompileTask* task = _first; task != NULL; task = task->next()) {
    7.30 +      delete task;
    7.31 +    }
    7.32 +    _first = NULL;
    7.33 +  }
    7.34 +}
    7.35 +
    7.36  // ------------------------------------------------------------------
    7.37  // CompileQueue::get
    7.38  //
    7.39 @@ -640,6 +647,11 @@
    7.40    // case we perform code cache sweeps to free memory such that we can re-enable
    7.41    // compilation.
    7.42    while (_first == NULL) {
    7.43 +    // Exit loop if compilation is disabled forever
    7.44 +    if (CompileBroker::is_compilation_disabled_forever()) {
    7.45 +      return NULL;
    7.46 +    }
    7.47 +
    7.48      if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
    7.49        // Wait a certain amount of time to possibly do another sweep.
    7.50        // We must wait until stack scanning has happened so that we can
    7.51 @@ -664,9 +676,17 @@
    7.52        // remains unchanged. This behavior is desired, since we want to keep
    7.53        // the stable state, i.e., we do not want to evict methods from the
    7.54        // code cache if it is unnecessary.
    7.55 -      lock()->wait();
    7.56 +      // We need a timed wait here, since compiler threads can exit if compilation
    7.57 +      // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
    7.58 +      // is not critical and we do not want idle compiler threads to wake up too often.
    7.59 +      lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
    7.60      }
    7.61    }
    7.62 +
    7.63 +  if (CompileBroker::is_compilation_disabled_forever()) {
    7.64 +    return NULL;
    7.65 +  }
    7.66 +
    7.67    CompileTask* task = CompilationPolicy::policy()->select_task(this);
    7.68    remove(task);
    7.69    return task;
    7.70 @@ -891,10 +911,8 @@
    7.71  }
    7.72  
    7.73  
    7.74 -
    7.75 -// ------------------------------------------------------------------
    7.76 -// CompileBroker::make_compiler_thread
    7.77 -CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) {
    7.78 +CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
    7.79 +                                                    AbstractCompiler* comp, TRAPS) {
    7.80    CompilerThread* compiler_thread = NULL;
    7.81  
    7.82    Klass* k =
    7.83 @@ -961,6 +979,7 @@
    7.84      java_lang_Thread::set_daemon(thread_oop());
    7.85  
    7.86      compiler_thread->set_threadObj(thread_oop());
    7.87 +    compiler_thread->set_compiler(comp);
    7.88      Threads::add(compiler_thread);
    7.89      Thread::start(compiler_thread);
    7.90    }
    7.91 @@ -972,25 +991,24 @@
    7.92  }
    7.93  
    7.94  
    7.95 -// ------------------------------------------------------------------
    7.96 -// CompileBroker::init_compiler_threads
    7.97 -//
    7.98 -// Initialize the compilation queue
    7.99  void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
   7.100    EXCEPTION_MARK;
   7.101  #if !defined(ZERO) && !defined(SHARK)
   7.102    assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
   7.103  #endif // !ZERO && !SHARK
   7.104 +  // Initialize the compilation queue
   7.105    if (c2_compiler_count > 0) {
   7.106      _c2_method_queue  = new CompileQueue("C2MethodQueue",  MethodCompileQueue_lock);
   7.107 +    _compilers[1]->set_num_compiler_threads(c2_compiler_count);
   7.108    }
   7.109    if (c1_compiler_count > 0) {
   7.110      _c1_method_queue  = new CompileQueue("C1MethodQueue",  MethodCompileQueue_lock);
   7.111 +    _compilers[0]->set_num_compiler_threads(c1_compiler_count);
   7.112    }
   7.113  
   7.114    int compiler_count = c1_compiler_count + c2_compiler_count;
   7.115  
   7.116 -  _method_threads =
   7.117 +  _compiler_threads =
   7.118      new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true);
   7.119  
   7.120    char name_buffer[256];
   7.121 @@ -998,21 +1016,22 @@
   7.122      // Create a name for our thread.
   7.123      sprintf(name_buffer, "C2 CompilerThread%d", i);
   7.124      CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
   7.125 -    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, CHECK);
   7.126 -    _method_threads->append(new_thread);
   7.127 +    // Shark and C2
   7.128 +    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, _compilers[1], CHECK);
   7.129 +    _compiler_threads->append(new_thread);
   7.130    }
   7.131  
   7.132    for (int i = c2_compiler_count; i < compiler_count; i++) {
   7.133      // Create a name for our thread.
   7.134      sprintf(name_buffer, "C1 CompilerThread%d", i);
   7.135      CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
   7.136 -    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, CHECK);
   7.137 -    _method_threads->append(new_thread);
   7.138 +    // C1
   7.139 +    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, _compilers[0], CHECK);
   7.140 +    _compiler_threads->append(new_thread);
   7.141    }
   7.142  
   7.143    if (UsePerfData) {
   7.144 -    PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes,
   7.145 -                                     compiler_count, CHECK);
   7.146 +    PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK);
   7.147    }
   7.148  }
   7.149  
   7.150 @@ -1029,27 +1048,6 @@
   7.151  }
   7.152  
   7.153  // ------------------------------------------------------------------
   7.154 -// CompileBroker::is_idle
   7.155 -bool CompileBroker::is_idle() {
   7.156 -  if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) {
   7.157 -    return false;
   7.158 -  } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) {
   7.159 -    return false;
   7.160 -  } else {
   7.161 -    int num_threads = _method_threads->length();
   7.162 -    for (int i=0; i<num_threads; i++) {
   7.163 -      if (_method_threads->at(i)->task() != NULL) {
   7.164 -        return false;
   7.165 -      }
   7.166 -    }
   7.167 -
   7.168 -    // No pending or active compilations.
   7.169 -    return true;
   7.170 -  }
   7.171 -}
   7.172 -
   7.173 -
   7.174 -// ------------------------------------------------------------------
   7.175  // CompileBroker::compile_method
   7.176  //
   7.177  // Request compilation of a method.
   7.178 @@ -1551,6 +1549,101 @@
   7.179    free_task(task);
   7.180  }
   7.181  
   7.182 +// Initialize compiler thread(s) + compiler object(s). The postcondition
   7.183 +// of this function is that the compiler runtimes are initialized and that
   7.184 +//compiler threads can start compiling.
   7.185 +bool CompileBroker::init_compiler_runtime() {
   7.186 +  CompilerThread* thread = CompilerThread::current();
   7.187 +  AbstractCompiler* comp = thread->compiler();
   7.188 +  // Final sanity check - the compiler object must exist
   7.189 +  guarantee(comp != NULL, "Compiler object must exist");
   7.190 +
   7.191 +  int system_dictionary_modification_counter;
   7.192 +  {
   7.193 +    MutexLocker locker(Compile_lock, thread);
   7.194 +    system_dictionary_modification_counter = SystemDictionary::number_of_modifications();
   7.195 +  }
   7.196 +
   7.197 +  {
   7.198 +    // Must switch to native to allocate ci_env
   7.199 +    ThreadToNativeFromVM ttn(thread);
   7.200 +    ciEnv ci_env(NULL, system_dictionary_modification_counter);
   7.201 +    // Cache Jvmti state
   7.202 +    ci_env.cache_jvmti_state();
   7.203 +    // Cache DTrace flags
   7.204 +    ci_env.cache_dtrace_flags();
   7.205 +
   7.206 +    // Switch back to VM state to do compiler initialization
   7.207 +    ThreadInVMfromNative tv(thread);
   7.208 +    ResetNoHandleMark rnhm;
   7.209 +
   7.210 +
   7.211 +    if (!comp->is_shark()) {
   7.212 +      // Perform per-thread and global initializations
   7.213 +      comp->initialize();
   7.214 +    }
   7.215 +  }
   7.216 +
   7.217 +  if (comp->is_failed()) {
   7.218 +    disable_compilation_forever();
   7.219 +    // If compiler initialization failed, no compiler thread that is specific to a
   7.220 +    // particular compiler runtime will ever start to compile methods.
   7.221 +
   7.222 +    shutdown_compiler_runtime(comp, thread);
   7.223 +    return false;
   7.224 +  }
   7.225 +
   7.226 +  // C1 specific check
   7.227 +  if (comp->is_c1() && (thread->get_buffer_blob() == NULL)) {
   7.228 +    warning("Initialization of %s thread failed (no space to run compilers)", thread->name());
   7.229 +    return false;
   7.230 +  }
   7.231 +
   7.232 +  return true;
   7.233 +}
   7.234 +
   7.235 +// If C1 and/or C2 initialization failed, we shut down all compilation.
   7.236 +// We do this to keep things simple. This can be changed if it ever turns out to be
   7.237 +// a problem.
   7.238 +void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) {
   7.239 +  // Free buffer blob, if allocated
   7.240 +  if (thread->get_buffer_blob() != NULL) {
   7.241 +    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   7.242 +    CodeCache::free(thread->get_buffer_blob());
   7.243 +  }
   7.244 +
   7.245 +  if (comp->should_perform_shutdown()) {
   7.246 +    // There are two reasons for shutting down the compiler
   7.247 +    // 1) compiler runtime initialization failed
   7.248 +    // 2) The code cache is full and the following flag is set: -XX:-UseCodeCacheFlushing
   7.249 +    warning("Shutting down compiler %s (no space to run compilers)", comp->name());
   7.250 +
   7.251 +    // Only one thread per compiler runtime object enters here
   7.252 +    // Set state to shut down
   7.253 +    comp->set_shut_down();
   7.254 +
   7.255 +    MutexLocker mu(MethodCompileQueue_lock, thread);
   7.256 +    CompileQueue* queue;
   7.257 +    if (_c1_method_queue != NULL) {
   7.258 +      _c1_method_queue->delete_all();
   7.259 +      queue = _c1_method_queue;
   7.260 +      _c1_method_queue = NULL;
   7.261 +      delete _c1_method_queue;
   7.262 +    }
   7.263 +
   7.264 +    if (_c2_method_queue != NULL) {
   7.265 +      _c2_method_queue->delete_all();
   7.266 +      queue = _c2_method_queue;
   7.267 +      _c2_method_queue = NULL;
   7.268 +      delete _c2_method_queue;
   7.269 +    }
   7.270 +
   7.271 +    // We could delete compiler runtimes also. However, there are references to
   7.272 +    // the compiler runtime(s) (e.g.,  nmethod::is_compiled_by_c1()) which then
   7.273 +    // fail. This can be done later if necessary.
   7.274 +  }
   7.275 +}
   7.276 +
   7.277  // ------------------------------------------------------------------
   7.278  // CompileBroker::compiler_thread_loop
   7.279  //
   7.280 @@ -1558,7 +1651,6 @@
   7.281  void CompileBroker::compiler_thread_loop() {
   7.282    CompilerThread* thread = CompilerThread::current();
   7.283    CompileQueue* queue = thread->queue();
   7.284 -
   7.285    // For the thread that initializes the ciObjectFactory
   7.286    // this resource mark holds all the shared objects
   7.287    ResourceMark rm;
   7.288 @@ -1587,65 +1679,78 @@
   7.289      log->end_elem();
   7.290    }
   7.291  
   7.292 -  while (true) {
   7.293 -    {
   7.294 -      // We need this HandleMark to avoid leaking VM handles.
   7.295 -      HandleMark hm(thread);
   7.296 +  // If compiler thread/runtime initialization fails, exit the compiler thread
   7.297 +  if (!init_compiler_runtime()) {
   7.298 +    return;
   7.299 +  }
   7.300  
   7.301 -      if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
   7.302 -        // the code cache is really full
   7.303 -        handle_full_code_cache();
   7.304 -      }
   7.305 +  // Poll for new compilation tasks as long as the JVM runs. Compilation
   7.306 +  // should only be disabled if something went wrong while initializing the
   7.307 +  // compiler runtimes. This, in turn, should not happen. The only known case
   7.308 +  // when compiler runtime initialization fails is if there is not enough free
   7.309 +  // space in the code cache to generate the necessary stubs, etc.
   7.310 +  while (!is_compilation_disabled_forever()) {
   7.311 +    // We need this HandleMark to avoid leaking VM handles.
   7.312 +    HandleMark hm(thread);
   7.313  
   7.314 -      CompileTask* task = queue->get();
   7.315 +    if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) {
   7.316 +      // the code cache is really full
   7.317 +      handle_full_code_cache();
   7.318 +    }
   7.319  
   7.320 -      // Give compiler threads an extra quanta.  They tend to be bursty and
   7.321 -      // this helps the compiler to finish up the job.
   7.322 -      if( CompilerThreadHintNoPreempt )
   7.323 -        os::hint_no_preempt();
   7.324 +    CompileTask* task = queue->get();
   7.325 +    if (task == NULL) {
   7.326 +      continue;
   7.327 +    }
   7.328  
   7.329 -      // trace per thread time and compile statistics
   7.330 -      CompilerCounters* counters = ((CompilerThread*)thread)->counters();
   7.331 -      PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
   7.332 +    // Give compiler threads an extra quanta.  They tend to be bursty and
   7.333 +    // this helps the compiler to finish up the job.
   7.334 +    if( CompilerThreadHintNoPreempt )
   7.335 +      os::hint_no_preempt();
   7.336  
   7.337 -      // Assign the task to the current thread.  Mark this compilation
   7.338 -      // thread as active for the profiler.
   7.339 -      CompileTaskWrapper ctw(task);
   7.340 -      nmethodLocker result_handle;  // (handle for the nmethod produced by this task)
   7.341 -      task->set_code_handle(&result_handle);
   7.342 -      methodHandle method(thread, task->method());
   7.343 +    // trace per thread time and compile statistics
   7.344 +    CompilerCounters* counters = ((CompilerThread*)thread)->counters();
   7.345 +    PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
   7.346  
   7.347 -      // Never compile a method if breakpoints are present in it
   7.348 -      if (method()->number_of_breakpoints() == 0) {
   7.349 -        // Compile the method.
   7.350 -        if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
   7.351 +    // Assign the task to the current thread.  Mark this compilation
   7.352 +    // thread as active for the profiler.
   7.353 +    CompileTaskWrapper ctw(task);
   7.354 +    nmethodLocker result_handle;  // (handle for the nmethod produced by this task)
   7.355 +    task->set_code_handle(&result_handle);
   7.356 +    methodHandle method(thread, task->method());
   7.357 +
   7.358 +    // Never compile a method if breakpoints are present in it
   7.359 +    if (method()->number_of_breakpoints() == 0) {
   7.360 +      // Compile the method.
   7.361 +      if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
   7.362  #ifdef COMPILER1
   7.363 -          // Allow repeating compilations for the purpose of benchmarking
   7.364 -          // compile speed. This is not useful for customers.
   7.365 -          if (CompilationRepeat != 0) {
   7.366 -            int compile_count = CompilationRepeat;
   7.367 -            while (compile_count > 0) {
   7.368 -              invoke_compiler_on_method(task);
   7.369 -              nmethod* nm = method->code();
   7.370 -              if (nm != NULL) {
   7.371 -                nm->make_zombie();
   7.372 -                method->clear_code();
   7.373 -              }
   7.374 -              compile_count--;
   7.375 +        // Allow repeating compilations for the purpose of benchmarking
   7.376 +        // compile speed. This is not useful for customers.
   7.377 +        if (CompilationRepeat != 0) {
   7.378 +          int compile_count = CompilationRepeat;
   7.379 +          while (compile_count > 0) {
   7.380 +            invoke_compiler_on_method(task);
   7.381 +            nmethod* nm = method->code();
   7.382 +            if (nm != NULL) {
   7.383 +              nm->make_zombie();
   7.384 +              method->clear_code();
   7.385              }
   7.386 +            compile_count--;
   7.387            }
   7.388 +        }
   7.389  #endif /* COMPILER1 */
   7.390 -          invoke_compiler_on_method(task);
   7.391 -        } else {
   7.392 -          // After compilation is disabled, remove remaining methods from queue
   7.393 -          method->clear_queued_for_compilation();
   7.394 -        }
   7.395 +        invoke_compiler_on_method(task);
   7.396 +      } else {
   7.397 +        // After compilation is disabled, remove remaining methods from queue
   7.398 +        method->clear_queued_for_compilation();
   7.399        }
   7.400      }
   7.401    }
   7.402 +
   7.403 +  // Shut down compiler runtime
   7.404 +  shutdown_compiler_runtime(thread->compiler(), thread);
   7.405  }
   7.406  
   7.407 -
   7.408  // ------------------------------------------------------------------
   7.409  // CompileBroker::init_compiler_thread_log
   7.410  //
   7.411 @@ -1960,8 +2065,7 @@
   7.412          NMethodSweeper::possibly_sweep();
   7.413        }
   7.414      } else {
   7.415 -      UseCompiler               = false;
   7.416 -      AlwaysCompileLoopMethods  = false;
   7.417 +      disable_compilation_forever();
   7.418      }
   7.419    }
   7.420    codecache_print(/* detailed= */ true);
     8.1 --- a/src/share/vm/compiler/compileBroker.hpp	Fri Oct 11 10:14:02 2013 -0700
     8.2 +++ b/src/share/vm/compiler/compileBroker.hpp	Thu Oct 10 15:44:12 2013 +0200
     8.3 @@ -213,8 +213,12 @@
     8.4  
     8.5    // Redefine Classes support
     8.6    void mark_on_stack();
     8.7 +  void delete_all();
     8.8 +  void         print();
     8.9  
    8.10 -  void         print();
    8.11 +  ~CompileQueue() {
    8.12 +    assert (is_empty(), " Compile Queue must be empty");
    8.13 +  }
    8.14  };
    8.15  
    8.16  // CompileTaskWrapper
    8.17 @@ -266,7 +270,7 @@
    8.18    static CompileQueue* _c1_method_queue;
    8.19    static CompileTask* _task_free_list;
    8.20  
    8.21 -  static GrowableArray<CompilerThread*>* _method_threads;
    8.22 +  static GrowableArray<CompilerThread*>* _compiler_threads;
    8.23  
    8.24    // performance counters
    8.25    static PerfCounter* _perf_total_compilation;
    8.26 @@ -311,7 +315,7 @@
    8.27    static int _sum_nmethod_code_size;
    8.28    static long _peak_compilation_time;
    8.29  
    8.30 -  static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS);
    8.31 +  static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS);
    8.32    static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
    8.33    static bool compilation_is_complete  (methodHandle method, int osr_bci, int comp_level);
    8.34    static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
    8.35 @@ -351,6 +355,9 @@
    8.36      if (is_c1_compile(comp_level)) return _c1_method_queue;
    8.37      return NULL;
    8.38    }
    8.39 +  static bool init_compiler_runtime();
    8.40 +  static void shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread);
    8.41 +
    8.42   public:
    8.43    enum {
    8.44      // The entry bci used for non-OSR compilations.
    8.45 @@ -378,9 +385,7 @@
    8.46                                   const char* comment, Thread* thread);
    8.47  
    8.48    static void compiler_thread_loop();
    8.49 -
    8.50    static uint get_compilation_id() { return _compilation_id; }
    8.51 -  static bool is_idle();
    8.52  
    8.53    // Set _should_block.
    8.54    // Call this from the VM, with Threads_lock held and a safepoint requested.
    8.55 @@ -391,8 +396,9 @@
    8.56  
    8.57    enum {
    8.58      // Flags for toggling compiler activity
    8.59 -    stop_compilation = 0,
    8.60 -    run_compilation  = 1
    8.61 +    stop_compilation    = 0,
    8.62 +    run_compilation     = 1,
    8.63 +    shutdown_compilaton = 2
    8.64    };
    8.65  
    8.66    static bool should_compile_new_jobs() { return UseCompiler && (_should_compile_new_jobs == run_compilation); }
    8.67 @@ -401,6 +407,16 @@
    8.68      jint old = Atomic::cmpxchg(new_state, &_should_compile_new_jobs, 1-new_state);
    8.69      return (old == (1-new_state));
    8.70    }
    8.71 +
    8.72 +  static void disable_compilation_forever() {
    8.73 +    UseCompiler               = false;
    8.74 +    AlwaysCompileLoopMethods  = false;
    8.75 +    Atomic::xchg(shutdown_compilaton, &_should_compile_new_jobs);
    8.76 +  }
    8.77 +
    8.78 +  static bool is_compilation_disabled_forever() {
    8.79 +    return _should_compile_new_jobs == shutdown_compilaton;
    8.80 +  }
    8.81    static void handle_full_code_cache();
    8.82  
    8.83    // Return total compilation ticks
     9.1 --- a/src/share/vm/opto/c2compiler.cpp	Fri Oct 11 10:14:02 2013 -0700
     9.2 +++ b/src/share/vm/opto/c2compiler.cpp	Thu Oct 10 15:44:12 2013 +0200
     9.3 @@ -44,9 +44,6 @@
     9.4  # include "adfiles/ad_ppc.hpp"
     9.5  #endif
     9.6  
     9.7 -
     9.8 -volatile int C2Compiler::_runtimes = uninitialized;
     9.9 -
    9.10  // register information defined by ADLC
    9.11  extern const char register_save_policy[];
    9.12  extern const int  register_save_type[];
    9.13 @@ -57,7 +54,7 @@
    9.14  const char* C2Compiler::retry_no_escape_analysis() {
    9.15    return "retry without escape analysis";
    9.16  }
    9.17 -void C2Compiler::initialize_runtime() {
    9.18 +bool C2Compiler::init_c2_runtime() {
    9.19  
    9.20    // Check assumptions used while running ADLC
    9.21    Compile::adlc_verification();
    9.22 @@ -90,41 +87,31 @@
    9.23  
    9.24    CompilerThread* thread = CompilerThread::current();
    9.25  
    9.26 -  HandleMark  handle_mark(thread);
    9.27 -
    9.28 -  OptoRuntime::generate(thread->env());
    9.29 -
    9.30 +  HandleMark handle_mark(thread);
    9.31 +  return OptoRuntime::generate(thread->env());
    9.32  }
    9.33  
    9.34  
    9.35  void C2Compiler::initialize() {
    9.36 -
    9.37 -  // This method can only be called once per C2Compiler object
    9.38    // The first compiler thread that gets here will initialize the
    9.39 -  // small amount of global state (and runtime stubs) that c2 needs.
    9.40 +  // small amount of global state (and runtime stubs) that C2 needs.
    9.41  
    9.42    // There is a race possible once at startup and then we're fine
    9.43  
    9.44    // Note that this is being called from a compiler thread not the
    9.45    // main startup thread.
    9.46 -
    9.47 -  if (_runtimes != initialized) {
    9.48 -    initialize_runtimes( initialize_runtime, &_runtimes);
    9.49 +  if (should_perform_init()) {
    9.50 +    bool successful = C2Compiler::init_c2_runtime();
    9.51 +    int new_state = (successful) ? initialized : failed;
    9.52 +    set_state(new_state);
    9.53    }
    9.54 -
    9.55 -  // Mark this compiler object as ready to roll
    9.56 -  mark_initialized();
    9.57  }
    9.58  
    9.59 -void C2Compiler::compile_method(ciEnv* env,
    9.60 -                                ciMethod* target,
    9.61 -                                int entry_bci) {
    9.62 -  if (!is_initialized()) {
    9.63 -    initialize();
    9.64 -  }
    9.65 +void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
    9.66 +  assert(is_initialized(), "Compiler thread must be initialized");
    9.67 +
    9.68    bool subsume_loads = SubsumeLoads;
    9.69 -  bool do_escape_analysis = DoEscapeAnalysis &&
    9.70 -    !env->jvmti_can_access_local_variables();
    9.71 +  bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables();
    9.72    bool eliminate_boxing = EliminateAutoBox;
    9.73    while (!env->failing()) {
    9.74      // Attempt to compile while subsuming loads into machine instructions.
    10.1 --- a/src/share/vm/opto/c2compiler.hpp	Fri Oct 11 10:14:02 2013 -0700
    10.2 +++ b/src/share/vm/opto/c2compiler.hpp	Thu Oct 10 15:44:12 2013 +0200
    10.3 @@ -28,24 +28,17 @@
    10.4  #include "compiler/abstractCompiler.hpp"
    10.5  
    10.6  class C2Compiler : public AbstractCompiler {
    10.7 -private:
    10.8 -
    10.9 -  static void initialize_runtime();
   10.10 + private:
   10.11 +  static bool init_c2_runtime();
   10.12  
   10.13  public:
   10.14    // Name
   10.15    const char *name() { return "C2"; }
   10.16  
   10.17 -  static volatile int _runtimes;
   10.18 -
   10.19  #ifdef TIERED
   10.20    virtual bool is_c2() { return true; };
   10.21  #endif // TIERED
   10.22  
   10.23 -  // Customization
   10.24 -  bool needs_adapters         () { return true; }
   10.25 -  bool needs_stubs            () { return true; }
   10.26 -
   10.27    void initialize();
   10.28  
   10.29    // Compilation entry point for methods
    11.1 --- a/src/share/vm/opto/runtime.cpp	Fri Oct 11 10:14:02 2013 -0700
    11.2 +++ b/src/share/vm/opto/runtime.cpp	Thu Oct 10 15:44:12 2013 +0200
    11.3 @@ -138,9 +138,10 @@
    11.4  
    11.5  
    11.6  #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \
    11.7 -  var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc)
    11.8 +  var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc); \
    11.9 +  if (var == NULL) { return false; }
   11.10  
   11.11 -void OptoRuntime::generate(ciEnv* env) {
   11.12 +bool OptoRuntime::generate(ciEnv* env) {
   11.13  
   11.14    generate_exception_blob();
   11.15  
   11.16 @@ -158,7 +159,7 @@
   11.17    gen(env, _multianewarrayN_Java           , multianewarrayN_Type         , multianewarrayN_C               ,    0 , true , false, false);
   11.18    gen(env, _g1_wb_pre_Java                 , g1_wb_pre_Type               , SharedRuntime::g1_wb_pre        ,    0 , false, false, false);
   11.19    gen(env, _g1_wb_post_Java                , g1_wb_post_Type              , SharedRuntime::g1_wb_post       ,    0 , false, false, false);
   11.20 -  gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C      ,    0 , false, false, false);
   11.21 +  gen(env, _complete_monitor_locking_Java  , complete_monitor_enter_Type  , SharedRuntime::complete_monitor_locking_C, 0, false, false, false);
   11.22    gen(env, _rethrow_Java                   , rethrow_Type                 , rethrow_C                       ,    2 , true , false, true );
   11.23  
   11.24    gen(env, _slow_arraycopy_Java            , slow_arraycopy_Type          , SharedRuntime::slow_arraycopy_C ,    0 , false, false, false);
   11.25 @@ -168,7 +169,7 @@
   11.26    gen(env, _zap_dead_Java_locals_Java      , zap_dead_locals_Type         , zap_dead_Java_locals_C          ,    0 , false, true , false );
   11.27    gen(env, _zap_dead_native_locals_Java    , zap_dead_locals_Type         , zap_dead_native_locals_C        ,    0 , false, true , false );
   11.28  # endif
   11.29 -
   11.30 +  return true;
   11.31  }
   11.32  
   11.33  #undef gen
    12.1 --- a/src/share/vm/opto/runtime.hpp	Fri Oct 11 10:14:02 2013 -0700
    12.2 +++ b/src/share/vm/opto/runtime.hpp	Thu Oct 10 15:44:12 2013 +0200
    12.3 @@ -203,8 +203,10 @@
    12.4  
    12.5    static bool is_callee_saved_register(MachRegisterNumbers reg);
    12.6  
    12.7 -  // One time only generate runtime code stubs
    12.8 -  static void generate(ciEnv* env);
    12.9 +  // One time only generate runtime code stubs. Returns true
   12.10 +  // when runtime stubs have been generated successfully and
   12.11 +  // false otherwise.
   12.12 +  static bool generate(ciEnv* env);
   12.13  
   12.14    // Returns the name of a stub
   12.15    static const char* stub_name(address entry);
    13.1 --- a/src/share/vm/runtime/thread.cpp	Fri Oct 11 10:14:02 2013 -0700
    13.2 +++ b/src/share/vm/runtime/thread.cpp	Thu Oct 10 15:44:12 2013 +0200
    13.3 @@ -1454,7 +1454,6 @@
    13.4    _interp_only_mode    = 0;
    13.5    _special_runtime_exit_condition = _no_async_condition;
    13.6    _pending_async_exception = NULL;
    13.7 -  _is_compiling = false;
    13.8    _thread_stat = NULL;
    13.9    _thread_stat = new ThreadStatistics();
   13.10    _blocked_on_compilation = false;
   13.11 @@ -1815,7 +1814,8 @@
   13.12      // Call Thread.exit(). We try 3 times in case we got another Thread.stop during
   13.13      // the execution of the method. If that is not enough, then we don't really care. Thread.stop
   13.14      // is deprecated anyhow.
   13.15 -    { int count = 3;
   13.16 +    if (!is_Compiler_thread()) {
   13.17 +      int count = 3;
   13.18        while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) {
   13.19          EXCEPTION_MARK;
   13.20          JavaValue result(T_VOID);
   13.21 @@ -1828,7 +1828,6 @@
   13.22          CLEAR_PENDING_EXCEPTION;
   13.23        }
   13.24      }
   13.25 -
   13.26      // notify JVMTI
   13.27      if (JvmtiExport::should_post_thread_life()) {
   13.28        JvmtiExport::post_thread_end(this);
   13.29 @@ -3239,6 +3238,7 @@
   13.30    _counters = counters;
   13.31    _buffer_blob = NULL;
   13.32    _scanned_nmethod = NULL;
   13.33 +  _compiler = NULL;
   13.34  
   13.35  #ifndef PRODUCT
   13.36    _ideal_graph_printer = NULL;
   13.37 @@ -3255,6 +3255,7 @@
   13.38    }
   13.39  }
   13.40  
   13.41 +
   13.42  // ======= Threads ========
   13.43  
   13.44  // The Threads class links together all active threads, and provides
   13.45 @@ -3275,8 +3276,6 @@
   13.46  // All JavaThreads
   13.47  #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next())
   13.48  
   13.49 -void os_stream();
   13.50 -
   13.51  // All JavaThreads + all non-JavaThreads (i.e., every thread in the system)
   13.52  void Threads::threads_do(ThreadClosure* tc) {
   13.53    assert_locked_or_safepoint(Threads_lock);
    14.1 --- a/src/share/vm/runtime/thread.hpp	Fri Oct 11 10:14:02 2013 -0700
    14.2 +++ b/src/share/vm/runtime/thread.hpp	Thu Oct 10 15:44:12 2013 +0200
    14.3 @@ -923,9 +923,6 @@
    14.4    volatile address _exception_handler_pc;        // PC for handler of exception
    14.5    volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
    14.6  
    14.7 -  // support for compilation
    14.8 -  bool    _is_compiling;                         // is true if a compilation is active inthis thread (one compilation per thread possible)
    14.9 -
   14.10    // support for JNI critical regions
   14.11    jint    _jni_active_critical;                  // count of entries into JNI critical region
   14.12  
   14.13 @@ -1005,10 +1002,6 @@
   14.14    // Testers
   14.15    virtual bool is_Java_thread() const            { return true;  }
   14.16  
   14.17 -  // compilation
   14.18 -  void set_is_compiling(bool f)                  { _is_compiling = f; }
   14.19 -  bool is_compiling() const                      { return _is_compiling; }
   14.20 -
   14.21    // Thread chain operations
   14.22    JavaThread* next() const                       { return _next; }
   14.23    void set_next(JavaThread* p)                   { _next = p; }
   14.24 @@ -1816,13 +1809,14 @@
   14.25   private:
   14.26    CompilerCounters* _counters;
   14.27  
   14.28 -  ciEnv*        _env;
   14.29 -  CompileLog*   _log;
   14.30 -  CompileTask*  _task;
   14.31 -  CompileQueue* _queue;
   14.32 -  BufferBlob*   _buffer_blob;
   14.33 +  ciEnv*            _env;
   14.34 +  CompileLog*       _log;
   14.35 +  CompileTask*      _task;
   14.36 +  CompileQueue*     _queue;
   14.37 +  BufferBlob*       _buffer_blob;
   14.38  
   14.39 -  nmethod*      _scanned_nmethod;  // nmethod being scanned by the sweeper
   14.40 +  nmethod*          _scanned_nmethod;  // nmethod being scanned by the sweeper
   14.41 +  AbstractCompiler* _compiler;
   14.42  
   14.43   public:
   14.44  
   14.45 @@ -1834,14 +1828,17 @@
   14.46    // Hide this compiler thread from external view.
   14.47    bool is_hidden_from_external_view() const      { return true; }
   14.48  
   14.49 -  CompileQueue* queue()                          { return _queue; }
   14.50 -  CompilerCounters* counters()                   { return _counters; }
   14.51 +  void set_compiler(AbstractCompiler* c)         { _compiler = c; }
   14.52 +  AbstractCompiler* compiler() const             { return _compiler; }
   14.53 +
   14.54 +  CompileQueue* queue()        const             { return _queue; }
   14.55 +  CompilerCounters* counters() const             { return _counters; }
   14.56  
   14.57    // Get/set the thread's compilation environment.
   14.58    ciEnv*        env()                            { return _env; }
   14.59    void          set_env(ciEnv* env)              { _env = env; }
   14.60  
   14.61 -  BufferBlob*   get_buffer_blob()                { return _buffer_blob; }
   14.62 +  BufferBlob*   get_buffer_blob() const          { return _buffer_blob; }
   14.63    void          set_buffer_blob(BufferBlob* b)   { _buffer_blob = b; };
   14.64  
   14.65    // Get/set the thread's logging information
    15.1 --- a/src/share/vm/runtime/vmStructs.cpp	Fri Oct 11 10:14:02 2013 -0700
    15.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Thu Oct 10 15:44:12 2013 +0200
    15.3 @@ -910,7 +910,6 @@
    15.4    volatile_nonstatic_field(JavaThread,         _exception_oop,                                oop)                                   \
    15.5    volatile_nonstatic_field(JavaThread,         _exception_pc,                                 address)                               \
    15.6    volatile_nonstatic_field(JavaThread,         _is_method_handle_return,                      int)                                   \
    15.7 -  nonstatic_field(JavaThread,                  _is_compiling,                                 bool)                                  \
    15.8    nonstatic_field(JavaThread,                  _special_runtime_exit_condition,               JavaThread::AsyncRequests)             \
    15.9    nonstatic_field(JavaThread,                  _saved_exception_pc,                           address)                               \
   15.10     volatile_nonstatic_field(JavaThread,        _thread_state,                                 JavaThreadState)                       \
    16.1 --- a/src/share/vm/shark/sharkCompiler.cpp	Fri Oct 11 10:14:02 2013 -0700
    16.2 +++ b/src/share/vm/shark/sharkCompiler.cpp	Thu Oct 10 15:44:12 2013 +0200
    16.3 @@ -133,11 +133,10 @@
    16.4      exit(1);
    16.5    }
    16.6  
    16.7 -  execution_engine()->addModule(
    16.8 -    _native_context->module());
    16.9 +  execution_engine()->addModule(_native_context->module());
   16.10  
   16.11    // All done
   16.12 -  mark_initialized();
   16.13 +  set_state(initialized);
   16.14  }
   16.15  
   16.16  void SharkCompiler::initialize() {
    17.1 --- a/src/share/vm/shark/sharkCompiler.hpp	Fri Oct 11 10:14:02 2013 -0700
    17.2 +++ b/src/share/vm/shark/sharkCompiler.hpp	Thu Oct 10 15:44:12 2013 +0200
    17.3 @@ -50,10 +50,6 @@
    17.4      return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form());
    17.5    }
    17.6  
    17.7 -  // Customization
    17.8 -  bool needs_adapters()  { return false; }
    17.9 -  bool needs_stubs()     { return false; }
   17.10 -
   17.11    // Initialization
   17.12    void initialize();
   17.13  
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/compiler/startup/SmallCodeCacheStartup.java	Thu Oct 10 15:44:12 2013 +0200
    18.3 @@ -0,0 +1,43 @@
    18.4 +/*
    18.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.7 + *
    18.8 + * This code is free software; you can redistribute it and/or modify it
    18.9 + * under the terms of the GNU General Public License version 2 only, as
   18.10 + * published by the Free Software Foundation.
   18.11 + *
   18.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   18.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   18.15 + * version 2 for more details (a copy is included in the LICENSE file that
   18.16 + * accompanied this code).
   18.17 + *
   18.18 + * You should have received a copy of the GNU General Public License version
   18.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   18.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18.21 + *
   18.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   18.23 + * or visit www.oracle.com if you need additional information or have any
   18.24 + * questions.
   18.25 + */
   18.26 +
   18.27 +/*
   18.28 + * @test
   18.29 + * @bug 8023014
   18.30 + * @summary Test ensures that there is no crash when compiler initialization fails
   18.31 + * @library /testlibrary
   18.32 + *
   18.33 + */
   18.34 +import com.oracle.java.testlibrary.*;
   18.35 +
   18.36 +public class SmallCodeCacheStartup {
   18.37 +  public static void main(String[] args) throws Exception {
   18.38 +    ProcessBuilder pb;
   18.39 +    OutputAnalyzer out;
   18.40 +
   18.41 +    pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=3m", "-XX:CICompilerCount=64", "-version");
   18.42 +    out = new OutputAnalyzer(pb.start());
   18.43 +    out.shouldContain("no space to run compiler");
   18.44 +    out.shouldHaveExitValue(0);
   18.45 +  }
   18.46 +}

mercurial