diff --git a/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp b/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp index bdfd3dbeefa9dee5110134128769aa46b3da6c78..e81b874a40305acd04ca0f14453ada88aece6720 100644 --- a/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp +++ b/src/cpu/sparc/vm/c1_FrameMap_sparc.cpp @@ -181,8 +181,8 @@ bool FrameMap::is_caller_save_register (Register r) { } -void FrameMap::init () { - if (_init_done) return; +void FrameMap::initialize() { + assert(!_init_done, "once"); int i=0; // Register usage: diff --git a/src/cpu/x86/vm/assembler_x86.cpp b/src/cpu/x86/vm/assembler_x86.cpp index 039a23888c546f5361fa86e876b5d96ef55c9167..ab758216c5731184c56067dc6051f51b7237eaf3 100644 --- a/src/cpu/x86/vm/assembler_x86.cpp +++ b/src/cpu/x86/vm/assembler_x86.cpp @@ -7643,6 +7643,9 @@ void MacroAssembler::verify_oop(Register reg, const char* s) { // Pass register number to verify_oop_subroutine char* b = new char[strlen(s) + 50]; sprintf(b, "verify_oop: %s: %s", reg->name(), s); +#ifdef _LP64 + push(rscratch1); // save r10, trashed by movptr() +#endif push(rax); // save rax, push(reg); // pass register argument ExternalAddress buffer((address) b); @@ -7653,6 +7656,7 @@ void MacroAssembler::verify_oop(Register reg, const char* s) { // call indirectly to solve generation ordering problem movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); call(rax); + // Caller pops the arguments (oop, message) and restores rax, r10 } @@ -7767,6 +7771,9 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) { char* b = new char[strlen(s) + 50]; sprintf(b, "verify_oop_addr: %s", s); +#ifdef _LP64 + push(rscratch1); // save r10, trashed by movptr() +#endif push(rax); // save rax, // addr may contain rsp so we will have to adjust it based on the push // we just did @@ -7789,7 +7796,7 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) { // call indirectly to solve generation ordering problem movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address())); call(rax); - // Caller pops the arguments and restores rax, from the stack + // Caller pops the arguments (addr, message) and restores rax, r10. } void MacroAssembler::verify_tlab() { diff --git a/src/cpu/x86/vm/c1_FrameMap_x86.cpp b/src/cpu/x86/vm/c1_FrameMap_x86.cpp index e967f436a2b2bcb39783e2583f16b35984d81220..20e78c242c511707f8c88190754b82c971ccc4b7 100644 --- a/src/cpu/x86/vm/c1_FrameMap_x86.cpp +++ b/src/cpu/x86/vm/c1_FrameMap_x86.cpp @@ -136,8 +136,8 @@ XMMRegister FrameMap::nr2xmmreg(int rnr) { // 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 --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp index bf7e1278bcabfca9ae9d657e936756be3501eadb..9dacdcaf3161d21838c54acae1f1c406b8d27328 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -914,6 +914,7 @@ class StubGenerator: public StubCodeGenerator { // * [tos + 5]: error message (char*) // * [tos + 6]: object to verify (oop) // * [tos + 7]: saved rax - saved by caller and bashed + // * [tos + 8]: saved r10 (rscratch1) - saved by caller // * = popped on exit address generate_verify_oop() { StubCodeMark mark(this, "StubRoutines", "verify_oop"); @@ -934,6 +935,7 @@ class StubGenerator: public StubCodeGenerator { // After previous pushes. oop_to_verify = 6 * wordSize, saved_rax = 7 * wordSize, + saved_r10 = 8 * wordSize, // Before the call to MacroAssembler::debug(), see below. return_addr = 16 * wordSize, @@ -983,15 +985,17 @@ class StubGenerator: public StubCodeGenerator { // return if everything seems ok __ bind(exit); __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back __ pop(c_rarg3); // restore c_rarg3 __ pop(c_rarg2); // restore c_rarg2 __ pop(r12); // restore r12 __ popf(); // restore flags - __ ret(3 * wordSize); // pop caller saved stuff + __ ret(4 * wordSize); // pop caller saved stuff // handle errors __ bind(error); __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back + __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back __ pop(c_rarg3); // get saved c_rarg3 back __ pop(c_rarg2); // get saved c_rarg2 back __ pop(r12); // get saved r12 back @@ -1009,6 +1013,7 @@ class StubGenerator: public StubCodeGenerator { // * [tos + 17] error message (char*) // * [tos + 18] object to verify (oop) // * [tos + 19] saved rax - saved by caller and bashed + // * [tos + 20] saved r10 (rscratch1) - saved by caller // * = popped on exit __ movptr(c_rarg0, Address(rsp, error_msg)); // pass address of error message @@ -1021,7 +1026,7 @@ class StubGenerator: public StubCodeGenerator { __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); __ mov(rsp, r12); // restore rsp __ popa(); // pop registers (includes r12) - __ ret(3 * wordSize); // pop caller saved stuff + __ ret(4 * wordSize); // pop caller saved stuff return start; } diff --git a/src/share/vm/c1/c1_Canonicalizer.cpp b/src/share/vm/c1/c1_Canonicalizer.cpp index 00b8173f1fb5b88a711653d88f85692d0d617456..5607fc00fa8612a81855041fcd70dd8853e23ef6 100644 --- a/src/share/vm/c1/c1_Canonicalizer.cpp +++ b/src/share/vm/c1/c1_Canonicalizer.cpp @@ -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 @@ void Canonicalizer::set_canonical(Value x) { // 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 @@ void Canonicalizer::do_StoreField (StoreField* x) { // 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 --git a/src/share/vm/c1/c1_Compilation.cpp b/src/share/vm/c1/c1_Compilation.cpp index 2bf8902941cb195e95e2b06b59431a351beefd2d..d6f72b8d1b6edd5fb3982f61dea89cdf388d8ece 100644 --- a/src/share/vm/c1/c1_Compilation.cpp +++ b/src/share/vm/c1/c1_Compilation.cpp @@ -66,9 +66,6 @@ class PhaseTraceTime: public TraceTime { } }; -Arena* Compilation::_arena = NULL; -Compilation* Compilation::_compilation = NULL; - // Implementation of Compilation @@ -238,9 +235,23 @@ void Compilation::emit_code_epilog(LIR_Assembler* assembler) { } +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 @@ void Compilation::generate_exception_handler_table() { } -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 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho , _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 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho { 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 --git a/src/share/vm/c1/c1_Compilation.hpp b/src/share/vm/c1/c1_Compilation.hpp index 9d24b24a79b30f895129467e1e035670bcebead4..86d6cbf7a057667727d31b5059186bfa99321be3 100644 --- a/src/share/vm/c1/c1_Compilation.hpp +++ b/src/share/vm/c1/c1_Compilation.hpp @@ -53,15 +53,11 @@ define_stack(ExceptionInfoList, ExceptionInfoArray) 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 @@ class Compilation: public StackObj { 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 @@ class Compilation: public StackObj { 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 @@ class Compilation: public StackObj { 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 @@ class InstructionMark: public StackObj { // 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 --git a/src/share/vm/c1/c1_Compiler.cpp b/src/share/vm/c1/c1_Compiler.cpp index 53216e39925ee04d3cbaf6f200bfb3c0370af799..958a080c80a8ba4f665098be0755b2d6295d63c9 100644 --- a/src/share/vm/c1/c1_Compiler.cpp +++ b/src/share/vm/c1/c1_Compiler.cpp @@ -27,9 +27,6 @@ volatile int Compiler::_runtimes = uninitialized; -volatile bool Compiler::_compiling = false; - - Compiler::Compiler() { } @@ -39,47 +36,62 @@ Compiler::~Compiler() { } +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); - } -#ifdef TIERED - { - ThreadInVMfromNative tv(thread); - MutexLocker only_one (C1_lock, thread); - _compiling = false; - C1_lock->notify(); + Compilation c(this, env, method, entry_bci, buffer_blob); } -#endif // TIERED } diff --git a/src/share/vm/c1/c1_Compiler.hpp b/src/share/vm/c1/c1_Compiler.hpp index 3f7d1f94db03bf2e2d5efa6ee676fb29f2d3542e..a8e6eacd74810a4093e328c8bd2fa3b325c45319 100644 --- a/src/share/vm/c1/c1_Compiler.hpp +++ b/src/share/vm/c1/c1_Compiler.hpp @@ -31,10 +31,6 @@ class Compiler: public AbstractCompiler { // 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 @@ class Compiler: public AbstractCompiler { 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 @@ class Compiler: public AbstractCompiler { // 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 --git a/src/share/vm/c1/c1_FrameMap.cpp b/src/share/vm/c1/c1_FrameMap.cpp index d9ff44afa692a7624f42a62959d14477681e4cba..55fd77b9809dd8d1ba36e72b7bb321d3a82e8ffa 100644 --- a/src/share/vm/c1/c1_FrameMap.cpp +++ b/src/share/vm/c1/c1_FrameMap.cpp @@ -153,7 +153,7 @@ int FrameMap::_cpu_reg2rnr [FrameMap::nof_cpu_regs]; 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 --git a/src/share/vm/c1/c1_FrameMap.hpp b/src/share/vm/c1/c1_FrameMap.hpp index dcbe31d187f760945a5ada73743a550d249cabe7..4c4c99a74923c93d441f93c8c5dfa6666ec6befb 100644 --- a/src/share/vm/c1/c1_FrameMap.hpp +++ b/src/share/vm/c1/c1_FrameMap.hpp @@ -235,7 +235,7 @@ class FrameMap : public CompilationResourceObj { return _caller_save_fpu_regs[i]; } - static void init(); + static void initialize(); }; // CallingConvention diff --git a/src/share/vm/c1/c1_GraphBuilder.cpp b/src/share/vm/c1/c1_GraphBuilder.cpp index b281289992c324c0be902ff734a0faa32b2ffecf..9ffb2ad083ece122c10604d8f7f569aca38971e8 100644 --- a/src/share/vm/c1/c1_GraphBuilder.cpp +++ b/src/share/vm/c1/c1_GraphBuilder.cpp @@ -2530,16 +2530,10 @@ void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) } -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 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope) 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 --git a/src/share/vm/c1/c1_GraphBuilder.hpp b/src/share/vm/c1/c1_GraphBuilder.hpp index 52fe6d7fba2f0acfc208702323c453b4ccf1a178..4ce9dd2bdf3c41506ee64dbdd8fe90fd5994b563 100644 --- a/src/share/vm/c1/c1_GraphBuilder.hpp +++ b/src/share/vm/c1/c1_GraphBuilder.hpp @@ -162,7 +162,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { }; // 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 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { 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 --git a/src/share/vm/c1/c1_IR.cpp b/src/share/vm/c1/c1_IR.cpp index 75b516d5e42732cb7d3cdcf367d59e22d66122c7..4df75f40f66b964007e3a7aa0cadbc92aed0d69d 100644 --- a/src/share/vm/c1/c1_IR.cpp +++ b/src/share/vm/c1/c1_IR.cpp @@ -287,11 +287,6 @@ void CodeEmitInfo::add_register_oop(LIR_Opr opr) { 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 @@ void IR::split_critical_edges() { } -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 @@ class UseCountComputer: public AllStatic { (*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 @@ class UseCountComputer: public AllStatic { 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 @@ void IR::verify() { #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 @@ void SubstitutionResolver::substitute(Value* v) { } #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 @@ void SubstitutionResolver::block_do(BlockBegin* block) { } #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 --git a/src/share/vm/c1/c1_IR.hpp b/src/share/vm/c1/c1_IR.hpp index 6cce0fca488a1b18fa8c08ff238b7497d071da3c..05ef1789f857b82186d8bde6c2ccb8fa0107fdfc 100644 --- a/src/share/vm/c1/c1_IR.hpp +++ b/src/share/vm/c1/c1_IR.hpp @@ -371,8 +371,8 @@ class IR: public CompilationResourceObj { // 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 --git a/src/share/vm/c1/c1_Instruction.cpp b/src/share/vm/c1/c1_Instruction.cpp index f7bdfad85e919825b5397ab9d3a4fd9adb470d0e..018047a351946934ad40655b29f7bd43fd32e073 100644 --- a/src/share/vm/c1/c1_Instruction.cpp +++ b/src/share/vm/c1/c1_Instruction.cpp @@ -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 @@ ciType* CheckCast::exact_type() const { } -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 @@ bool LogicOp::is_commutative() const { // 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 @@ IRScope* StateSplit::scope() const { } -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 BlockBegin::state_values_do(void f(Value*)) { } -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 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* 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 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* } -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 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right, } -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::iterate_postorder(BlockClosure* closure) { } -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::blocks_do(void f(BlockBegin*)) { } -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::substitute_sux(BlockBegin* old_sux, BlockBegin* new_sux) { } -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 @@ int Phi::operand_count() const { // Implementation of Throw -void Throw::state_values_do(void f(Value*)) { +void Throw::state_values_do(ValueVisitor* f) { BlockEnd::state_values_do(f); } diff --git a/src/share/vm/c1/c1_Instruction.hpp b/src/share/vm/c1/c1_Instruction.hpp index 98e19f11473428f6d29f63f2041355350977f9d6..98e9d41bc8adb2412393920fcf63b4ecefed37b5 100644 --- a/src/share/vm/c1/c1_Instruction.hpp +++ b/src/share/vm/c1/c1_Instruction.hpp @@ -116,6 +116,13 @@ class BlockClosure: public CompilationResourceObj { }; +// 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 @@ class BlockList: public _BlockList { 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 InstructionVisitor: public StackObj { 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 @@ class Instruction: public CompilationResourceObj { #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 @@ class Instruction: public CompilationResourceObj { } 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 @@ class Instruction: public CompilationResourceObj { 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 @@ class Instruction: public CompilationResourceObj { 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 @@ class Instruction: public CompilationResourceObj { // 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 @@ LEAF(HiWord, Instruction) 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 @@ LEAF(Phi, Instruction) } // generic - virtual void input_values_do(void f(Value*)) { + virtual void input_values_do(ValueVisitor* f) { } }; @@ -635,7 +651,7 @@ LEAF(Local, Instruction) 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 @@ LEAF(Constant, Instruction) // 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 @@ BASE(AccessField, Instruction) // 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 @@ LEAF(StoreField, AccessField) 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 @@ BASE(AccessArray, Instruction) // 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 @@ BASE(AccessIndexed, AccessArray) 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 @@ LEAF(StoreIndexed, AccessIndexed) 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 @@ LEAF(NegateOp, Instruction) 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 @@ BASE(Op2, Instruction) // 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 @@ LEAF(ArithmeticOp, Op2) // 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 @@ LEAF(CompareOp, Op2) // 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 @@ LEAF(IfOp, Op2) 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 @@ LEAF(Convert, Instruction) 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 @@ LEAF(NullCheck, Instruction) // 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 @@ BASE(StateSplit, Instruction) 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 @@ LEAF(Invoke, StateSplit) // 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 @@ BASE(NewArray, StateSplit) // 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 @@ LEAF(NewMultiArray, NewArray) 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 @@ LEAF(NewMultiArray, NewArray) // 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 @@ BASE(TypeCheck, StateSplit) // 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 @@ BASE(AccessMonitor, StateSplit) 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 @@ LEAF(MonitorEnter, AccessMonitor) // 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 @@ LEAF(Intrinsic, StateSplit) // 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 @@ class LIR_List; 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 @@ LEAF(BlockBegin, StateSplit) 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 @@ LEAF(BlockBegin, StateSplit) 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 @@ LEAF(BlockBegin, StateSplit) 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 @@ BASE(BlockEnd, StateSplit) 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 @@ LEAF(If, BlockEnd) 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 @@ LEAF(IfInstanceOf, BlockEnd) } // 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 @@ BASE(Switch, BlockEnd) 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 @@ LEAF(Return, BlockEnd) 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 @@ LEAF(Throw, BlockEnd) // 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 @@ LEAF(OsrEntry, Instruction) #endif // generic - virtual void input_values_do(void f(Value*)) { } + virtual void input_values_do(ValueVisitor* f) { } }; @@ -1984,7 +2006,7 @@ LEAF(ExceptionObject, Instruction) } // generic - virtual void input_values_do(void f(Value*)) { } + virtual void input_values_do(ValueVisitor* f) { } }; @@ -2008,7 +2030,7 @@ LEAF(RoundFP, Instruction) 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 @@ BASE(UnsafeOp, Instruction) 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 @@ BASE(UnsafeRawOp, UnsafeOp) 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 @@ LEAF(UnsafePutRaw, UnsafeRawOp) 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 @@ BASE(UnsafeObjectOp, UnsafeOp) 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 @@ LEAF(UnsafePutObject, UnsafeObjectOp) 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 @@ LEAF(ProfileCall, Instruction) 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 @@ LEAF(ProfileCounter, Instruction) 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 --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp index c200775d2f5ee74f49caa7031eb845c6da7cbee8..36b46eeaa9fd8c858e16eb388c64cab41fb7ffca 100644 --- a/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/src/share/vm/c1/c1_LIRGenerator.cpp @@ -304,7 +304,7 @@ void LIRGenerator::block_do_prolog(BlockBegin* block) { __ 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 --git a/src/share/vm/c1/c1_LinearScan.cpp b/src/share/vm/c1/c1_LinearScan.cpp index 907e584d59d209ae2dd37a5921c7778c3dffc02c..0888bef3c0108d2406287847ed17774d1d436545 100644 --- a/src/share/vm/c1/c1_LinearScan.cpp +++ b/src/share/vm/c1/c1_LinearScan.cpp @@ -84,10 +84,6 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map) , _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 @@ Range::Range(int from, int to, Range* next) : // 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 @@ void Range::print(outputStream* out) const { // 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 --git a/src/share/vm/c1/c1_LinearScan.hpp b/src/share/vm/c1/c1_LinearScan.hpp index 49bce80dc0afc9f28741c1a8f1d64d95176ce756..9d5b2171e5208232a61e02771291ed21f1b1ca39 100644 --- a/src/share/vm/c1/c1_LinearScan.hpp +++ b/src/share/vm/c1/c1_LinearScan.hpp @@ -462,7 +462,7 @@ class Range : public CompilationResourceObj { 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 @@ class Interval : public CompilationResourceObj { public: Interval(int reg_num); - static void initialize(); + static void initialize(Arena* arena); static Interval* end() { return _end; } // accessors diff --git a/src/share/vm/c1/c1_Optimizer.cpp b/src/share/vm/c1/c1_Optimizer.cpp index f432e4de39ca21b78a4f8847eae6b5b60f172b60..fd5ddd53eab4294ac7c29ac322932308a2c477e3 100644 --- a/src/share/vm/c1/c1_Optimizer.cpp +++ b/src/share/vm/c1/c1_Optimizer.cpp @@ -437,11 +437,8 @@ public: // 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 @@ class NullCheckEliminator { // 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_ProfileCall (ProfileCall* x) { nce()->clear_las 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_all() { 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 @@ void NullCheckEliminator::iterate_one(BlockBegin* block) { 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 --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp index 7db7841c64c7de2360496454c0a4cfb2a9ca5249..b157987dada540ac7b894ea4efcf0929aff20afe 100644 --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -60,7 +60,6 @@ void StubAssembler::set_num_rt_args(int args) { // 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_array_store_exception_count = 0; 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 @@ static void deopt_caller() { } -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::generate_blob_for(StubID id) { } -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 } +#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 --git a/src/share/vm/c1/c1_Runtime1.hpp b/src/share/vm/c1/c1_Runtime1.hpp index aed47055a115b88fc0e0f59f8c1879d902762376..c2c589cc791864f02ecc2b875828b8465fe387f2 100644 --- a/src/share/vm/c1/c1_Runtime1.hpp +++ b/src/share/vm/c1/c1_Runtime1.hpp @@ -70,18 +70,6 @@ class StubAssembler; 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 @@ class Runtime1: public AllStatic { #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 @@ class Runtime1: public AllStatic { 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 --git a/src/share/vm/c1/c1_ValueStack.cpp b/src/share/vm/c1/c1_ValueStack.cpp index 1e08e04f43d377ed663080038ad311a4e3e7cd7d..261176507b39123c161fdc23b4dfaab474689ab4 100644 --- a/src/share/vm/c1/c1_ValueStack.cpp +++ b/src/share/vm/c1/c1_ValueStack.cpp @@ -119,14 +119,14 @@ void ValueStack::pin_stack_for_linear_scan() { // 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::apply(Values list, void f(Value*)) { } -void ValueStack::values_do(void f(Value*)) { +void ValueStack::values_do(ValueVisitor* f) { apply(_stack, f); apply(_locks, f); diff --git a/src/share/vm/c1/c1_ValueStack.hpp b/src/share/vm/c1/c1_ValueStack.hpp index 3aaca56b4a89c2c2bc3197f06fb3fe06c8758f75..9e254bf0dcdbf08da81fa0a2bfc422b0f7b65275 100644 --- a/src/share/vm/c1/c1_ValueStack.hpp +++ b/src/share/vm/c1/c1_ValueStack.hpp @@ -41,7 +41,7 @@ class ValueStack: public CompilationResourceObj { } // helper routine - static void apply(Values list, void f(Value*)); + static void apply(Values list, ValueVisitor* f); public: // creation @@ -143,7 +143,7 @@ class ValueStack: public CompilationResourceObj { 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 --git a/src/share/vm/c1/c1_ValueType.cpp b/src/share/vm/c1/c1_ValueType.cpp index 94fb7d2b02839c5527dbf9e2104500dd1536ce3b..24a2083d07c321e139d113f8963f6ca89ba51245 100644 --- a/src/share/vm/c1/c1_ValueType.cpp +++ b/src/share/vm/c1/c1_ValueType.cpp @@ -46,27 +46,26 @@ IntConstant* intOne = NULL; 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(); - - // constants - intZero = new IntConstant(0); - intOne = new IntConstant(1); - objectNull = new ObjectConstant(ciNullObject::make()); + 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(); + + intZero = new (arena) IntConstant(0); + intOne = new (arena) IntConstant(1); + objectNull = new (arena) ObjectConstant(ciNullObject::make()); }; diff --git a/src/share/vm/c1/c1_ValueType.hpp b/src/share/vm/c1/c1_ValueType.hpp index 001df60be59d1b8c5128c78a48ae557faa3ff855..3098114cf95f936f13d23542199eee91f92533e4 100644 --- a/src/share/vm/c1/c1_ValueType.hpp +++ b/src/share/vm/c1/c1_ValueType.hpp @@ -94,7 +94,7 @@ class ValueType: public CompilationResourceObj { 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 --git a/src/share/vm/includeDB_compiler1 b/src/share/vm/includeDB_compiler1 index 3e3b0e9c6ff35d6040a9a313668ab1aceba492a6..302bcc596001d3ad98f65e6e224622a78c2f2456 100644 --- a/src/share/vm/includeDB_compiler1 +++ b/src/share/vm/includeDB_compiler1 @@ -71,8 +71,8 @@ c1_Compilation.cpp c1_LinearScan.hpp 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 arguments.hpp 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 --git a/src/share/vm/opto/superword.cpp b/src/share/vm/opto/superword.cpp index 248319382f6ec7fbc01035e03a89c260d049e281..be93c15ea8b5fbb7bfec1f5373f8194b6200cefb 100644 --- a/src/share/vm/opto/superword.cpp +++ b/src/share/vm/opto/superword.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -514,6 +514,13 @@ bool SuperWord::exists_at(Node* s, uint pos) { bool SuperWord::are_adjacent_refs(Node* s1, Node* s2) { if (!s1->is_Mem() || !s2->is_Mem()) return false; if (!in_bb(s1) || !in_bb(s2)) return false; + + // Do not use superword for non-primitives + if (!is_java_primitive(s1->as_Mem()->memory_type()) || + !is_java_primitive(s2->as_Mem()->memory_type())) { + return false; + } + // FIXME - co_locate_pack fails on Stores in different mem-slices, so // only pack memops that are in the same alias set until that's fixed. if (_phase->C->get_alias_index(s1->as_Mem()->adr_type()) != diff --git a/src/share/vm/runtime/mutexLocker.cpp b/src/share/vm/runtime/mutexLocker.cpp index 0941aedf61f5231f7d332ce127f85beea3647c14..71cbc7718568c0f899f781c1bd77218b0105112b 100644 --- a/src/share/vm/runtime/mutexLocker.cpp +++ b/src/share/vm/runtime/mutexLocker.cpp @@ -82,9 +82,6 @@ Mutex* EvacFailureStack_lock = NULL; 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 @@ void mutex_init() { 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 --git a/src/share/vm/runtime/mutexLocker.hpp b/src/share/vm/runtime/mutexLocker.hpp index 2d29d1f4dd5b587dc36d33cb93b490d7b5ddda50..08083f5a19ed623f1d01bfff26f35674c115c41b 100644 --- a/src/share/vm/runtime/mutexLocker.hpp +++ b/src/share/vm/runtime/mutexLocker.hpp @@ -84,9 +84,6 @@ extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare) 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 --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index b5b4f6e606993057ce9a9fe6be6d70fc7616ab5b..5527173edf9a9686b615d5cc88cc628436c3ad89 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -2799,6 +2799,7 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters) _task = NULL; _queue = queue; _counters = counters; + _buffer_blob = NULL; #ifndef PRODUCT _ideal_graph_printer = NULL; diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index fa56662118480c37276628eb22d420d8ff4849ce..901c7f7ff678b4068ae4b0cc50d439230b62f795 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -1577,6 +1577,7 @@ class CompilerThread : public JavaThread { CompileLog* _log; CompileTask* _task; CompileQueue* _queue; + BufferBlob* _buffer_blob; public: @@ -1595,6 +1596,9 @@ class CompilerThread : public JavaThread { 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) { diff --git a/test/compiler/6958485/Test.java b/test/compiler/6958485/Test.java new file mode 100644 index 0000000000000000000000000000000000000000..0bbc1ec62853e31bfaffe68f1727cfe2dd33db65 --- /dev/null +++ b/test/compiler/6958485/Test.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 6958485 + * @summary fix for 6879921 was insufficient + * + * @run main/othervm -Xbatch -XX:CompileOnly=Test.init Test + */ + +public class Test { + + public static void init(Object src[], boolean[] dst) { + // initialize the arrays + for (int i =0; i