duke@435: /* trims@1907: * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: duke@435: class BlockBegin; duke@435: class CompilationResourceObj; duke@435: class XHandlers; duke@435: class ExceptionInfo; duke@435: class DebugInformationRecorder; duke@435: class FrameMap; duke@435: class IR; duke@435: class IRScope; duke@435: class Instruction; duke@435: class LinearScan; duke@435: class OopMap; duke@435: class LIR_Emitter; duke@435: class LIR_Assembler; duke@435: class CodeEmitInfo; duke@435: class ciEnv; duke@435: class ciMethod; duke@435: class ValueStack; duke@435: class LIR_OprDesc; duke@435: class C1_MacroAssembler; duke@435: class CFGPrinter; duke@435: typedef LIR_OprDesc* LIR_Opr; duke@435: duke@435: duke@435: define_array(BasicTypeArray, BasicType) duke@435: define_stack(BasicTypeList, BasicTypeArray) duke@435: duke@435: define_array(ExceptionInfoArray, ExceptionInfo*) duke@435: define_stack(ExceptionInfoList, ExceptionInfoArray) duke@435: duke@435: class Compilation: public StackObj { duke@435: friend class CompilationResourceObj; duke@435: private: duke@435: // compilation specifics iveresov@1939: Arena* _arena; iveresov@1939: int _next_id; iveresov@1939: int _next_block_id; duke@435: AbstractCompiler* _compiler; duke@435: ciEnv* _env; duke@435: ciMethod* _method; duke@435: int _osr_bci; duke@435: IR* _hir; duke@435: int _max_spills; duke@435: FrameMap* _frame_map; duke@435: C1_MacroAssembler* _masm; duke@435: bool _has_exception_handlers; duke@435: bool _has_fpu_code; duke@435: bool _has_unsafe_access; duke@435: const char* _bailout_msg; duke@435: ExceptionInfoList* _exception_info_list; duke@435: ExceptionHandlerTable _exception_handler_table; duke@435: ImplicitExceptionTable _implicit_exception_table; duke@435: LinearScan* _allocator; duke@435: CodeOffsets _offsets; duke@435: CodeBuffer _code; duke@435: duke@435: // compilation helpers duke@435: void initialize(); duke@435: void build_hir(); duke@435: void emit_lir(); duke@435: duke@435: void emit_code_epilog(LIR_Assembler* assembler); duke@435: int emit_code_body(); duke@435: duke@435: int compile_java_method(); duke@435: void install_code(int frame_size); duke@435: void compile_method(); duke@435: duke@435: void generate_exception_handler_table(); duke@435: duke@435: ExceptionInfoList* exception_info_list() const { return _exception_info_list; } duke@435: ExceptionHandlerTable* exception_handler_table() { return &_exception_handler_table; } duke@435: duke@435: LinearScan* allocator() { return _allocator; } duke@435: void set_allocator(LinearScan* allocator) { _allocator = allocator; } duke@435: duke@435: Instruction* _current_instruction; // the instruction currently being processed duke@435: #ifndef PRODUCT duke@435: Instruction* _last_instruction_printed; // the last instruction printed during traversal duke@435: #endif // PRODUCT duke@435: duke@435: public: duke@435: // creation iveresov@1939: Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method, iveresov@1939: int osr_bci, BufferBlob* buffer_blob); duke@435: ~Compilation(); duke@435: iveresov@1939: iveresov@1939: static Compilation* current() { iveresov@1939: return (Compilation*) ciEnv::current()->compiler_data(); iveresov@1939: } duke@435: duke@435: // accessors duke@435: ciEnv* env() const { return _env; } duke@435: AbstractCompiler* compiler() const { return _compiler; } duke@435: bool has_exception_handlers() const { return _has_exception_handlers; } duke@435: bool has_fpu_code() const { return _has_fpu_code; } duke@435: bool has_unsafe_access() const { return _has_unsafe_access; } duke@435: ciMethod* method() const { return _method; } duke@435: int osr_bci() const { return _osr_bci; } duke@435: bool is_osr_compile() const { return osr_bci() >= 0; } duke@435: IR* hir() const { return _hir; } duke@435: int max_spills() const { return _max_spills; } duke@435: FrameMap* frame_map() const { return _frame_map; } duke@435: CodeBuffer* code() { return &_code; } duke@435: C1_MacroAssembler* masm() const { return _masm; } duke@435: CodeOffsets* offsets() { return &_offsets; } iveresov@1939: Arena* arena() { return _arena; } iveresov@1939: iveresov@1939: // Instruction ids iveresov@1939: int get_next_id() { return _next_id++; } iveresov@1939: int number_of_instructions() const { return _next_id; } iveresov@1939: iveresov@1939: // BlockBegin ids iveresov@1939: int get_next_block_id() { return _next_block_id++; } iveresov@1939: int number_of_blocks() const { return _next_block_id; } duke@435: duke@435: // setters duke@435: void set_has_exception_handlers(bool f) { _has_exception_handlers = f; } duke@435: void set_has_fpu_code(bool f) { _has_fpu_code = f; } duke@435: void set_has_unsafe_access(bool f) { _has_unsafe_access = f; } duke@435: // Add a set of exception handlers covering the given PC offset duke@435: void add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers); duke@435: // Statistics gathering duke@435: void notice_inlined_method(ciMethod* method); duke@435: duke@435: DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info(); duke@435: Dependencies* dependency_recorder() const; // = _env->dependencies() duke@435: ImplicitExceptionTable* implicit_exception_table() { return &_implicit_exception_table; } duke@435: duke@435: Instruction* current_instruction() const { return _current_instruction; } duke@435: Instruction* set_current_instruction(Instruction* instr) { duke@435: Instruction* previous = _current_instruction; duke@435: _current_instruction = instr; duke@435: return previous; duke@435: } duke@435: duke@435: #ifndef PRODUCT duke@435: void maybe_print_current_instruction(); duke@435: #endif // PRODUCT duke@435: duke@435: // error handling duke@435: void bailout(const char* msg); duke@435: bool bailed_out() const { return _bailout_msg != NULL; } duke@435: const char* bailout_msg() const { return _bailout_msg; } duke@435: iveresov@1939: static int desired_max_code_buffer_size() { bobv@2036: #ifndef PPC iveresov@1939: return (int) NMethodSizeLimit; // default 256K or 512K bobv@2036: #else bobv@2036: // conditional branches on PPC are restricted to 16 bit signed bobv@2036: return MAX2((unsigned int)NMethodSizeLimit,32*K); bobv@2036: #endif iveresov@1939: } iveresov@1939: static int desired_max_constant_size() { bobv@2036: #ifndef PPC iveresov@1939: return (int) NMethodSizeLimit / 10; // about 25K bobv@2036: #else bobv@2036: return (MAX2((unsigned int)NMethodSizeLimit, 32*K)) / 10; bobv@2036: #endif iveresov@1939: } iveresov@1939: iveresov@1939: static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate); iveresov@1939: duke@435: // timers duke@435: static void print_timers(); duke@435: duke@435: #ifndef PRODUCT duke@435: // debugging support. duke@435: // produces a file named c1compileonly in the current directory with duke@435: // directives to compile only the current method and it's inlines. duke@435: // The file can be passed to the command line option -XX:Flags= duke@435: void compile_only_this_method(); duke@435: void compile_only_this_scope(outputStream* st, IRScope* scope); duke@435: void exclude_this_method(); duke@435: #endif // PRODUCT duke@435: }; duke@435: duke@435: duke@435: // Macro definitions for unified bailout-support duke@435: // The methods bailout() and bailed_out() are present in all classes duke@435: // that might bailout, but forward all calls to Compilation duke@435: #define BAILOUT(msg) { bailout(msg); return; } duke@435: #define BAILOUT_(msg, res) { bailout(msg); return res; } duke@435: duke@435: #define CHECK_BAILOUT() { if (bailed_out()) return; } duke@435: #define CHECK_BAILOUT_(res) { if (bailed_out()) return res; } duke@435: duke@435: duke@435: class InstructionMark: public StackObj { duke@435: private: duke@435: Compilation* _compilation; duke@435: Instruction* _previous; duke@435: duke@435: public: duke@435: InstructionMark(Compilation* compilation, Instruction* instr) { duke@435: _compilation = compilation; duke@435: _previous = _compilation->set_current_instruction(instr); duke@435: } duke@435: ~InstructionMark() { duke@435: _compilation->set_current_instruction(_previous); duke@435: } duke@435: }; duke@435: duke@435: duke@435: //---------------------------------------------------------------------- duke@435: // Base class for objects allocated by the compiler in the compilation arena duke@435: class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC { duke@435: public: iveresov@1939: void* operator new(size_t size) { return Compilation::current()->arena()->Amalloc(size); } iveresov@1939: void* operator new(size_t size, Arena* arena) { iveresov@1939: return arena->Amalloc(size); iveresov@1939: } duke@435: void operator delete(void* p) {} // nothing to do duke@435: }; duke@435: duke@435: duke@435: //---------------------------------------------------------------------- duke@435: // Class for aggregating exception handler information. duke@435: duke@435: // Effectively extends XHandlers class with PC offset of duke@435: // potentially exception-throwing instruction. duke@435: // This class is used at the end of the compilation to build the duke@435: // ExceptionHandlerTable. duke@435: class ExceptionInfo: public CompilationResourceObj { duke@435: private: duke@435: int _pco; // PC of potentially exception-throwing instruction duke@435: XHandlers* _exception_handlers; // flat list of exception handlers covering this PC duke@435: duke@435: public: duke@435: ExceptionInfo(int pco, XHandlers* exception_handlers) duke@435: : _pco(pco) duke@435: , _exception_handlers(exception_handlers) duke@435: { } duke@435: duke@435: int pco() { return _pco; } duke@435: XHandlers* exception_handlers() { return _exception_handlers; } duke@435: };