提交 1a229f8a 编写于 作者: I iveresov

6958292: C1: Enable parallel compilation

Summary: Enable parallel compilation in C1
Reviewed-by: never, kvn
上级 21b0475a
...@@ -181,8 +181,8 @@ bool FrameMap::is_caller_save_register (Register r) { ...@@ -181,8 +181,8 @@ bool FrameMap::is_caller_save_register (Register r) {
} }
void FrameMap::init () { void FrameMap::initialize() {
if (_init_done) return; assert(!_init_done, "once");
int i=0; int i=0;
// Register usage: // Register usage:
......
...@@ -136,8 +136,8 @@ XMMRegister FrameMap::nr2xmmreg(int rnr) { ...@@ -136,8 +136,8 @@ XMMRegister FrameMap::nr2xmmreg(int rnr) {
// FrameMap // FrameMap
//-------------------------------------------------------- //--------------------------------------------------------
void FrameMap::init() { void FrameMap::initialize() {
if (_init_done) return; assert(!_init_done, "once");
assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers"); 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); map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0);
......
...@@ -26,9 +26,11 @@ ...@@ -26,9 +26,11 @@
#include "incls/_c1_Canonicalizer.cpp.incl" #include "incls/_c1_Canonicalizer.cpp.incl"
static void do_print_value(Value* vp) { class PrintValueVisitor: public ValueVisitor {
(*vp)->print_line(); void visit(Value* vp) {
} (*vp)->print_line();
}
};
void Canonicalizer::set_canonical(Value x) { void Canonicalizer::set_canonical(Value x) {
assert(x != NULL, "value must exist"); assert(x != NULL, "value must exist");
...@@ -37,10 +39,11 @@ void Canonicalizer::set_canonical(Value x) { ...@@ -37,10 +39,11 @@ void Canonicalizer::set_canonical(Value x) {
// in the instructions). // in the instructions).
if (canonical() != x) { if (canonical() != x) {
if (PrintCanonicalization) { if (PrintCanonicalization) {
canonical()->input_values_do(do_print_value); PrintValueVisitor do_print_value;
canonical()->input_values_do(&do_print_value);
canonical()->print_line(); canonical()->print_line();
tty->print_cr("canonicalized to:"); tty->print_cr("canonicalized to:");
x->input_values_do(do_print_value); x->input_values_do(&do_print_value);
x->print_line(); x->print_line();
tty->cr(); tty->cr();
} }
...@@ -202,7 +205,7 @@ void Canonicalizer::do_StoreField (StoreField* x) { ...@@ -202,7 +205,7 @@ void Canonicalizer::do_StoreField (StoreField* x) {
// limit this optimization to current block // limit this optimization to current block
if (value != NULL && in_current_block(conv)) { if (value != NULL && in_current_block(conv)) {
set_canonical(new StoreField(x->obj(), x->offset(), x->field(), value, x->is_static(), 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; return;
} }
} }
......
...@@ -66,9 +66,6 @@ class PhaseTraceTime: public TraceTime { ...@@ -66,9 +66,6 @@ class PhaseTraceTime: public TraceTime {
} }
}; };
Arena* Compilation::_arena = NULL;
Compilation* Compilation::_compilation = NULL;
// Implementation of Compilation // Implementation of Compilation
...@@ -238,9 +235,23 @@ void Compilation::emit_code_epilog(LIR_Assembler* assembler) { ...@@ -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() { int Compilation::emit_code_body() {
// emit code // emit code
Runtime1::setup_code_buffer(code(), allocator()->num_calls()); setup_code_buffer(code(), allocator()->num_calls());
code()->initialize_oop_recorder(env()->oop_recorder()); code()->initialize_oop_recorder(env()->oop_recorder());
_masm = new C1_MacroAssembler(code()); _masm = new C1_MacroAssembler(code());
...@@ -422,7 +433,8 @@ void Compilation::generate_exception_handler_table() { ...@@ -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) : _compiler(compiler)
, _env(env) , _env(env)
, _method(method) , _method(method)
...@@ -437,8 +449,10 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho ...@@ -437,8 +449,10 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
, _bailout_msg(NULL) , _bailout_msg(NULL)
, _exception_info_list(NULL) , _exception_info_list(NULL)
, _allocator(NULL) , _allocator(NULL)
, _code(Runtime1::get_buffer_blob()->instructions_begin(), , _next_id(0)
Runtime1::get_buffer_blob()->instructions_size()) , _next_block_id(0)
, _code(buffer_blob->instructions_begin(),
buffer_blob->instructions_size())
, _current_instruction(NULL) , _current_instruction(NULL)
#ifndef PRODUCT #ifndef PRODUCT
, _last_instruction_printed(NULL) , _last_instruction_printed(NULL)
...@@ -446,17 +460,15 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho ...@@ -446,17 +460,15 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
{ {
PhaseTraceTime timeit(_t_compile); PhaseTraceTime timeit(_t_compile);
assert(_arena == NULL, "shouldn't only one instance of Compilation in existence at a time");
_arena = Thread::current()->resource_area(); _arena = Thread::current()->resource_area();
_compilation = this; _env->set_compiler_data(this);
_exception_info_list = new ExceptionInfoList(); _exception_info_list = new ExceptionInfoList();
_implicit_exception_table.set_size(0); _implicit_exception_table.set_size(0);
compile_method(); compile_method();
} }
Compilation::~Compilation() { Compilation::~Compilation() {
_arena = NULL; _env->set_compiler_data(NULL);
_compilation = NULL;
} }
......
...@@ -53,15 +53,11 @@ define_stack(ExceptionInfoList, ExceptionInfoArray) ...@@ -53,15 +53,11 @@ define_stack(ExceptionInfoList, ExceptionInfoArray)
class Compilation: public StackObj { class Compilation: public StackObj {
friend class CompilationResourceObj; friend class CompilationResourceObj;
private:
static Arena* _arena;
static Arena* arena() { return _arena; }
static Compilation* _compilation;
private: private:
// compilation specifics // compilation specifics
Arena* _arena;
int _next_id;
int _next_block_id;
AbstractCompiler* _compiler; AbstractCompiler* _compiler;
ciEnv* _env; ciEnv* _env;
ciMethod* _method; ciMethod* _method;
...@@ -108,10 +104,14 @@ class Compilation: public StackObj { ...@@ -108,10 +104,14 @@ class Compilation: public StackObj {
public: public:
// creation // 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(); ~Compilation();
static Compilation* current_compilation() { return _compilation; }
static Compilation* current() {
return (Compilation*) ciEnv::current()->compiler_data();
}
// accessors // accessors
ciEnv* env() const { return _env; } ciEnv* env() const { return _env; }
...@@ -128,6 +128,15 @@ class Compilation: public StackObj { ...@@ -128,6 +128,15 @@ class Compilation: public StackObj {
CodeBuffer* code() { return &_code; } CodeBuffer* code() { return &_code; }
C1_MacroAssembler* masm() const { return _masm; } C1_MacroAssembler* masm() const { return _masm; }
CodeOffsets* offsets() { return &_offsets; } 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 // setters
void set_has_exception_handlers(bool f) { _has_exception_handlers = f; } void set_has_exception_handlers(bool f) { _has_exception_handlers = f; }
...@@ -158,6 +167,15 @@ class Compilation: public StackObj { ...@@ -158,6 +167,15 @@ class Compilation: public StackObj {
bool bailed_out() const { return _bailout_msg != NULL; } bool bailed_out() const { return _bailout_msg != NULL; }
const char* bailout_msg() const { return _bailout_msg; } 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 // timers
static void print_timers(); static void print_timers();
...@@ -203,7 +221,10 @@ class InstructionMark: public StackObj { ...@@ -203,7 +221,10 @@ class InstructionMark: public StackObj {
// Base class for objects allocated by the compiler in the compilation arena // Base class for objects allocated by the compiler in the compilation arena
class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC { class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC {
public: 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 void operator delete(void* p) {} // nothing to do
}; };
......
...@@ -27,9 +27,6 @@ ...@@ -27,9 +27,6 @@
volatile int Compiler::_runtimes = uninitialized; volatile int Compiler::_runtimes = uninitialized;
volatile bool Compiler::_compiling = false;
Compiler::Compiler() { Compiler::Compiler() {
} }
...@@ -39,47 +36,62 @@ 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() { void Compiler::initialize() {
if (_runtimes != initialized) { if (_runtimes != initialized) {
initialize_runtimes( Runtime1::initialize, &_runtimes); initialize_runtimes( initialize_all, &_runtimes);
} }
mark_initialized(); 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) { 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()) { if (!is_initialized()) {
initialize(); initialize();
} }
// invoke compilation // 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 // We are nested here because we need for the destructor
// of Compilation to occur before we release the any // of Compilation to occur before we release the any
// competing compiler thread // competing compiler thread
ResourceMark rm; 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
} }
......
...@@ -31,10 +31,6 @@ class Compiler: public AbstractCompiler { ...@@ -31,10 +31,6 @@ class Compiler: public AbstractCompiler {
// Tracks whether runtime has been initialized // Tracks whether runtime has been initialized
static volatile int _runtimes; 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: public:
// Creation // Creation
Compiler(); Compiler();
...@@ -47,6 +43,7 @@ class Compiler: public AbstractCompiler { ...@@ -47,6 +43,7 @@ class Compiler: public AbstractCompiler {
virtual bool is_c1() { return true; }; virtual bool is_c1() { return true; };
#endif // TIERED #endif // TIERED
BufferBlob* build_buffer_blob();
// Missing feature tests // Missing feature tests
virtual bool supports_native() { return true; } virtual bool supports_native() { return true; }
...@@ -58,6 +55,7 @@ class Compiler: public AbstractCompiler { ...@@ -58,6 +55,7 @@ class Compiler: public AbstractCompiler {
// Initialization // Initialization
virtual void initialize(); virtual void initialize();
static void initialize_all();
// Compilation entry point for methods // Compilation entry point for methods
virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
......
...@@ -153,7 +153,7 @@ int FrameMap::_cpu_reg2rnr [FrameMap::nof_cpu_regs]; ...@@ -153,7 +153,7 @@ int FrameMap::_cpu_reg2rnr [FrameMap::nof_cpu_regs];
FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) { FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) {
if (!_init_done) init(); assert(_init_done, "should already be completed");
_framesize = -1; _framesize = -1;
_num_spills = -1; _num_spills = -1;
......
...@@ -235,7 +235,7 @@ class FrameMap : public CompilationResourceObj { ...@@ -235,7 +235,7 @@ class FrameMap : public CompilationResourceObj {
return _caller_save_fpu_regs[i]; return _caller_save_fpu_regs[i];
} }
static void init(); static void initialize();
}; };
// CallingConvention // CallingConvention
......
...@@ -2530,16 +2530,10 @@ void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) ...@@ -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::_can_trap [Bytecodes::number_of_java_codes];
bool GraphBuilder::_is_async[Bytecodes::number_of_java_codes]; bool GraphBuilder::_is_async[Bytecodes::number_of_java_codes];
void GraphBuilder::initialize() { 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 // the following bytecodes are assumed to potentially
// throw exceptions in compiled code - note that e.g. // throw exceptions in compiled code - note that e.g.
// monitorexit & the return bytecodes do not throw // monitorexit & the return bytecodes do not throw
...@@ -2855,7 +2849,6 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope) ...@@ -2855,7 +2849,6 @@ GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
BlockList* bci2block = blm.bci2block(); BlockList* bci2block = blm.bci2block();
BlockBegin* start_block = bci2block->at(0); BlockBegin* start_block = bci2block->at(0);
assert(is_initialized(), "GraphBuilder must have been initialized");
push_root_scope(scope, bci2block, start_block); push_root_scope(scope, bci2block, start_block);
// setup state for std entry // setup state for std entry
......
...@@ -162,7 +162,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { ...@@ -162,7 +162,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
}; };
// for all GraphBuilders // 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 _can_trap[Bytecodes::number_of_java_codes];
static bool _is_async[Bytecodes::number_of_java_codes]; static bool _is_async[Bytecodes::number_of_java_codes];
...@@ -268,7 +267,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC { ...@@ -268,7 +267,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
Instruction* append_split(StateSplit* instr); Instruction* append_split(StateSplit* instr);
// other helpers // other helpers
static bool is_initialized() { return _is_initialized; }
static bool is_async(Bytecodes::Code code) { static bool is_async(Bytecodes::Code code) {
assert(0 <= code && code < Bytecodes::number_of_java_codes, "illegal bytecode"); assert(0 <= code && code < Bytecodes::number_of_java_codes, "illegal bytecode");
return _is_async[code]; return _is_async[code];
......
...@@ -287,11 +287,6 @@ void CodeEmitInfo::add_register_oop(LIR_Opr opr) { ...@@ -287,11 +287,6 @@ void CodeEmitInfo::add_register_oop(LIR_Opr opr) {
IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) : IR::IR(Compilation* compilation, ciMethod* method, int osr_bci) :
_locals_size(in_WordSize(-1)) _locals_size(in_WordSize(-1))
, _num_loops(0) { , _num_loops(0) {
// initialize data structures
ValueType::initialize();
Instruction::initialize();
BlockBegin::initialize();
GraphBuilder::initialize();
// setup IR fields // setup IR fields
_compilation = compilation; _compilation = compilation;
_top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true); _top_scope = new IRScope(compilation, NULL, -1, method, osr_bci, true);
...@@ -381,15 +376,15 @@ void IR::split_critical_edges() { ...@@ -381,15 +376,15 @@ void IR::split_critical_edges() {
} }
class UseCountComputer: public AllStatic { class UseCountComputer: public ValueVisitor, BlockClosure {
private: private:
static void update_use_count(Value* n) { void visit(Value* n) {
// Local instructions and Phis for expression stack values at the // Local instructions and Phis for expression stack values at the
// start of basic blocks are not added to the instruction list // start of basic blocks are not added to the instruction list
if ((*n)->bci() == -99 && (*n)->as_Local() == NULL && if ((*n)->bci() == -99 && (*n)->as_Local() == NULL &&
(*n)->as_Phi() == NULL) { (*n)->as_Phi() == NULL) {
assert(false, "a node was not appended to the graph"); 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 // use n's input if not visited before
if (!(*n)->is_pinned() && !(*n)->has_uses()) { if (!(*n)->is_pinned() && !(*n)->has_uses()) {
...@@ -402,31 +397,31 @@ class UseCountComputer: public AllStatic { ...@@ -402,31 +397,31 @@ class UseCountComputer: public AllStatic {
(*n)->_use_count++; (*n)->_use_count++;
} }
static Values* worklist; Values* worklist;
static int depth; int depth;
enum { enum {
max_recurse_depth = 20 max_recurse_depth = 20
}; };
static void uses_do(Value* n) { void uses_do(Value* n) {
depth++; depth++;
if (depth > max_recurse_depth) { if (depth > max_recurse_depth) {
// don't allow the traversal to recurse too deeply // don't allow the traversal to recurse too deeply
worklist->push(*n); worklist->push(*n);
} else { } else {
(*n)->input_values_do(update_use_count); (*n)->input_values_do(this);
// special handling for some instructions // special handling for some instructions
if ((*n)->as_BlockEnd() != NULL) { if ((*n)->as_BlockEnd() != NULL) {
// note on BlockEnd: // note on BlockEnd:
// must 'use' the stack only if the method doesn't // must 'use' the stack only if the method doesn't
// terminate, however, in those cases stack is empty // terminate, however, in those cases stack is empty
(*n)->state_values_do(update_use_count); (*n)->state_values_do(this);
} }
} }
depth--; depth--;
} }
static void basic_compute_use_count(BlockBegin* b) { void block_do(BlockBegin* b) {
depth = 0; depth = 0;
// process all pinned nodes as the roots of expression trees // process all pinned nodes as the roots of expression trees
for (Instruction* n = b; n != NULL; n = n->next()) { for (Instruction* n = b; n != NULL; n = n->next()) {
...@@ -449,18 +444,19 @@ class UseCountComputer: public AllStatic { ...@@ -449,18 +444,19 @@ class UseCountComputer: public AllStatic {
assert(depth == 0, "should have counted back down"); assert(depth == 0, "should have counted back down");
} }
UseCountComputer() {
worklist = new Values();
depth = 0;
}
public: public:
static void compute(BlockList* blocks) { static void compute(BlockList* blocks) {
worklist = new Values(); UseCountComputer ucc;
blocks->blocks_do(basic_compute_use_count); blocks->iterate_backward(&ucc);
worklist = NULL;
} }
}; };
Values* UseCountComputer::worklist = NULL;
int UseCountComputer::depth = 0;
// helper macro for short definition of trace-output inside code // helper macro for short definition of trace-output inside code
#ifndef PRODUCT #ifndef PRODUCT
#define TRACE_LINEAR_SCAN(level, code) \ #define TRACE_LINEAR_SCAN(level, code) \
...@@ -1302,7 +1298,7 @@ void IR::verify() { ...@@ -1302,7 +1298,7 @@ void IR::verify() {
#endif // PRODUCT #endif // PRODUCT
void SubstitutionResolver::substitute(Value* v) { void SubstitutionResolver::visit(Value* v) {
Value v0 = *v; Value v0 = *v;
if (v0) { if (v0) {
Value vs = v0->subst(); Value vs = v0->subst();
...@@ -1313,20 +1309,22 @@ void SubstitutionResolver::substitute(Value* v) { ...@@ -1313,20 +1309,22 @@ void SubstitutionResolver::substitute(Value* v) {
} }
#ifdef ASSERT #ifdef ASSERT
void check_substitute(Value* v) { class SubstitutionChecker: public ValueVisitor {
Value v0 = *v; void visit(Value* v) {
if (v0) { Value v0 = *v;
Value vs = v0->subst(); if (v0) {
assert(vs == v0, "missed substitution"); Value vs = v0->subst();
assert(vs == v0, "missed substitution");
}
} }
} };
#endif #endif
void SubstitutionResolver::block_do(BlockBegin* block) { void SubstitutionResolver::block_do(BlockBegin* block) {
Instruction* last = NULL; Instruction* last = NULL;
for (Instruction* n = block; n != NULL;) { for (Instruction* n = block; n != NULL;) {
n->values_do(substitute); n->values_do(this);
// need to remove this instruction from the instruction stream // need to remove this instruction from the instruction stream
if (n->subst() != n) { if (n->subst() != n) {
assert(last != NULL, "must have last"); assert(last != NULL, "must have last");
...@@ -1338,8 +1336,9 @@ void SubstitutionResolver::block_do(BlockBegin* block) { ...@@ -1338,8 +1336,9 @@ void SubstitutionResolver::block_do(BlockBegin* block) {
} }
#ifdef ASSERT #ifdef ASSERT
if (block->state()) block->state()->values_do(check_substitute); SubstitutionChecker check_substitute;
block->block_values_do(check_substitute); if (block->state()) block->state()->values_do(&check_substitute);
if (block->end() && block->end()->state()) block->end()->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 #endif
} }
...@@ -371,8 +371,8 @@ class IR: public CompilationResourceObj { ...@@ -371,8 +371,8 @@ class IR: public CompilationResourceObj {
// instructions from the instruction list. // instructions from the instruction list.
// //
class SubstitutionResolver: public BlockClosure { class SubstitutionResolver: public BlockClosure, ValueVisitor {
static void substitute(Value* v); virtual void visit(Value* v);
public: public:
SubstitutionResolver(IR* hir) { SubstitutionResolver(IR* hir) {
......
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
// Implementation of Instruction // Implementation of Instruction
int Instruction::_next_id = 0;
#ifdef ASSERT #ifdef ASSERT
void Instruction::create_hi_word() { void Instruction::create_hi_word() {
assert(type()->is_double_word() && _hi_word == NULL, "only double word has high word"); assert(type()->is_double_word() && _hi_word == NULL, "only double word has high word");
...@@ -193,22 +191,22 @@ ciType* CheckCast::exact_type() const { ...@@ -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); 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); 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); if (lock_stack() != NULL) lock_stack()->values_do(f);
} }
// Implementation of AccessField // 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 (state_before() != NULL) state_before()->values_do(f);
if (lock_stack() != NULL) lock_stack()->values_do(f); if (lock_stack() != NULL) lock_stack()->values_do(f);
} }
...@@ -270,7 +268,7 @@ bool LogicOp::is_commutative() const { ...@@ -270,7 +268,7 @@ bool LogicOp::is_commutative() const {
// Implementation of CompareOp // 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); if (state_before() != NULL) state_before()->values_do(f);
} }
...@@ -302,12 +300,12 @@ IRScope* StateSplit::scope() const { ...@@ -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); 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); StateSplit::state_values_do(f);
if (is_set(BlockBegin::exception_entry_flag)) { if (is_set(BlockBegin::exception_entry_flag)) {
...@@ -318,13 +316,13 @@ void BlockBegin::state_values_do(void f(Value*)) { ...@@ -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); StateSplit::state_values_do(f);
_lock_stack_before->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); StateSplit::state_values_do(f);
if (lock_stack() != NULL) lock_stack()->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* ...@@ -349,8 +347,9 @@ Invoke::Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values*
assert(args != NULL, "args must exist"); assert(args != NULL, "args must exist");
#ifdef ASSERT #ifdef ASSERT
values_do(assert_value); AssertValues assert_value;
#endif // ASSERT values_do(&assert_value);
#endif
// provide an initial guess of signature size. // provide an initial guess of signature size.
_signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0)); _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* ...@@ -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); StateSplit::state_values_do(f);
if (state_before() != NULL) state_before()->values_do(f); if (state_before() != NULL) state_before()->values_do(f);
if (state() != NULL) state()->values_do(f); if (state() != NULL) state()->values_do(f);
...@@ -500,30 +499,27 @@ BlockBegin* Constant::compare(Instruction::Condition cond, Value right, ...@@ -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); if (state() != NULL) state()->values_do(f);
} }
// Implementation of NewArray // 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); if (state_before() != NULL) state_before()->values_do(f);
} }
// Implementation of TypeCheck // 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); if (state_before() != NULL) state_before()->values_do(f);
} }
// Implementation of BlockBegin // Implementation of BlockBegin
int BlockBegin::_next_block_id = 0;
void BlockBegin::set_end(BlockEnd* end) { void BlockBegin::set_end(BlockEnd* end) {
assert(end != NULL, "should not reset block end to NULL"); assert(end != NULL, "should not reset block end to NULL");
BlockEnd* old_end = _end; BlockEnd* old_end = _end;
...@@ -738,7 +734,7 @@ void BlockBegin::iterate_postorder(BlockClosure* closure) { ...@@ -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); for (Instruction* n = this; n != NULL; n = n->next()) n->values_do(f);
} }
...@@ -930,7 +926,7 @@ void BlockList::blocks_do(void f(BlockBegin*)) { ...@@ -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); 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) { ...@@ -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); if (state_before() != NULL) state_before()->values_do(f);
} }
...@@ -1012,6 +1008,6 @@ int Phi::operand_count() const { ...@@ -1012,6 +1008,6 @@ int Phi::operand_count() const {
// Implementation of Throw // Implementation of Throw
void Throw::state_values_do(void f(Value*)) { void Throw::state_values_do(ValueVisitor* f) {
BlockEnd::state_values_do(f); BlockEnd::state_values_do(f);
} }
此差异已折叠。
...@@ -304,7 +304,7 @@ void LIRGenerator::block_do_prolog(BlockBegin* block) { ...@@ -304,7 +304,7 @@ void LIRGenerator::block_do_prolog(BlockBegin* block) {
__ branch_destination(block->label()); __ branch_destination(block->label());
if (LIRTraceExecution && 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)) { !block->is_set(BlockBegin::exception_entry_flag)) {
assert(block->lir()->instructions_list()->length() == 1, "should come right after br_dst"); assert(block->lir()->instructions_list()->length() == 1, "should come right after br_dst");
trace_block_entry(block); trace_block_entry(block);
......
...@@ -84,10 +84,6 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map) ...@@ -84,10 +84,6 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map)
, _fpu_stack_allocator(NULL) , _fpu_stack_allocator(NULL)
#endif #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->ir() != NULL, "check if valid");
assert(this->compilation() != NULL, "check if valid"); assert(this->compilation() != NULL, "check if valid");
assert(this->gen() != NULL, "check if valid"); assert(this->gen() != NULL, "check if valid");
...@@ -3929,8 +3925,8 @@ Range::Range(int from, int to, Range* next) : ...@@ -3929,8 +3925,8 @@ Range::Range(int from, int to, Range* next) :
// initialize sentinel // initialize sentinel
Range* Range::_end = NULL; Range* Range::_end = NULL;
void Range::initialize() { void Range::initialize(Arena* arena) {
_end = new Range(max_jint, max_jint, NULL); _end = new (arena) Range(max_jint, max_jint, NULL);
} }
int Range::intersects_at(Range* r2) const { int Range::intersects_at(Range* r2) const {
...@@ -3976,9 +3972,9 @@ void Range::print(outputStream* out) const { ...@@ -3976,9 +3972,9 @@ void Range::print(outputStream* out) const {
// initialize sentinel // initialize sentinel
Interval* Interval::_end = NULL; Interval* Interval::_end = NULL;
void Interval::initialize() { void Interval::initialize(Arena* arena) {
Range::initialize(); Range::initialize(arena);
_end = new Interval(-1); _end = new (arena) Interval(-1);
} }
Interval::Interval(int reg_num) : Interval::Interval(int reg_num) :
......
...@@ -462,7 +462,7 @@ class Range : public CompilationResourceObj { ...@@ -462,7 +462,7 @@ class Range : public CompilationResourceObj {
public: public:
Range(int from, int to, Range* next); Range(int from, int to, Range* next);
static void initialize(); static void initialize(Arena* arena);
static Range* end() { return _end; } static Range* end() { return _end; }
int from() const { return _from; } int from() const { return _from; }
...@@ -529,7 +529,7 @@ class Interval : public CompilationResourceObj { ...@@ -529,7 +529,7 @@ class Interval : public CompilationResourceObj {
public: public:
Interval(int reg_num); Interval(int reg_num);
static void initialize(); static void initialize(Arena* arena);
static Interval* end() { return _end; } static Interval* end() { return _end; }
// accessors // accessors
......
...@@ -437,11 +437,8 @@ public: ...@@ -437,11 +437,8 @@ public:
// Because of a static contained within (for the purpose of iteration // Because of a static contained within (for the purpose of iteration
// over instructions), it is only valid to have one of these active at // over instructions), it is only valid to have one of these active at
// a time // a time
class NullCheckEliminator { class NullCheckEliminator: public ValueVisitor {
private: private:
static NullCheckEliminator* _static_nce;
static void do_value(Value* vp);
Optimizer* _opt; Optimizer* _opt;
ValueSet* _visitable_instructions; // Visit each instruction only once per basic block ValueSet* _visitable_instructions; // Visit each instruction only once per basic block
...@@ -504,6 +501,8 @@ class NullCheckEliminator { ...@@ -504,6 +501,8 @@ class NullCheckEliminator {
// Process a graph // Process a graph
void iterate(BlockBegin* root); void iterate(BlockBegin* root);
void visit(Value* f);
// In some situations (like NullCheck(x); getfield(x)) the debug // In some situations (like NullCheck(x); getfield(x)) the debug
// information from the explicit NullCheck can be used to populate // information from the explicit NullCheck can be used to populate
// the getfield, even if the two instructions are in different // the getfield, even if the two instructions are in different
...@@ -602,14 +601,11 @@ void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_las ...@@ -602,14 +601,11 @@ void NullCheckVisitor::do_ProfileCall (ProfileCall* x) { nce()->clear_las
void NullCheckVisitor::do_ProfileCounter (ProfileCounter* x) {} void NullCheckVisitor::do_ProfileCounter (ProfileCounter* x) {}
NullCheckEliminator* NullCheckEliminator::_static_nce = NULL; void NullCheckEliminator::visit(Value* p) {
void NullCheckEliminator::do_value(Value* p) {
assert(*p != NULL, "should not find NULL instructions"); assert(*p != NULL, "should not find NULL instructions");
if (_static_nce->visitable(*p)) { if (visitable(*p)) {
_static_nce->mark_visited(*p); mark_visited(*p);
(*p)->visit(&_static_nce->_visitor); (*p)->visit(&_visitor);
} }
} }
...@@ -637,7 +633,6 @@ void NullCheckEliminator::iterate_all() { ...@@ -637,7 +633,6 @@ void NullCheckEliminator::iterate_all() {
void NullCheckEliminator::iterate_one(BlockBegin* block) { void NullCheckEliminator::iterate_one(BlockBegin* block) {
_static_nce = this;
clear_visitable_state(); clear_visitable_state();
// clear out an old explicit null checks // clear out an old explicit null checks
set_last_explicit_null_check(NULL); set_last_explicit_null_check(NULL);
...@@ -712,7 +707,7 @@ void NullCheckEliminator::iterate_one(BlockBegin* block) { ...@@ -712,7 +707,7 @@ void NullCheckEliminator::iterate_one(BlockBegin* block) {
mark_visitable(instr); mark_visitable(instr);
if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) { if (instr->is_root() || instr->can_trap() || (instr->as_NullCheck() != NULL)) {
mark_visited(instr); mark_visited(instr);
instr->input_values_do(&NullCheckEliminator::do_value); instr->input_values_do(this);
instr->visit(&_visitor); instr->visit(&_visitor);
} }
} }
......
...@@ -60,7 +60,6 @@ void StubAssembler::set_num_rt_args(int args) { ...@@ -60,7 +60,6 @@ void StubAssembler::set_num_rt_args(int args) {
// Implementation of Runtime1 // Implementation of Runtime1
bool Runtime1::_is_initialized = false;
CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids]; CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids];
const char *Runtime1::_blob_names[] = { const char *Runtime1::_blob_names[] = {
RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME) RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME)
...@@ -89,8 +88,6 @@ int Runtime1::_throw_array_store_exception_count = 0; ...@@ -89,8 +88,6 @@ int Runtime1::_throw_array_store_exception_count = 0;
int Runtime1::_throw_count = 0; int Runtime1::_throw_count = 0;
#endif #endif
BufferBlob* Runtime1::_buffer_blob = NULL;
// Simple helper to see if the caller of a runtime stub which // Simple helper to see if the caller of a runtime stub which
// entered the VM has been deoptimized // entered the VM has been deoptimized
...@@ -117,43 +114,14 @@ static void deopt_caller() { ...@@ -117,43 +114,14 @@ static void deopt_caller() {
} }
BufferBlob* Runtime1::get_buffer_blob() { void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
// 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) {
assert(0 <= id && id < number_of_ids, "illegal stub id"); assert(0 <= id && id < number_of_ids, "illegal stub id");
ResourceMark rm; ResourceMark rm;
// create code buffer for code storage // create code buffer for code storage
CodeBuffer code(get_buffer_blob()->instructions_begin(), CodeBuffer code(buffer_blob->instructions_begin(),
get_buffer_blob()->instructions_size()); buffer_blob->instructions_size());
setup_code_buffer(&code, 0); Compilation::setup_code_buffer(&code, 0);
// create assembler for code generation // create assembler for code generation
StubAssembler* sasm = new StubAssembler(&code, name_for(id), id); StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
...@@ -204,35 +172,28 @@ void Runtime1::generate_blob_for(StubID id) { ...@@ -204,35 +172,28 @@ void Runtime1::generate_blob_for(StubID id) {
} }
void Runtime1::initialize() { void Runtime1::initialize(BufferBlob* blob) {
// Warning: If we have more than one compilation running in parallel, we // platform-dependent initialization
// need a lock here with the current setup (lazy initialization). initialize_pd();
if (!is_initialized()) { // generate stubs
_is_initialized = true; for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
// printing
// platform-dependent initialization
initialize_pd();
// generate stubs
for (int id = 0; id < number_of_ids; id++) generate_blob_for((StubID)id);
// printing
#ifndef PRODUCT #ifndef PRODUCT
if (PrintSimpleStubs) { if (PrintSimpleStubs) {
ResourceMark rm; ResourceMark rm;
for (int id = 0; id < number_of_ids; id++) { for (int id = 0; id < number_of_ids; id++) {
_blobs[id]->print(); _blobs[id]->print();
if (_blobs[id]->oop_maps() != NULL) { if (_blobs[id]->oop_maps() != NULL) {
_blobs[id]->oop_maps()->print(); _blobs[id]->oop_maps()->print();
}
} }
} }
#endif
} }
#endif
} }
CodeBlob* Runtime1::blob_for(StubID id) { CodeBlob* Runtime1::blob_for(StubID id) {
assert(0 <= id && id < number_of_ids, "illegal stub id"); assert(0 <= id && id < number_of_ids, "illegal stub id");
if (!is_initialized()) initialize();
return _blobs[id]; return _blobs[id];
} }
......
...@@ -70,18 +70,6 @@ class StubAssembler; ...@@ -70,18 +70,6 @@ class StubAssembler;
class Runtime1: public AllStatic { class Runtime1: public AllStatic {
friend class VMStructs; friend class VMStructs;
friend class ArrayCopyStub; 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: public:
enum StubID { enum StubID {
...@@ -115,12 +103,11 @@ class Runtime1: public AllStatic { ...@@ -115,12 +103,11 @@ class Runtime1: public AllStatic {
#endif #endif
private: private:
static bool _is_initialized;
static CodeBlob* _blobs[number_of_ids]; static CodeBlob* _blobs[number_of_ids];
static const char* _blob_names[]; static const char* _blob_names[];
// stub generation // 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_code_for(StubID id, StubAssembler* masm);
static OopMapSet* generate_exception_throw(StubAssembler* sasm, address target, bool has_argument); 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); 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 { ...@@ -162,12 +149,8 @@ class Runtime1: public AllStatic {
static void patch_code(JavaThread* thread, StubID stub_id); static void patch_code(JavaThread* thread, StubID stub_id);
public: public:
static BufferBlob* get_buffer_blob();
static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
// initialization // initialization
static bool is_initialized() { return _is_initialized; } static void initialize(BufferBlob* blob);
static void initialize();
static void initialize_pd(); static void initialize_pd();
// stubs // stubs
......
...@@ -119,14 +119,14 @@ void ValueStack::pin_stack_for_linear_scan() { ...@@ -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) // 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++) { for (int i = 0; i < list.length(); i++) {
Value* va = list.adr_at(i); Value* va = list.adr_at(i);
Value v0 = *va; Value v0 = *va;
if (v0 != NULL) { if (v0 != NULL) {
if (!v0->type()->is_illegal()) { if (!v0->type()->is_illegal()) {
assert(v0->as_HiWord() == NULL, "should never see HiWord during traversal"); assert(v0->as_HiWord() == NULL, "should never see HiWord during traversal");
f(va); f->visit(va);
#ifdef ASSERT #ifdef ASSERT
Value v1 = *va; Value v1 = *va;
if (v0 != v1) { if (v0 != v1) {
...@@ -143,7 +143,7 @@ void ValueStack::apply(Values list, void f(Value*)) { ...@@ -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(_stack, f);
apply(_locks, f); apply(_locks, f);
......
...@@ -41,7 +41,7 @@ class ValueStack: public CompilationResourceObj { ...@@ -41,7 +41,7 @@ class ValueStack: public CompilationResourceObj {
} }
// helper routine // helper routine
static void apply(Values list, void f(Value*)); static void apply(Values list, ValueVisitor* f);
public: public:
// creation // creation
...@@ -143,7 +143,7 @@ class ValueStack: public CompilationResourceObj { ...@@ -143,7 +143,7 @@ class ValueStack: public CompilationResourceObj {
void pin_stack_for_linear_scan(); void pin_stack_for_linear_scan();
// iteration // iteration
void values_do(void f(Value*)); void values_do(ValueVisitor* f);
// untyped manipulation (for dup_x1, etc.) // untyped manipulation (for dup_x1, etc.)
void clear_stack() { _stack.clear(); } void clear_stack() { _stack.clear(); }
......
...@@ -46,27 +46,26 @@ IntConstant* intOne = NULL; ...@@ -46,27 +46,26 @@ IntConstant* intOne = NULL;
ObjectConstant* objectNull = NULL; ObjectConstant* objectNull = NULL;
void ValueType::initialize() { void ValueType::initialize(Arena* arena) {
// Note: Must initialize all types for each compilation // Note: Must initialize all types for each compilation
// as they are allocated within a ResourceMark! // as they are allocated within a ResourceMark!
// types // types
voidType = new VoidType(); voidType = new (arena) VoidType();
intType = new IntType(); intType = new (arena) IntType();
longType = new LongType(); longType = new (arena) LongType();
floatType = new FloatType(); floatType = new (arena) FloatType();
doubleType = new DoubleType(); doubleType = new (arena) DoubleType();
objectType = new ObjectType(); objectType = new (arena) ObjectType();
arrayType = new ArrayType(); arrayType = new (arena) ArrayType();
instanceType = new InstanceType(); instanceType = new (arena) InstanceType();
classType = new ClassType(); classType = new (arena) ClassType();
addressType = new AddressType(); addressType = new (arena) AddressType();
illegalType = new IllegalType(); illegalType = new (arena) IllegalType();
// constants intZero = new (arena) IntConstant(0);
intZero = new IntConstant(0); intOne = new (arena) IntConstant(1);
intOne = new IntConstant(1); objectNull = new (arena) ObjectConstant(ciNullObject::make());
objectNull = new ObjectConstant(ciNullObject::make());
}; };
......
...@@ -94,7 +94,7 @@ class ValueType: public CompilationResourceObj { ...@@ -94,7 +94,7 @@ class ValueType: public CompilationResourceObj {
public: public:
// initialization // initialization
static void initialize(); static void initialize(Arena* arena);
// accessors // accessors
virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant) virtual ValueType* base() const = 0; // the 'canonical' type (e.g., intType for an IntConstant)
......
...@@ -71,8 +71,8 @@ c1_Compilation.cpp c1_LinearScan.hpp ...@@ -71,8 +71,8 @@ c1_Compilation.cpp c1_LinearScan.hpp
c1_Compilation.cpp c1_MacroAssembler.hpp c1_Compilation.cpp c1_MacroAssembler.hpp
c1_Compilation.cpp c1_ValueMap.hpp c1_Compilation.cpp c1_ValueMap.hpp
c1_Compilation.cpp c1_ValueStack.hpp c1_Compilation.cpp c1_ValueStack.hpp
c1_Compilation.cpp ciEnv.hpp
c1_Compilation.cpp debugInfoRec.hpp c1_Compilation.cpp debugInfoRec.hpp
c1_Compilation.hpp ciEnv.hpp
c1_Compilation.hpp exceptionHandlerTable.hpp c1_Compilation.hpp exceptionHandlerTable.hpp
c1_Compilation.hpp resourceArea.hpp c1_Compilation.hpp resourceArea.hpp
...@@ -82,6 +82,8 @@ c1_Compiler.cpp arguments.hpp ...@@ -82,6 +82,8 @@ c1_Compiler.cpp arguments.hpp
c1_Compiler.cpp c1_Compilation.hpp c1_Compiler.cpp c1_Compilation.hpp
c1_Compiler.cpp c1_Compiler.hpp c1_Compiler.cpp c1_Compiler.hpp
c1_Compiler.cpp c1_FrameMap.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_MacroAssembler.hpp
c1_Compiler.cpp c1_Runtime1.hpp c1_Compiler.cpp c1_Runtime1.hpp
c1_Compiler.cpp c1_ValueType.hpp c1_Compiler.cpp c1_ValueType.hpp
......
...@@ -82,9 +82,6 @@ Mutex* EvacFailureStack_lock = NULL; ...@@ -82,9 +82,6 @@ Mutex* EvacFailureStack_lock = NULL;
Mutex* DerivedPointerTableGC_lock = NULL; Mutex* DerivedPointerTableGC_lock = NULL;
Mutex* Compile_lock = NULL; Mutex* Compile_lock = NULL;
Monitor* MethodCompileQueue_lock = NULL; Monitor* MethodCompileQueue_lock = NULL;
#ifdef TIERED
Monitor* C1_lock = NULL;
#endif // TIERED
Monitor* CompileThread_lock = NULL; Monitor* CompileThread_lock = NULL;
Mutex* CompileTaskAlloc_lock = NULL; Mutex* CompileTaskAlloc_lock = NULL;
Mutex* CompileStatistics_lock = NULL; Mutex* CompileStatistics_lock = NULL;
...@@ -255,11 +252,6 @@ void mutex_init() { ...@@ -255,11 +252,6 @@ void mutex_init() {
def(Debug3_lock , Mutex , nonleaf+4, true ); def(Debug3_lock , Mutex , nonleaf+4, true );
def(ProfileVM_lock , Monitor, nonleaf+4, false); // used for profiling of the VMThread def(ProfileVM_lock , Monitor, nonleaf+4, false); // used for profiling of the VMThread
def(CompileThread_lock , Monitor, nonleaf+5, false ); def(CompileThread_lock , Monitor, nonleaf+5, false );
#ifdef TIERED
def(C1_lock , Monitor, nonleaf+5, false );
#endif // TIERED
} }
GCMutexLocker::GCMutexLocker(Monitor * mutex) { GCMutexLocker::GCMutexLocker(Monitor * mutex) {
......
...@@ -84,9 +84,6 @@ extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare) ...@@ -84,9 +84,6 @@ extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare)
extern Mutex* EvacFailureStack_lock; // guards the evac failure scan stack 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 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 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 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* CompileTaskAlloc_lock; // a lock held when CompileTasks are allocated
extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics extern Mutex* CompileStatistics_lock; // a lock held when updating compilation statistics
......
...@@ -2797,6 +2797,7 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters) ...@@ -2797,6 +2797,7 @@ CompilerThread::CompilerThread(CompileQueue* queue, CompilerCounters* counters)
_task = NULL; _task = NULL;
_queue = queue; _queue = queue;
_counters = counters; _counters = counters;
_buffer_blob = NULL;
#ifndef PRODUCT #ifndef PRODUCT
_ideal_graph_printer = NULL; _ideal_graph_printer = NULL;
......
...@@ -1576,6 +1576,7 @@ class CompilerThread : public JavaThread { ...@@ -1576,6 +1576,7 @@ class CompilerThread : public JavaThread {
CompileLog* _log; CompileLog* _log;
CompileTask* _task; CompileTask* _task;
CompileQueue* _queue; CompileQueue* _queue;
BufferBlob* _buffer_blob;
public: public:
...@@ -1594,6 +1595,9 @@ class CompilerThread : public JavaThread { ...@@ -1594,6 +1595,9 @@ class CompilerThread : public JavaThread {
ciEnv* env() { return _env; } ciEnv* env() { return _env; }
void set_env(ciEnv* env) { _env = 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 // Get/set the thread's logging information
CompileLog* log() { return _log; } CompileLog* log() { return _log; }
void init_log(CompileLog* log) { void init_log(CompileLog* log) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册