# HG changeset patch # User iveresov # Date 1275675484 25200 # Node ID 6c66849ed24e9bd892a8966035255f0b62f3cbe6 # Parent 0c91076143f9b888e1da2822fc5c2ad3dee1ed04 6958292: C1: Enable parallel compilation Summary: Enable parallel compilation in C1 Reviewed-by: never, kvn diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp --- 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: diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/cpu/x86/vm/c1_FrameMap_x86.cpp --- 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); diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Canonicalizer.cpp --- 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; } } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Compilation.cpp --- 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); } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Compilation.hpp --- 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 }; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Compiler.cpp --- 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 } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Compiler.hpp --- 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); diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_FrameMap.cpp --- 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; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_FrameMap.hpp --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_GraphBuilder.hpp --- 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]; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_IR.cpp --- 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 } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_IR.hpp --- 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) { diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Instruction.cpp --- 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); } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Instruction.hpp --- 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); } }; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- 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); diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_LinearScan.cpp --- 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) : diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_LinearScan.hpp --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Optimizer.cpp --- 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); } } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Runtime1.cpp --- 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]; } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_Runtime1.hpp --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_ValueStack.cpp --- 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); diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_ValueStack.hpp --- 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(); } diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_ValueType.cpp --- 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()); }; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/c1/c1_ValueType.hpp --- 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) diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/includeDB_compiler1 --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/runtime/mutexLocker.cpp --- 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) { diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/runtime/mutexLocker.hpp --- 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 diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/runtime/thread.cpp --- 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; diff -r 0c91076143f9 -r 6c66849ed24e hotspot/src/share/vm/runtime/thread.hpp --- 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) {