6958292: C1: Enable parallel compilation
authoriveresov
Fri, 04 Jun 2010 11:18:04 -0700
changeset 5707 6c66849ed24e
parent 5706 0c91076143f9
child 5708 e92b3d8118f1
6958292: C1: Enable parallel compilation Summary: Enable parallel compilation in C1 Reviewed-by: never, kvn
hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp
hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp
hotspot/src/share/vm/c1/c1_Canonicalizer.cpp
hotspot/src/share/vm/c1/c1_Compilation.cpp
hotspot/src/share/vm/c1/c1_Compilation.hpp
hotspot/src/share/vm/c1/c1_Compiler.cpp
hotspot/src/share/vm/c1/c1_Compiler.hpp
hotspot/src/share/vm/c1/c1_FrameMap.cpp
hotspot/src/share/vm/c1/c1_FrameMap.hpp
hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
hotspot/src/share/vm/c1/c1_IR.cpp
hotspot/src/share/vm/c1/c1_IR.hpp
hotspot/src/share/vm/c1/c1_Instruction.cpp
hotspot/src/share/vm/c1/c1_Instruction.hpp
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
hotspot/src/share/vm/c1/c1_LinearScan.cpp
hotspot/src/share/vm/c1/c1_LinearScan.hpp
hotspot/src/share/vm/c1/c1_Optimizer.cpp
hotspot/src/share/vm/c1/c1_Runtime1.cpp
hotspot/src/share/vm/c1/c1_Runtime1.hpp
hotspot/src/share/vm/c1/c1_ValueStack.cpp
hotspot/src/share/vm/c1/c1_ValueStack.hpp
hotspot/src/share/vm/c1/c1_ValueType.cpp
hotspot/src/share/vm/c1/c1_ValueType.hpp
hotspot/src/share/vm/includeDB_compiler1
hotspot/src/share/vm/runtime/mutexLocker.cpp
hotspot/src/share/vm/runtime/mutexLocker.hpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
--- a/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -181,8 +181,8 @@
 }
 
 
-void FrameMap::init () {
-  if (_init_done) return;
+void FrameMap::initialize() {
+  assert(!_init_done, "once");
 
   int i=0;
   // Register usage:
--- a/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -136,8 +136,8 @@
 //               FrameMap
 //--------------------------------------------------------
 
-void FrameMap::init() {
-  if (_init_done) return;
+void FrameMap::initialize() {
+  assert(!_init_done, "once");
 
   assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers");
   map_register(0, rsi);  rsi_opr = LIR_OprFact::single_cpu(0);
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -26,9 +26,11 @@
 #include "incls/_c1_Canonicalizer.cpp.incl"
 
 
-static void do_print_value(Value* vp) {
-  (*vp)->print_line();
-}
+class PrintValueVisitor: public ValueVisitor {
+  void visit(Value* vp) {
+    (*vp)->print_line();
+  }
+};
 
 void Canonicalizer::set_canonical(Value x) {
   assert(x != NULL, "value must exist");
@@ -37,10 +39,11 @@
   // in the instructions).
   if (canonical() != x) {
     if (PrintCanonicalization) {
-      canonical()->input_values_do(do_print_value);
+      PrintValueVisitor do_print_value;
+      canonical()->input_values_do(&do_print_value);
       canonical()->print_line();
       tty->print_cr("canonicalized to:");
-      x->input_values_do(do_print_value);
+      x->input_values_do(&do_print_value);
       x->print_line();
       tty->cr();
     }
@@ -202,7 +205,7 @@
     // limit this optimization to current block
     if (value != NULL && in_current_block(conv)) {
       set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(),
-                                   x->lock_stack(), x->state_before(), x->is_loaded(), x->is_initialized()));
+                                       x->lock_stack(), x->state_before(), x->is_loaded(), x->is_initialized()));
       return;
     }
   }
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -66,9 +66,6 @@
   }
 };
 
-Arena* Compilation::_arena = NULL;
-Compilation* Compilation::_compilation = NULL;
-
 // Implementation of Compilation
 
 
@@ -238,9 +235,23 @@
 }
 
 
+void Compilation::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
+  // Preinitialize the consts section to some large size:
+  int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo));
+  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
+  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
+                                        locs_buffer_size / sizeof(relocInfo));
+  code->initialize_consts_size(Compilation::desired_max_constant_size());
+  // Call stubs + deopt/exception handler
+  code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
+                              LIR_Assembler::exception_handler_size +
+                              LIR_Assembler::deopt_handler_size);
+}
+
+
 int Compilation::emit_code_body() {
   // emit code
-  Runtime1::setup_code_buffer(code(), allocator()->num_calls());
+  setup_code_buffer(code(), allocator()->num_calls());
   code()->initialize_oop_recorder(env()->oop_recorder());
 
   _masm = new C1_MacroAssembler(code());
@@ -422,7 +433,8 @@
 }
 
 
-Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, int osr_bci)
+Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method,
+                         int osr_bci, BufferBlob* buffer_blob)
 : _compiler(compiler)
 , _env(env)
 , _method(method)
@@ -437,8 +449,10 @@
 , _bailout_msg(NULL)
 , _exception_info_list(NULL)
 , _allocator(NULL)
-, _code(Runtime1::get_buffer_blob()->instructions_begin(),
-        Runtime1::get_buffer_blob()->instructions_size())
+, _next_id(0)
+, _next_block_id(0)
+, _code(buffer_blob->instructions_begin(),
+        buffer_blob->instructions_size())
 , _current_instruction(NULL)
 #ifndef PRODUCT
 , _last_instruction_printed(NULL)
@@ -446,17 +460,15 @@
 {
   PhaseTraceTime timeit(_t_compile);
 
-  assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time");
   _arena = Thread::current()->resource_area();
-  _compilation = this;
+  _env->set_compiler_data(this);
   _exception_info_list = new ExceptionInfoList();
   _implicit_exception_table.set_size(0);
   compile_method();
 }
 
 Compilation::~Compilation() {
-  _arena = NULL;
-  _compilation = NULL;
+  _env->set_compiler_data(NULL);
 }
 
 
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -54,14 +54,10 @@
 class Compilation: public StackObj {
   friend class CompilationResourceObj;
  private:
-
-  static Arena* _arena;
-  static Arena* arena() { return _arena; }
-
-  static Compilation* _compilation;
-
- private:
   // compilation specifics
+  Arena* _arena;
+  int _next_id;
+  int _next_block_id;
   AbstractCompiler*  _compiler;
   ciEnv*             _env;
   ciMethod*          _method;
@@ -108,10 +104,14 @@
 
  public:
   // creation
-  Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, int osr_bci);
+  Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method,
+              int osr_bci, BufferBlob* buffer_blob);
   ~Compilation();
 
-  static Compilation* current_compilation()      { return _compilation; }
+
+  static Compilation* current() {
+    return (Compilation*) ciEnv::current()->compiler_data();
+  }
 
   // accessors
   ciEnv* env() const                             { return _env; }
@@ -128,6 +128,15 @@
   CodeBuffer* code()                             { return &_code; }
   C1_MacroAssembler* masm() const                { return _masm; }
   CodeOffsets* offsets()                         { return &_offsets; }
+  Arena* arena()                                 { return _arena; }
+
+  // Instruction ids
+  int get_next_id()                              { return _next_id++; }
+  int number_of_instructions() const             { return _next_id; }
+
+  // BlockBegin ids
+  int get_next_block_id()                        { return _next_block_id++; }
+  int number_of_blocks() const                   { return _next_block_id; }
 
   // setters
   void set_has_exception_handlers(bool f)        { _has_exception_handlers = f; }
@@ -158,6 +167,15 @@
   bool bailed_out() const                        { return _bailout_msg != NULL; }
   const char* bailout_msg() const                { return _bailout_msg; }
 
+  static int desired_max_code_buffer_size() {
+    return (int) NMethodSizeLimit;  // default 256K or 512K
+  }
+  static int desired_max_constant_size() {
+    return (int) NMethodSizeLimit / 10;  // about 25K
+  }
+
+  static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
+
   // timers
   static void print_timers();
 
@@ -203,7 +221,10 @@
 // Base class for objects allocated by the compiler in the compilation arena
 class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC {
  public:
-  void* operator new(size_t size) { return Compilation::arena()->Amalloc(size); }
+  void* operator new(size_t size) { return Compilation::current()->arena()->Amalloc(size); }
+  void* operator new(size_t size, Arena* arena) {
+    return arena->Amalloc(size);
+  }
   void  operator delete(void* p) {} // nothing to do
 };
 
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -27,9 +27,6 @@
 
 volatile int Compiler::_runtimes = uninitialized;
 
-volatile bool Compiler::_compiling = false;
-
-
 Compiler::Compiler() {
 }
 
@@ -39,47 +36,62 @@
 }
 
 
+void Compiler::initialize_all() {
+  BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
+  Arena* arena = new Arena();
+  Runtime1::initialize(buffer_blob);
+  FrameMap::initialize();
+  // initialize data structures
+  ValueType::initialize(arena);
+  // Instruction::initialize();
+  // BlockBegin::initialize();
+  GraphBuilder::initialize();
+  // note: to use more than one instance of LinearScan at a time this function call has to
+  //       be moved somewhere outside of this constructor:
+  Interval::initialize(arena);
+}
+
+
 void Compiler::initialize() {
   if (_runtimes != initialized) {
-    initialize_runtimes( Runtime1::initialize, &_runtimes);
+    initialize_runtimes( initialize_all, &_runtimes);
   }
   mark_initialized();
 }
 
 
+BufferBlob* Compiler::build_buffer_blob() {
+  // setup CodeBuffer.  Preallocate a BufferBlob of size
+  // NMethodSizeLimit plus some extra space for constants.
+  int code_buffer_size = Compilation::desired_max_code_buffer_size() +
+    Compilation::desired_max_constant_size();
+  BufferBlob* blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
+                                        code_buffer_size);
+  guarantee(blob != NULL, "must create initial code buffer");
+  return blob;
+}
+
+
 void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) {
+  // Allocate buffer blob once at startup since allocation for each
+  // compilation seems to be too expensive (at least on Intel win32).
+  BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
+  if (buffer_blob == NULL) {
+    buffer_blob = build_buffer_blob();
+    CompilerThread::current()->set_buffer_blob(buffer_blob);
+  }
 
   if (!is_initialized()) {
     initialize();
   }
   // invoke compilation
-#ifdef TIERED
-  // We are thread in native here...
-  CompilerThread* thread = CompilerThread::current();
-  {
-    ThreadInVMfromNative tv(thread);
-    MutexLocker only_one (C1_lock, thread);
-    while ( _compiling) {
-      C1_lock->wait();
-    }
-    _compiling = true;
-  }
-#endif // TIERED
   {
     // We are nested here because we need for the destructor
     // of Compilation to occur before we release the any
     // competing compiler thread
     ResourceMark rm;
-    Compilation c(this, env, method, entry_bci);
+    Compilation c(this, env, method, entry_bci, buffer_blob);
   }
-#ifdef TIERED
-  {
-    ThreadInVMfromNative tv(thread);
-    MutexLocker only_one (C1_lock, thread);
-    _compiling = false;
-    C1_lock->notify();
-  }
-#endif // TIERED
 }
 
 
--- a/hotspot/src/share/vm/c1/c1_Compiler.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Compiler.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -31,10 +31,6 @@
  // Tracks whether runtime has been initialized
  static volatile int _runtimes;
 
- // In tiered it is possible for multiple threads to want to do compilation
- // only one can enter c1 at a time
- static volatile bool _compiling;
-
  public:
   // Creation
   Compiler();
@@ -47,6 +43,7 @@
   virtual bool is_c1() { return true; };
 #endif // TIERED
 
+  BufferBlob* build_buffer_blob();
 
   // Missing feature tests
   virtual bool supports_native()                 { return true; }
@@ -58,6 +55,7 @@
 
   // Initialization
   virtual void initialize();
+  static  void initialize_all();
 
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -153,7 +153,7 @@
 
 
 FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) {
-  if (!_init_done) init();
+  assert(_init_done, "should already be completed");
 
   _framesize = -1;
   _num_spills = -1;
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -235,7 +235,7 @@
     return _caller_save_fpu_regs[i];
   }
 
-  static void init();
+  static void initialize();
 };
 
 //               CallingConvention
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -2530,16 +2530,10 @@
 }
 
 
-bool GraphBuilder::_is_initialized = false;
 bool GraphBuilder::_can_trap      [Bytecodes::number_of_java_codes];
 bool GraphBuilder::_is_async[Bytecodes::number_of_java_codes];
 
 void GraphBuilder::initialize() {
-  // make sure initialization happens only once (need a
-  // lock here, if we allow the compiler to be re-entrant)
-  if (is_initialized()) return;
-  _is_initialized = true;
-
   // the following bytecodes are assumed to potentially
   // throw exceptions in compiled code - note that e.g.
   // monitorexit & the return bytecodes do not throw
@@ -2855,7 +2849,6 @@
   BlockList* bci2block = blm.bci2block();
   BlockBegin* start_block = bci2block->at(0);
 
-  assert(is_initialized(), "GraphBuilder must have been initialized");
   push_root_scope(scope, bci2block, start_block);
 
   // setup state for std entry
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -162,7 +162,6 @@
   };
 
   // for all GraphBuilders
-  static bool       _is_initialized;             // true if trap tables were initialized, false otherwise
   static bool       _can_trap[Bytecodes::number_of_java_codes];
   static bool       _is_async[Bytecodes::number_of_java_codes];
 
@@ -268,7 +267,6 @@
   Instruction* append_split(StateSplit* instr);
 
   // other helpers
-  static bool is_initialized()                   { return _is_initialized; }
   static bool is_async(Bytecodes::Code code) {
     assert(0 <= code && code < Bytecodes::number_of_java_codes, "illegal bytecode");
     return _is_async[code];
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -287,11 +287,6 @@
 IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) :
     _locals_size(in_WordSize(-1))
   , _num_loops(0) {
-  // initialize data structures
-  ValueType::initialize();
-  Instruction::initialize();
-  BlockBegin::initialize();
-  GraphBuilder::initialize();
   // setup IR fields
   _compilation = compilation;
   _top_scope   = new IRScope(compilation, NULL, -1, method, osr_bci, true);
@@ -381,15 +376,15 @@
 }
 
 
-class UseCountComputer: public AllStatic {
+class UseCountComputer: public ValueVisitor, BlockClosure {
  private:
-  static void update_use_count(Value* n) {
+  void visit(Value* n) {
     // Local instructions and Phis for expression stack values at the
     // start of basic blocks are not added to the instruction list
     if ((*n)->bci() == -99 && (*n)->as_Local() == NULL &&
         (*n)->as_Phi() == NULL) {
       assert(false, "a node was not appended to the graph");
-      Compilation::current_compilation()->bailout("a node was not appended to the graph");
+      Compilation::current()->bailout("a node was not appended to the graph");
     }
     // use n's input if not visited before
     if (!(*n)->is_pinned() && !(*n)->has_uses()) {
@@ -402,31 +397,31 @@
     (*n)->_use_count++;
   }
 
-  static Values* worklist;
-  static int depth;
+  Values* worklist;
+  int depth;
   enum {
     max_recurse_depth = 20
   };
 
-  static void uses_do(Value* n) {
+  void uses_do(Value* n) {
     depth++;
     if (depth > max_recurse_depth) {
       // don't allow the traversal to recurse too deeply
       worklist->push(*n);
     } else {
-      (*n)->input_values_do(update_use_count);
+      (*n)->input_values_do(this);
       // special handling for some instructions
       if ((*n)->as_BlockEnd() != NULL) {
         // note on BlockEnd:
         //   must 'use' the stack only if the method doesn't
         //   terminate, however, in those cases stack is empty
-        (*n)->state_values_do(update_use_count);
+        (*n)->state_values_do(this);
       }
     }
     depth--;
   }
 
-  static void basic_compute_use_count(BlockBegin* b) {
+  void block_do(BlockBegin* b) {
     depth = 0;
     // process all pinned nodes as the roots of expression trees
     for (Instruction* n = b; n != NULL; n = n->next()) {
@@ -449,18 +444,19 @@
     assert(depth == 0, "should have counted back down");
   }
 
+  UseCountComputer() {
+    worklist = new Values();
+    depth = 0;
+  }
+
  public:
   static void compute(BlockList* blocks) {
-    worklist = new Values();
-    blocks->blocks_do(basic_compute_use_count);
-    worklist = NULL;
+    UseCountComputer ucc;
+    blocks->iterate_backward(&ucc);
   }
 };
 
 
-Values* UseCountComputer::worklist = NULL;
-int UseCountComputer::depth = 0;
-
 // helper macro for short definition of trace-output inside code
 #ifndef PRODUCT
   #define TRACE_LINEAR_SCAN(level, code)       \
@@ -1302,7 +1298,7 @@
 
 #endif // PRODUCT
 
-void SubstitutionResolver::substitute(Value* v) {
+void SubstitutionResolver::visit(Value* v) {
   Value v0 = *v;
   if (v0) {
     Value vs = v0->subst();
@@ -1313,20 +1309,22 @@
 }
 
 #ifdef ASSERT
-void check_substitute(Value* v) {
-  Value v0 = *v;
-  if (v0) {
-    Value vs = v0->subst();
-    assert(vs == v0, "missed substitution");
+class SubstitutionChecker: public ValueVisitor {
+  void visit(Value* v) {
+    Value v0 = *v;
+    if (v0) {
+      Value vs = v0->subst();
+      assert(vs == v0, "missed substitution");
+    }
   }
-}
+};
 #endif
 
 
 void SubstitutionResolver::block_do(BlockBegin* block) {
   Instruction* last = NULL;
   for (Instruction* n = block; n != NULL;) {
-    n->values_do(substitute);
+    n->values_do(this);
     // need to remove this instruction from the instruction stream
     if (n->subst() != n) {
       assert(last != NULL, "must have last");
@@ -1338,8 +1336,9 @@
   }
 
 #ifdef ASSERT
-  if (block->state()) block->state()->values_do(check_substitute);
-  block->block_values_do(check_substitute);
-  if (block->end() && block->end()->state()) block->end()->state()->values_do(check_substitute);
+  SubstitutionChecker check_substitute;
+  if (block->state()) block->state()->values_do(&check_substitute);
+  block->block_values_do(&check_substitute);
+  if (block->end() && block->end()->state()) block->end()->state()->values_do(&check_substitute);
 #endif
 }
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -371,8 +371,8 @@
 // instructions from the instruction list.
 //
 
-class SubstitutionResolver: public BlockClosure {
-  static void substitute(Value* v);
+class SubstitutionResolver: public BlockClosure, ValueVisitor {
+  virtual void visit(Value* v);
 
  public:
   SubstitutionResolver(IR* hir) {
--- a/hotspot/src/share/vm/c1/c1_Instruction.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -29,8 +29,6 @@
 // Implementation of Instruction
 
 
-int Instruction::_next_id = 0;
-
 #ifdef ASSERT
 void Instruction::create_hi_word() {
   assert(type()->is_double_word() && _hi_word == NULL, "only double word has high word");
@@ -193,22 +191,22 @@
 }
 
 
-void ArithmeticOp::other_values_do(void f(Value*)) {
+void ArithmeticOp::other_values_do(ValueVisitor* f) {
   if (lock_stack() != NULL) lock_stack()->values_do(f);
 }
 
-void NullCheck::other_values_do(void f(Value*)) {
+void NullCheck::other_values_do(ValueVisitor* f) {
   lock_stack()->values_do(f);
 }
 
-void AccessArray::other_values_do(void f(Value*)) {
+void AccessArray::other_values_do(ValueVisitor* f) {
   if (lock_stack() != NULL) lock_stack()->values_do(f);
 }
 
 
 // Implementation of AccessField
 
-void AccessField::other_values_do(void f(Value*)) {
+void AccessField::other_values_do(ValueVisitor* f) {
   if (state_before() != NULL) state_before()->values_do(f);
   if (lock_stack() != NULL) lock_stack()->values_do(f);
 }
@@ -270,7 +268,7 @@
 
 // Implementation of CompareOp
 
-void CompareOp::other_values_do(void f(Value*)) {
+void CompareOp::other_values_do(ValueVisitor* f) {
   if (state_before() != NULL) state_before()->values_do(f);
 }
 
@@ -302,12 +300,12 @@
 }
 
 
-void StateSplit::state_values_do(void f(Value*)) {
+void StateSplit::state_values_do(ValueVisitor* f) {
   if (state() != NULL) state()->values_do(f);
 }
 
 
-void BlockBegin::state_values_do(void f(Value*)) {
+void BlockBegin::state_values_do(ValueVisitor* f) {
   StateSplit::state_values_do(f);
 
   if (is_set(BlockBegin::exception_entry_flag)) {
@@ -318,13 +316,13 @@
 }
 
 
-void MonitorEnter::state_values_do(void f(Value*)) {
+void MonitorEnter::state_values_do(ValueVisitor* f) {
   StateSplit::state_values_do(f);
   _lock_stack_before->values_do(f);
 }
 
 
-void Intrinsic::state_values_do(void f(Value*)) {
+void Intrinsic::state_values_do(ValueVisitor* f) {
   StateSplit::state_values_do(f);
   if (lock_stack() != NULL) lock_stack()->values_do(f);
 }
@@ -349,8 +347,9 @@
 
   assert(args != NULL, "args must exist");
 #ifdef ASSERT
-  values_do(assert_value);
-#endif // ASSERT
+  AssertValues assert_value;
+  values_do(&assert_value);
+#endif
 
   // provide an initial guess of signature size.
   _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0));
@@ -368,7 +367,7 @@
 }
 
 
-void Invoke::state_values_do(void f(Value*)) {
+void Invoke::state_values_do(ValueVisitor* f) {
   StateSplit::state_values_do(f);
   if (state_before() != NULL) state_before()->values_do(f);
   if (state()        != NULL) state()->values_do(f);
@@ -500,30 +499,27 @@
 }
 
 
-void Constant::other_values_do(void f(Value*)) {
+void Constant::other_values_do(ValueVisitor* f) {
   if (state() != NULL) state()->values_do(f);
 }
 
 
 // Implementation of NewArray
 
-void NewArray::other_values_do(void f(Value*)) {
+void NewArray::other_values_do(ValueVisitor* f) {
   if (state_before() != NULL) state_before()->values_do(f);
 }
 
 
 // Implementation of TypeCheck
 
-void TypeCheck::other_values_do(void f(Value*)) {
+void TypeCheck::other_values_do(ValueVisitor* f) {
   if (state_before() != NULL) state_before()->values_do(f);
 }
 
 
 // Implementation of BlockBegin
 
-int BlockBegin::_next_block_id = 0;
-
-
 void BlockBegin::set_end(BlockEnd* end) {
   assert(end != NULL, "should not reset block end to NULL");
   BlockEnd* old_end = _end;
@@ -738,7 +734,7 @@
 }
 
 
-void BlockBegin::block_values_do(void f(Value*)) {
+void BlockBegin::block_values_do(ValueVisitor* f) {
   for (Instruction* n = this; n != NULL; n = n->next()) n->values_do(f);
 }
 
@@ -930,7 +926,7 @@
 }
 
 
-void BlockList::values_do(void f(Value*)) {
+void BlockList::values_do(ValueVisitor* f) {
   for (int i = length() - 1; i >= 0; i--) at(i)->block_values_do(f);
 }
 
@@ -973,7 +969,7 @@
 }
 
 
-void BlockEnd::other_values_do(void f(Value*)) {
+void BlockEnd::other_values_do(ValueVisitor* f) {
   if (state_before() != NULL) state_before()->values_do(f);
 }
 
@@ -1012,6 +1008,6 @@
 
 // Implementation of Throw
 
-void Throw::state_values_do(void f(Value*)) {
+void Throw::state_values_do(ValueVisitor* f) {
   BlockEnd::state_values_do(f);
 }
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -116,6 +116,13 @@
 };
 
 
+// A simple closure class for visiting the values of an Instruction
+class ValueVisitor: public StackObj {
+ public:
+  virtual void visit(Value* v) = 0;
+};
+
+
 // Some array and list classes
 define_array(BlockBeginArray, BlockBegin*)
 define_stack(_BlockList, BlockBeginArray)
@@ -129,7 +136,7 @@
   void iterate_forward(BlockClosure* closure);
   void iterate_backward(BlockClosure* closure);
   void blocks_do(void f(BlockBegin*));
-  void values_do(void f(Value*));
+  void values_do(ValueVisitor* f);
   void print(bool cfg_only = false, bool live_only = false) PRODUCT_RETURN;
 };
 
@@ -264,8 +271,6 @@
 
 class Instruction: public CompilationResourceObj {
  private:
-  static int   _next_id;                         // the node counter
-
   int          _id;                              // the unique instruction id
   int          _bci;                             // the instruction bci
   int          _use_count;                       // the number of instructions refering to this value (w/o prev/next); only roots can have use count = 0 or > 1
@@ -283,6 +288,7 @@
 #endif
 
   friend class UseCountComputer;
+  friend class BlockBegin;
 
  protected:
   void set_bci(int bci)                          { assert(bci == SynchronizationEntryBCI || bci >= 0, "illegal bci"); _bci = bci; }
@@ -292,6 +298,13 @@
   }
 
  public:
+  void* operator new(size_t size) {
+    Compilation* c = Compilation::current();
+    void* res = c->arena()->Amalloc(size);
+    ((Instruction*)res)->_id = c->get_next_id();
+    return res;
+  }
+
   enum InstructionFlag {
     NeedsNullCheckFlag = 0,
     CanTrapFlag,
@@ -338,13 +351,13 @@
   static Condition negate(Condition cond);
 
   // initialization
-  static void initialize()                       { _next_id = 0; }
-  static int number_of_instructions()            { return _next_id; }
+  static int number_of_instructions() {
+    return Compilation::current()->number_of_instructions();
+  }
 
   // creation
   Instruction(ValueType* type, bool type_is_constant = false, bool create_hi = true)
-  : _id(_next_id++)
-  , _bci(-99)
+  : _bci(-99)
   , _use_count(0)
   , _pin_state(0)
   , _type(type)
@@ -479,10 +492,10 @@
 
   virtual bool can_trap() const                  { return false; }
 
-  virtual void input_values_do(void f(Value*))   = 0;
-  virtual void state_values_do(void f(Value*))   { /* usually no state - override on demand */ }
-  virtual void other_values_do(void f(Value*))   { /* usually no other - override on demand */ }
-          void       values_do(void f(Value*))   { input_values_do(f); state_values_do(f); other_values_do(f); }
+  virtual void input_values_do(ValueVisitor* f)   = 0;
+  virtual void state_values_do(ValueVisitor* f)   { /* usually no state - override on demand */ }
+  virtual void other_values_do(ValueVisitor* f)   { /* usually no other - override on demand */ }
+          void       values_do(ValueVisitor* f)   { input_values_do(f); state_values_do(f); other_values_do(f); }
 
   virtual ciType* exact_type() const             { return NULL; }
   virtual ciType* declared_type() const          { return NULL; }
@@ -517,9 +530,12 @@
 
 // Debugging support
 
+
 #ifdef ASSERT
-  static void assert_value(Value* x)             { assert((*x) != NULL, "value must exist"); }
-  #define ASSERT_VALUES                          values_do(assert_value);
+class AssertValues: public ValueVisitor {
+  void visit(Value* x)             { assert((*x) != NULL, "value must exist"); }
+};
+  #define ASSERT_VALUES                          { AssertValues assert_value; values_do(&assert_value); }
 #else
   #define ASSERT_VALUES
 #endif // ASSERT
@@ -555,7 +571,7 @@
   void make_illegal()                            { set_type(illegalType); }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { ShouldNotReachHere(); }
+  virtual void input_values_do(ValueVisitor* f)   { ShouldNotReachHere(); }
 };
 
 
@@ -615,7 +631,7 @@
   }
 
   // generic
-  virtual void input_values_do(void f(Value*)) {
+  virtual void input_values_do(ValueVisitor* f) {
   }
 };
 
@@ -635,7 +651,7 @@
   int java_index() const                         { return _java_index; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { /* no values */ }
+  virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
 };
 
 
@@ -663,8 +679,8 @@
 
   // generic
   virtual bool can_trap() const                  { return state() != NULL; }
-  virtual void input_values_do(void f(Value*))   { /* no values */ }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
+  virtual void other_values_do(ValueVisitor* f);
 
   virtual intx hash() const;
   virtual bool is_equal(Value v) const;
@@ -734,8 +750,8 @@
 
   // generic
   virtual bool can_trap() const                  { return needs_null_check() || needs_patching(); }
-  virtual void input_values_do(void f(Value*))   { f(&_obj); }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_obj); }
+  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -776,7 +792,7 @@
   bool needs_write_barrier() const               { return check_flag(NeedsWriteBarrierFlag); }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { AccessField::input_values_do(f); f(&_value); }
+  virtual void input_values_do(ValueVisitor* f)   { AccessField::input_values_do(f); f->visit(&_value); }
 };
 
 
@@ -804,8 +820,8 @@
 
   // generic
   virtual bool can_trap() const                  { return needs_null_check(); }
-  virtual void input_values_do(void f(Value*))   { f(&_array); }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_array); }
+  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -857,7 +873,7 @@
   bool compute_needs_range_check();
 
   // generic
-  virtual void input_values_do(void f(Value*))   { AccessArray::input_values_do(f); f(&_index); if (_length != NULL) f(&_length); }
+  virtual void input_values_do(ValueVisitor* f)   { AccessArray::input_values_do(f); f->visit(&_index); if (_length != NULL) f->visit(&_length); }
 };
 
 
@@ -909,7 +925,7 @@
   bool needs_store_check() const                 { return check_flag(NeedsStoreCheckFlag); }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { AccessIndexed::input_values_do(f); f(&_value); }
+  virtual void input_values_do(ValueVisitor* f)   { AccessIndexed::input_values_do(f); f->visit(&_value); }
 };
 
 
@@ -927,7 +943,7 @@
   Value x() const                                { return _x; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { f(&_x); }
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_x); }
 };
 
 
@@ -956,7 +972,7 @@
 
   // generic
   virtual bool is_commutative() const            { return false; }
-  virtual void input_values_do(void f(Value*))   { f(&_x); f(&_y); }
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_x); f->visit(&_y); }
 };
 
 
@@ -982,7 +998,7 @@
   // generic
   virtual bool is_commutative() const;
   virtual bool can_trap() const;
-  virtual void other_values_do(void f(Value*));
+  virtual void other_values_do(ValueVisitor* f);
   HASHING3(Op2, true, op(), x()->subst(), y()->subst())
 };
 
@@ -1023,7 +1039,7 @@
 
   // generic
   HASHING3(Op2, true, op(), x()->subst(), y()->subst())
-  virtual void other_values_do(void f(Value*));
+  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -1051,7 +1067,7 @@
   Value fval() const                             { return _fval; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { Op2::input_values_do(f); f(&_tval); f(&_fval); }
+  virtual void input_values_do(ValueVisitor* f)   { Op2::input_values_do(f); f->visit(&_tval); f->visit(&_fval); }
 };
 
 
@@ -1071,7 +1087,7 @@
   Value value() const                            { return _value; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { f(&_value); }
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_value); }
   HASHING2(Convert, true, op(), value()->subst())
 };
 
@@ -1100,8 +1116,8 @@
 
   // generic
   virtual bool can_trap() const                  { return check_flag(CanTrapFlag); /* null-check elimination sets to false */ }
-  virtual void input_values_do(void f(Value*))   { f(&_obj); }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_obj); }
+  virtual void other_values_do(ValueVisitor* f);
   HASHING1(NullCheck, true, obj()->subst())
 };
 
@@ -1127,8 +1143,8 @@
   void set_state(ValueStack* state)              { _state = state; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { /* no values */ }
-  virtual void state_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
+  virtual void state_values_do(ValueVisitor* f);
 };
 
 
@@ -1169,12 +1185,12 @@
 
   // generic
   virtual bool can_trap() const                  { return true; }
-  virtual void input_values_do(void f(Value*)) {
+  virtual void input_values_do(ValueVisitor* f) {
     StateSplit::input_values_do(f);
-    if (has_receiver()) f(&_recv);
-    for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
+    if (has_receiver()) f->visit(&_recv);
+    for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
   }
-  virtual void state_values_do(void f(Value*));
+  virtual void state_values_do(ValueVisitor *f);
 };
 
 
@@ -1212,8 +1228,8 @@
 
   // generic
   virtual bool can_trap() const                  { return true; }
-  virtual void input_values_do(void f(Value*))   { StateSplit::input_values_do(f); f(&_length); }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_length); }
+  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -1262,7 +1278,7 @@
   int rank() const                               { return dims()->length(); }
 
   // generic
-  virtual void input_values_do(void f(Value*)) {
+  virtual void input_values_do(ValueVisitor* f) {
     // NOTE: we do not call NewArray::input_values_do since "length"
     // is meaningless for a multi-dimensional array; passing the
     // zeroth element down to NewArray as its length is a bad idea
@@ -1270,7 +1286,7 @@
     // get updated, and the value must not be traversed twice. Was bug
     // - kbr 4/10/2001
     StateSplit::input_values_do(f);
-    for (int i = 0; i < _dims->length(); i++) f(_dims->adr_at(i));
+    for (int i = 0; i < _dims->length(); i++) f->visit(_dims->adr_at(i));
   }
 };
 
@@ -1300,8 +1316,8 @@
 
   // generic
   virtual bool can_trap() const                  { return true; }
-  virtual void input_values_do(void f(Value*))   { StateSplit::input_values_do(f); f(&_obj); }
-  virtual void other_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_obj); }
+  virtual void other_values_do(ValueVisitor* f);
 };
 
 
@@ -1366,7 +1382,7 @@
   int monitor_no() const                         { return _monitor_no; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { StateSplit::input_values_do(f); f(&_obj); }
+  virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_obj); }
 };
 
 
@@ -1385,7 +1401,7 @@
 
   // accessors
   ValueStack* lock_stack_before() const          { return _lock_stack_before; }
-  virtual void state_values_do(void f(Value*));
+  virtual void state_values_do(ValueVisitor* f);
 
   // generic
   virtual bool can_trap() const                  { return true; }
@@ -1454,11 +1470,11 @@
 
   // generic
   virtual bool can_trap() const                  { return check_flag(CanTrapFlag); }
-  virtual void input_values_do(void f(Value*)) {
+  virtual void input_values_do(ValueVisitor* f) {
     StateSplit::input_values_do(f);
-    for (int i = 0; i < _args->length(); i++) f(_args->adr_at(i));
+    for (int i = 0; i < _args->length(); i++) f->visit(_args->adr_at(i));
   }
-  virtual void state_values_do(void f(Value*));
+  virtual void state_values_do(ValueVisitor* f);
 
 };
 
@@ -1467,8 +1483,6 @@
 
 LEAF(BlockBegin, StateSplit)
  private:
-  static int _next_block_id;                     // the block counter
-
   int        _block_id;                          // the unique block id
   int        _depth_first_number;                // number of this block in a depth-first ordering
   int        _linear_scan_number;                // number of this block in linear-scan ordering
@@ -1510,14 +1524,22 @@
   friend class SuxAndWeightAdjuster;
 
  public:
+   void* operator new(size_t size) {
+    Compilation* c = Compilation::current();
+    void* res = c->arena()->Amalloc(size);
+    ((BlockBegin*)res)->_id = c->get_next_id();
+    ((BlockBegin*)res)->_block_id = c->get_next_block_id();
+    return res;
+  }
+
   // initialization/counting
-  static void initialize()                       { _next_block_id = 0; }
-  static int  number_of_blocks()                 { return _next_block_id; }
+  static int  number_of_blocks() {
+    return Compilation::current()->number_of_blocks();
+  }
 
   // creation
   BlockBegin(int bci)
   : StateSplit(illegalType)
-  , _block_id(_next_block_id++)
   , _depth_first_number(-1)
   , _linear_scan_number(-1)
   , _loop_depth(0)
@@ -1592,7 +1614,7 @@
   void init_stores_to_locals(int locals_count)   { _stores_to_locals = BitMap(locals_count); _stores_to_locals.clear(); }
 
   // generic
-  virtual void state_values_do(void f(Value*));
+  virtual void state_values_do(ValueVisitor* f);
 
   // successors and predecessors
   int number_of_sux() const;
@@ -1646,7 +1668,7 @@
   void iterate_preorder   (BlockClosure* closure);
   void iterate_postorder  (BlockClosure* closure);
 
-  void block_values_do(void f(Value*));
+  void block_values_do(ValueVisitor* f);
 
   // loops
   void set_loop_index(int ix)                    { _loop_index = ix;        }
@@ -1698,7 +1720,7 @@
   void set_begin(BlockBegin* begin);
 
   // generic
-  virtual void other_values_do(void f(Value*));
+  virtual void other_values_do(ValueVisitor* f);
 
   // successors
   int number_of_sux() const                      { return _sux != NULL ? _sux->length() : 0; }
@@ -1787,7 +1809,7 @@
   void set_profiled_bci(int bci)                  { _profiled_bci = bci;       }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { BlockEnd::input_values_do(f); f(&_x); f(&_y); }
+  virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_x); f->visit(&_y); }
 };
 
 
@@ -1841,7 +1863,7 @@
   }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { BlockEnd::input_values_do(f); f(&_obj); }
+  virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_obj); }
 };
 
 
@@ -1863,7 +1885,7 @@
   int length() const                             { return number_of_sux() - 1; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { BlockEnd::input_values_do(f); f(&_tag); }
+  virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_tag); }
 };
 
 
@@ -1916,9 +1938,9 @@
   bool has_result() const                        { return result() != NULL; }
 
   // generic
-  virtual void input_values_do(void f(Value*)) {
+  virtual void input_values_do(ValueVisitor* f) {
     BlockEnd::input_values_do(f);
-    if (has_result()) f(&_result);
+    if (has_result()) f->visit(&_result);
   }
 };
 
@@ -1938,8 +1960,8 @@
 
   // generic
   virtual bool can_trap() const                  { return true; }
-  virtual void input_values_do(void f(Value*))   { BlockEnd::input_values_do(f); f(&_exception); }
-  virtual void state_values_do(void f(Value*));
+  virtual void input_values_do(ValueVisitor* f)   { BlockEnd::input_values_do(f); f->visit(&_exception); }
+  virtual void state_values_do(ValueVisitor* f);
 };
 
 
@@ -1971,7 +1993,7 @@
 #endif
 
   // generic
-  virtual void input_values_do(void f(Value*))   { }
+  virtual void input_values_do(ValueVisitor* f)   { }
 };
 
 
@@ -1984,7 +2006,7 @@
   }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { }
+  virtual void input_values_do(ValueVisitor* f)   { }
 };
 
 
@@ -2008,7 +2030,7 @@
   Value input() const                            { return _input; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { f(&_input); }
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_input); }
 };
 
 
@@ -2033,8 +2055,8 @@
   BasicType basic_type()                         { return _basic_type; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { }
-  virtual void other_values_do(void f(Value*))   { }
+  virtual void input_values_do(ValueVisitor* f)   { }
+  virtual void other_values_do(ValueVisitor* f)   { }
 };
 
 
@@ -2078,9 +2100,9 @@
   void set_log2_scale(int log2_scale)            { _log2_scale = log2_scale; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { UnsafeOp::input_values_do(f);
-                                                   f(&_base);
-                                                   if (has_index()) f(&_index); }
+  virtual void input_values_do(ValueVisitor* f)   { UnsafeOp::input_values_do(f);
+                                                   f->visit(&_base);
+                                                   if (has_index()) f->visit(&_index); }
 };
 
 
@@ -2128,8 +2150,8 @@
   Value value()                                  { return _value; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { UnsafeRawOp::input_values_do(f);
-                                                   f(&_value); }
+  virtual void input_values_do(ValueVisitor* f)   { UnsafeRawOp::input_values_do(f);
+                                                   f->visit(&_value); }
 };
 
 
@@ -2149,9 +2171,9 @@
   Value offset()                                 { return _offset; }
   bool  is_volatile()                            { return _is_volatile; }
   // generic
-  virtual void input_values_do(void f(Value*))   { UnsafeOp::input_values_do(f);
-                                                   f(&_object);
-                                                   f(&_offset); }
+  virtual void input_values_do(ValueVisitor* f)   { UnsafeOp::input_values_do(f);
+                                                   f->visit(&_object);
+                                                   f->visit(&_offset); }
 };
 
 
@@ -2180,8 +2202,8 @@
   Value value()                                  { return _value; }
 
   // generic
-  virtual void input_values_do(void f(Value*))   { UnsafeObjectOp::input_values_do(f);
-                                                   f(&_value); }
+  virtual void input_values_do(ValueVisitor* f)   { UnsafeObjectOp::input_values_do(f);
+                                                   f->visit(&_value); }
 };
 
 
@@ -2238,7 +2260,7 @@
   Value recv()            { return _recv; }
   ciKlass* known_holder() { return _known_holder; }
 
-  virtual void input_values_do(void f(Value*))   { if (_recv != NULL) f(&_recv); }
+  virtual void input_values_do(ValueVisitor* f)   { if (_recv != NULL) f->visit(&_recv); }
 };
 
 
@@ -2266,7 +2288,7 @@
   int offset()     { return _offset; }
   int increment()  { return _increment; }
 
-  virtual void input_values_do(void f(Value*))   { f(&_mdo); }
+  virtual void input_values_do(ValueVisitor* f)   { f->visit(&_mdo); }
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -304,7 +304,7 @@
   __ branch_destination(block->label());
 
   if (LIRTraceExecution &&
-      Compilation::current_compilation()->hir()->start()->block_id() != block->block_id() &&
+      Compilation::current()->hir()->start()->block_id() != block->block_id() &&
       !block->is_set(BlockBegin::exception_entry_flag)) {
     assert(block->lir()->instructions_list()->length() == 1, "should come right after br_dst");
     trace_block_entry(block);
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -84,10 +84,6 @@
  , _fpu_stack_allocator(NULL)
 #endif
 {
-  // note: to use more than on instance of LinearScan at a time this function call has to
-  //       be moved somewhere outside of this constructor:
-  Interval::initialize();
-
   assert(this->ir() != NULL,          "check if valid");
   assert(this->compilation() != NULL, "check if valid");
   assert(this->gen() != NULL,         "check if valid");
@@ -3929,8 +3925,8 @@
 
 // initialize sentinel
 Range* Range::_end = NULL;
-void Range::initialize() {
-  _end = new Range(max_jint, max_jint, NULL);
+void Range::initialize(Arena* arena) {
+  _end = new (arena) Range(max_jint, max_jint, NULL);
 }
 
 int Range::intersects_at(Range* r2) const {
@@ -3976,9 +3972,9 @@
 
 // initialize sentinel
 Interval* Interval::_end = NULL;
-void Interval::initialize() {
-  Range::initialize();
-  _end = new Interval(-1);
+void Interval::initialize(Arena* arena) {
+  Range::initialize(arena);
+  _end = new (arena) Interval(-1);
 }
 
 Interval::Interval(int reg_num) :
--- a/hotspot/src/share/vm/c1/c1_LinearScan.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -462,7 +462,7 @@
  public:
   Range(int from, int to, Range* next);
 
-  static void      initialize();
+  static void      initialize(Arena* arena);
   static Range*    end()                         { return _end; }
 
   int              from() const                  { return _from; }
@@ -529,7 +529,7 @@
  public:
   Interval(int reg_num);
 
-  static void      initialize();
+  static void      initialize(Arena* arena);
   static Interval* end()                         { return _end; }
 
   // accessors
--- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -437,11 +437,8 @@
 // Because of a static contained within (for the purpose of iteration
 // over instructions), it is only valid to have one of these active at
 // a time
-class NullCheckEliminator {
+class NullCheckEliminator: public ValueVisitor {
  private:
-  static NullCheckEliminator* _static_nce;
-  static void                 do_value(Value* vp);
-
   Optimizer*        _opt;
 
   ValueSet*         _visitable_instructions;        // Visit each instruction only once per basic block
@@ -504,6 +501,8 @@
   // Process a graph
   void iterate(BlockBegin* root);
 
+  void visit(Value* f);
+
   // In some situations (like NullCheck(x); getfield(x)) the debug
   // information from the explicit NullCheck can be used to populate
   // the getfield, even if the two instructions are in different
@@ -602,14 +601,11 @@
 void NullCheckVisitor::do_ProfileCounter (ProfileCounter*  x) {}
 
 
-NullCheckEliminator* NullCheckEliminator::_static_nce = NULL;
-
-
-void NullCheckEliminator::do_value(Value* p) {
+void NullCheckEliminator::visit(Value* p) {
   assert(*p != NULL, "should not find NULL instructions");
-  if (_static_nce->visitable(*p)) {
-    _static_nce->mark_visited(*p);
-    (*p)->visit(&_static_nce->_visitor);
+  if (visitable(*p)) {
+    mark_visited(*p);
+    (*p)->visit(&_visitor);
   }
 }
 
@@ -637,7 +633,6 @@
 
 
 void NullCheckEliminator::iterate_one(BlockBegin* block) {
-  _static_nce = this;
   clear_visitable_state();
   // clear out an old explicit null checks
   set_last_explicit_null_check(NULL);
@@ -712,7 +707,7 @@
     mark_visitable(instr);
     if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) {
       mark_visited(instr);
-      instr->input_values_do(&NullCheckEliminator::do_value);
+      instr->input_values_do(this);
       instr->visit(&_visitor);
     }
   }
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -60,7 +60,6 @@
 
 // Implementation of Runtime1
 
-bool      Runtime1::_is_initialized = false;
 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids];
 const char *Runtime1::_blob_names[] = {
   RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME)
@@ -89,8 +88,6 @@
 int Runtime1::_throw_count = 0;
 #endif
 
-BufferBlob* Runtime1::_buffer_blob  = NULL;
-
 // Simple helper to see if the caller of a runtime stub which
 // entered the VM has been deoptimized
 
@@ -117,43 +114,14 @@
 }
 
 
-BufferBlob* Runtime1::get_buffer_blob() {
-  // Allocate code buffer space only once
-  BufferBlob* blob = _buffer_blob;
-  if (blob == NULL) {
-    // setup CodeBuffer.  Preallocate a BufferBlob of size
-    // NMethodSizeLimit plus some extra space for constants.
-    int code_buffer_size = desired_max_code_buffer_size() + desired_max_constant_size();
-    blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
-                              code_buffer_size);
-    guarantee(blob != NULL, "must create initial code buffer");
-    _buffer_blob = blob;
-  }
-  return _buffer_blob;
-}
-
-void Runtime1::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
-  // Preinitialize the consts section to some large size:
-  int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo));
-  char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
-  code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
-                                        locs_buffer_size / sizeof(relocInfo));
-  code->initialize_consts_size(desired_max_constant_size());
-  // Call stubs + deopt/exception handler
-  code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
-                              LIR_Assembler::exception_handler_size +
-                              LIR_Assembler::deopt_handler_size);
-}
-
-
-void Runtime1::generate_blob_for(StubID id) {
+void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
   assert(0 <= id && id < number_of_ids, "illegal stub id");
   ResourceMark rm;
   // create code buffer for code storage
-  CodeBuffer code(get_buffer_blob()->instructions_begin(),
-                  get_buffer_blob()->instructions_size());
+  CodeBuffer code(buffer_blob->instructions_begin(),
+                  buffer_blob->instructions_size());
 
-  setup_code_buffer(&code, 0);
+  Compilation::setup_code_buffer(&code, 0);
 
   // create assembler for code generation
   StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
@@ -204,35 +172,28 @@
 }
 
 
-void Runtime1::initialize() {
-  // Warning: If we have more than one compilation running in parallel, we
-  //          need a lock here with the current setup (lazy initialization).
-  if (!is_initialized()) {
-    _is_initialized = true;
-
-    // platform-dependent initialization
-    initialize_pd();
-    // generate stubs
-    for (int id = 0; id < number_of_ids; id++) generate_blob_for((StubID)id);
-    // printing
+void Runtime1::initialize(BufferBlob* blob) {
+  // platform-dependent initialization
+  initialize_pd();
+  // generate stubs
+  for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
+  // printing
 #ifndef PRODUCT
-    if (PrintSimpleStubs) {
-      ResourceMark rm;
-      for (int id = 0; id < number_of_ids; id++) {
-        _blobs[id]->print();
-        if (_blobs[id]->oop_maps() != NULL) {
-          _blobs[id]->oop_maps()->print();
-        }
+  if (PrintSimpleStubs) {
+    ResourceMark rm;
+    for (int id = 0; id < number_of_ids; id++) {
+      _blobs[id]->print();
+      if (_blobs[id]->oop_maps() != NULL) {
+        _blobs[id]->oop_maps()->print();
       }
     }
+  }
 #endif
-  }
 }
 
 
 CodeBlob* Runtime1::blob_for(StubID id) {
   assert(0 <= id && id < number_of_ids, "illegal stub id");
-  if (!is_initialized()) initialize();
   return _blobs[id];
 }
 
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -70,18 +70,6 @@
 class Runtime1: public AllStatic {
   friend class VMStructs;
   friend class ArrayCopyStub;
- private:
-  static int desired_max_code_buffer_size() {
-    return (int) NMethodSizeLimit;  // default 256K or 512K
-  }
-  static int desired_max_constant_size() {
-    return (int) NMethodSizeLimit / 10;  // about 25K
-  }
-
-  // Note: This buffers is allocated once at startup since allocation
-  // for each compilation seems to be too expensive (at least on Intel
-  // win32).
-  static BufferBlob* _buffer_blob;
 
  public:
   enum StubID {
@@ -115,12 +103,11 @@
 #endif
 
  private:
-  static bool      _is_initialized;
   static CodeBlob* _blobs[number_of_ids];
   static const char* _blob_names[];
 
   // stub generation
-  static void generate_blob_for(StubID id);
+  static void generate_blob_for(BufferBlob* blob, StubID id);
   static OopMapSet* generate_code_for(StubID id, StubAssembler* masm);
   static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument);
   static void generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map, bool ignore_fpu_registers = false);
@@ -162,12 +149,8 @@
   static void patch_code(JavaThread* thread, StubID stub_id);
 
  public:
-  static BufferBlob* get_buffer_blob();
-  static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
-
   // initialization
-  static bool is_initialized()                   { return _is_initialized; }
-  static void initialize();
+  static void initialize(BufferBlob* blob);
   static void initialize_pd();
 
   // stubs
--- a/hotspot/src/share/vm/c1/c1_ValueStack.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueStack.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -119,14 +119,14 @@
 
 
 // apply function to all values of a list; factored out from values_do(f)
-void ValueStack::apply(Values list, void f(Value*)) {
+void ValueStack::apply(Values list, ValueVisitor* f) {
   for (int i = 0; i < list.length(); i++) {
     Value* va = list.adr_at(i);
     Value v0 = *va;
     if (v0 != NULL) {
       if (!v0->type()->is_illegal()) {
         assert(v0->as_HiWord() == NULL, "should never see HiWord during traversal");
-        f(va);
+        f->visit(va);
 #ifdef ASSERT
         Value v1 = *va;
         if (v0 != v1) {
@@ -143,7 +143,7 @@
 }
 
 
-void ValueStack::values_do(void f(Value*)) {
+void ValueStack::values_do(ValueVisitor* f) {
   apply(_stack, f);
   apply(_locks, f);
 
--- a/hotspot/src/share/vm/c1/c1_ValueStack.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueStack.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -41,7 +41,7 @@
   }
 
   // helper routine
-  static void apply(Values list, void f(Value*));
+  static void apply(Values list, ValueVisitor* f);
 
  public:
   // creation
@@ -143,7 +143,7 @@
   void pin_stack_for_linear_scan();
 
   // iteration
-  void values_do(void f(Value*));
+  void values_do(ValueVisitor* f);
 
   // untyped manipulation (for dup_x1, etc.)
   void clear_stack()                             { _stack.clear(); }
--- a/hotspot/src/share/vm/c1/c1_ValueType.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueType.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -46,27 +46,26 @@
 ObjectConstant* objectNull   = NULL;
 
 
-void ValueType::initialize() {
+void ValueType::initialize(Arena* arena) {
   // Note: Must initialize all types for each compilation
   //       as they are allocated within a ResourceMark!
 
   // types
-  voidType     = new VoidType();
-  intType      = new IntType();
-  longType     = new LongType();
-  floatType    = new FloatType();
-  doubleType   = new DoubleType();
-  objectType   = new ObjectType();
-  arrayType    = new ArrayType();
-  instanceType = new InstanceType();
-  classType    = new ClassType();
-  addressType  = new AddressType();
-  illegalType  = new IllegalType();
+  voidType     = new (arena) VoidType();
+  intType      = new (arena) IntType();
+  longType     = new (arena) LongType();
+  floatType    = new (arena) FloatType();
+  doubleType   = new (arena) DoubleType();
+  objectType   = new (arena) ObjectType();
+  arrayType    = new (arena) ArrayType();
+  instanceType = new (arena) InstanceType();
+  classType    = new (arena) ClassType();
+  addressType  = new (arena) AddressType();
+  illegalType  = new (arena) IllegalType();
 
-  // constants
-  intZero     = new IntConstant(0);
-  intOne      = new IntConstant(1);
-  objectNull  = new ObjectConstant(ciNullObject::make());
+  intZero     = new (arena) IntConstant(0);
+  intOne      = new (arena) IntConstant(1);
+  objectNull  = new (arena) ObjectConstant(ciNullObject::make());
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_ValueType.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_ValueType.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -94,7 +94,7 @@
 
  public:
   // initialization
-  static void initialize();
+  static void initialize(Arena* arena);
 
   // accessors
   virtual ValueType* base() const                = 0; // the 'canonical' type (e.g., intType for an IntConstant)
--- a/hotspot/src/share/vm/includeDB_compiler1	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/includeDB_compiler1	Fri Jun 04 11:18:04 2010 -0700
@@ -71,8 +71,8 @@
 c1_Compilation.cpp                      c1_MacroAssembler.hpp
 c1_Compilation.cpp                      c1_ValueMap.hpp
 c1_Compilation.cpp                      c1_ValueStack.hpp
-c1_Compilation.cpp                      ciEnv.hpp
 c1_Compilation.cpp                      debugInfoRec.hpp
+c1_Compilation.hpp                      ciEnv.hpp
 c1_Compilation.hpp                      exceptionHandlerTable.hpp
 c1_Compilation.hpp                      resourceArea.hpp
 
@@ -82,6 +82,8 @@
 c1_Compiler.cpp                         c1_Compilation.hpp
 c1_Compiler.cpp                         c1_Compiler.hpp
 c1_Compiler.cpp                         c1_FrameMap.hpp
+c1_Compiler.cpp                         c1_GraphBuilder.hpp
+c1_Compiler.cpp                         c1_LinearScan.hpp
 c1_Compiler.cpp                         c1_MacroAssembler.hpp
 c1_Compiler.cpp                         c1_Runtime1.hpp
 c1_Compiler.cpp                         c1_ValueType.hpp
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -82,9 +82,6 @@
 Mutex*   DerivedPointerTableGC_lock   = NULL;
 Mutex*   Compile_lock                 = NULL;
 Monitor* MethodCompileQueue_lock      = NULL;
-#ifdef TIERED
-Monitor* C1_lock                      = NULL;
-#endif // TIERED
 Monitor* CompileThread_lock           = NULL;
 Mutex*   CompileTaskAlloc_lock        = NULL;
 Mutex*   CompileStatistics_lock       = NULL;
@@ -255,11 +252,6 @@
   def(Debug3_lock                  , Mutex  , nonleaf+4,   true );
   def(ProfileVM_lock               , Monitor, nonleaf+4,   false); // used for profiling of the VMThread
   def(CompileThread_lock           , Monitor, nonleaf+5,   false );
-#ifdef TIERED
-  def(C1_lock                      , Monitor, nonleaf+5,   false );
-#endif // TIERED
-
-
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -84,9 +84,6 @@
 extern Mutex*   EvacFailureStack_lock;           // guards the evac failure scan stack
 extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
 extern Monitor* MethodCompileQueue_lock;         // a lock held when method compilations are enqueued, dequeued
-#ifdef TIERED
-extern Monitor* C1_lock;                         // a lock to ensure on single c1 compile is ever active
-#endif // TIERED
 extern Monitor* CompileThread_lock;              // a lock held by compile threads during compilation system initialization
 extern Mutex*   CompileTaskAlloc_lock;           // a lock held when CompileTasks are allocated
 extern Mutex*   CompileStatistics_lock;          // a lock held when updating compilation statistics
--- a/hotspot/src/share/vm/runtime/thread.cpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri Jun 04 11:18:04 2010 -0700
@@ -2797,6 +2797,7 @@
   _task  = NULL;
   _queue = queue;
   _counters = counters;
+  _buffer_blob = NULL;
 
 #ifndef PRODUCT
   _ideal_graph_printer = NULL;
--- a/hotspot/src/share/vm/runtime/thread.hpp	Thu Jun 03 14:20:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri Jun 04 11:18:04 2010 -0700
@@ -1576,6 +1576,7 @@
   CompileLog*   _log;
   CompileTask*  _task;
   CompileQueue* _queue;
+  BufferBlob*   _buffer_blob;
 
  public:
 
@@ -1594,6 +1595,9 @@
   ciEnv*        env()                            { return _env; }
   void          set_env(ciEnv* env)              { _env = env; }
 
+  BufferBlob*   get_buffer_blob()                { return _buffer_blob; }
+  void          set_buffer_blob(BufferBlob* b)   { _buffer_blob = b; };
+
   // Get/set the thread's logging information
   CompileLog*   log()                            { return _log; }
   void          init_log(CompileLog* log) {