c1_Compilation.hpp revision 1879:f95d63e2154a
155714Skris/*
255714Skris * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
355714Skris * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
455714Skris *
555714Skris * This code is free software; you can redistribute it and/or modify it
655714Skris * under the terms of the GNU General Public License version 2 only, as
755714Skris * published by the Free Software Foundation.
855714Skris *
955714Skris * This code is distributed in the hope that it will be useful, but WITHOUT
1055714Skris * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1155714Skris * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1255714Skris * version 2 for more details (a copy is included in the LICENSE file that
1355714Skris * accompanied this code).
1455714Skris *
1555714Skris * You should have received a copy of the GNU General Public License version
1655714Skris * 2 along with this work; if not, write to the Free Software Foundation,
1755714Skris * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1855714Skris *
1955714Skris * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2055714Skris * or visit www.oracle.com if you need additional information or have any
2155714Skris * questions.
2255714Skris *
2355714Skris */
2455714Skris
2555714Skris#ifndef SHARE_VM_C1_C1_COMPILATION_HPP
2655714Skris#define SHARE_VM_C1_C1_COMPILATION_HPP
2755714Skris
2855714Skris#include "ci/ciEnv.hpp"
2955714Skris#include "code/exceptionHandlerTable.hpp"
3055714Skris#include "memory/resourceArea.hpp"
3155714Skris
3255714Skrisclass CompilationResourceObj;
3355714Skrisclass XHandlers;
3455714Skrisclass ExceptionInfo;
3555714Skrisclass DebugInformationRecorder;
3655714Skrisclass FrameMap;
3755714Skrisclass IR;
3855714Skrisclass IRScope;
3955714Skrisclass Instruction;
4055714Skrisclass LinearScan;
4155714Skrisclass OopMap;
4255714Skrisclass LIR_Emitter;
4355714Skrisclass LIR_Assembler;
4455714Skrisclass CodeEmitInfo;
4555714Skrisclass ciEnv;
4655714Skrisclass ciMethod;
4755714Skrisclass ValueStack;
4855714Skrisclass LIR_OprDesc;
4955714Skrisclass C1_MacroAssembler;
5055714Skrisclass CFGPrinter;
5155714Skristypedef LIR_OprDesc* LIR_Opr;
5255714Skris
5355714Skris
5455714Skrisdefine_array(BasicTypeArray, BasicType)
5555714Skrisdefine_stack(BasicTypeList, BasicTypeArray)
5655714Skris
5755714Skrisdefine_array(ExceptionInfoArray, ExceptionInfo*)
5855714Skrisdefine_stack(ExceptionInfoList,  ExceptionInfoArray)
5955714Skris
6055714Skrisclass Compilation: public StackObj {
6155714Skris  friend class CompilationResourceObj;
6255714Skris private:
6355714Skris  // compilation specifics
6455714Skris  Arena* _arena;
65109998Smarkm  int _next_id;
66109998Smarkm  int _next_block_id;
67109998Smarkm  AbstractCompiler*  _compiler;
68109998Smarkm  ciEnv*             _env;
69109998Smarkm  ciMethod*          _method;
70109998Smarkm  int                _osr_bci;
7155714Skris  IR*                _hir;
7255714Skris  int                _max_spills;
7355714Skris  FrameMap*          _frame_map;
7455714Skris  C1_MacroAssembler* _masm;
7555714Skris  bool               _has_exception_handlers;
7655714Skris  bool               _has_fpu_code;
7755714Skris  bool               _has_unsafe_access;
7855714Skris  bool               _would_profile;
7955714Skris  bool               _has_method_handle_invokes;  // True if this method has MethodHandle invokes.
8055714Skris  const char*        _bailout_msg;
8155714Skris  ExceptionInfoList* _exception_info_list;
8255714Skris  ExceptionHandlerTable _exception_handler_table;
8355714Skris  ImplicitExceptionTable _implicit_exception_table;
8455714Skris  LinearScan*        _allocator;
8555714Skris  CodeOffsets        _offsets;
8655714Skris  CodeBuffer         _code;
8755714Skris
8855714Skris  // compilation helpers
8955714Skris  void initialize();
9055714Skris  void build_hir();
91109998Smarkm  void emit_lir();
9255714Skris
93109998Smarkm  void emit_code_epilog(LIR_Assembler* assembler);
94109998Smarkm  int  emit_code_body();
9555714Skris
9655714Skris  int  compile_java_method();
9755714Skris  void install_code(int frame_size);
9855714Skris  void compile_method();
9955714Skris
10055714Skris  void generate_exception_handler_table();
101109998Smarkm
10255714Skris  ExceptionInfoList* exception_info_list() const { return _exception_info_list; }
103109998Smarkm  ExceptionHandlerTable* exception_handler_table() { return &_exception_handler_table; }
104109998Smarkm
10555714Skris  LinearScan* allocator()                          { return _allocator;      }
10655714Skris  void        set_allocator(LinearScan* allocator) { _allocator = allocator; }
10755714Skris
10855714Skris  Instruction*       _current_instruction;       // the instruction currently being processed
10955714Skris#ifndef PRODUCT
11055714Skris  Instruction*       _last_instruction_printed;  // the last instruction printed during traversal
11155714Skris#endif // PRODUCT
11255714Skris
11355714Skris public:
11455714Skris  // creation
11555714Skris  Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method,
11655714Skris              int osr_bci, BufferBlob* buffer_blob);
11755714Skris  ~Compilation();
11855714Skris
11955714Skris
12055714Skris  static Compilation* current() {
12155714Skris    return (Compilation*) ciEnv::current()->compiler_data();
12255714Skris  }
123
124  // accessors
125  ciEnv* env() const                             { return _env; }
126  AbstractCompiler* compiler() const             { return _compiler; }
127  bool has_exception_handlers() const            { return _has_exception_handlers; }
128  bool has_fpu_code() const                      { return _has_fpu_code; }
129  bool has_unsafe_access() const                 { return _has_unsafe_access; }
130  ciMethod* method() const                       { return _method; }
131  int osr_bci() const                            { return _osr_bci; }
132  bool is_osr_compile() const                    { return osr_bci() >= 0; }
133  IR* hir() const                                { return _hir; }
134  int max_spills() const                         { return _max_spills; }
135  FrameMap* frame_map() const                    { return _frame_map; }
136  CodeBuffer* code()                             { return &_code; }
137  C1_MacroAssembler* masm() const                { return _masm; }
138  CodeOffsets* offsets()                         { return &_offsets; }
139  Arena* arena()                                 { return _arena; }
140
141  // Instruction ids
142  int get_next_id()                              { return _next_id++; }
143  int number_of_instructions() const             { return _next_id; }
144
145  // BlockBegin ids
146  int get_next_block_id()                        { return _next_block_id++; }
147  int number_of_blocks() const                   { return _next_block_id; }
148
149  // setters
150  void set_has_exception_handlers(bool f)        { _has_exception_handlers = f; }
151  void set_has_fpu_code(bool f)                  { _has_fpu_code = f; }
152  void set_has_unsafe_access(bool f)             { _has_unsafe_access = f; }
153  void set_would_profile(bool f)                 { _would_profile = f; }
154  // Add a set of exception handlers covering the given PC offset
155  void add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers);
156  // Statistics gathering
157  void notice_inlined_method(ciMethod* method);
158
159  // JSR 292
160  bool     has_method_handle_invokes() const { return _has_method_handle_invokes;     }
161  void set_has_method_handle_invokes(bool z) {        _has_method_handle_invokes = z; }
162
163  DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info();
164  Dependencies* dependency_recorder() const; // = _env->dependencies()
165  ImplicitExceptionTable* implicit_exception_table()     { return &_implicit_exception_table; }
166
167  Instruction* current_instruction() const       { return _current_instruction; }
168  Instruction* set_current_instruction(Instruction* instr) {
169    Instruction* previous = _current_instruction;
170    _current_instruction = instr;
171    return previous;
172  }
173
174#ifndef PRODUCT
175  void maybe_print_current_instruction();
176#endif // PRODUCT
177
178  // error handling
179  void bailout(const char* msg);
180  bool bailed_out() const                        { return _bailout_msg != NULL; }
181  const char* bailout_msg() const                { return _bailout_msg; }
182
183  static int desired_max_code_buffer_size() {
184#ifndef PPC
185    return (int) NMethodSizeLimit;  // default 256K or 512K
186#else
187    // conditional branches on PPC are restricted to 16 bit signed
188    return MIN2((unsigned int)NMethodSizeLimit,32*K);
189#endif
190  }
191  static int desired_max_constant_size() {
192    return desired_max_code_buffer_size() / 10;
193  }
194
195  static void setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);
196
197  // timers
198  static void print_timers();
199
200#ifndef PRODUCT
201  // debugging support.
202  // produces a file named c1compileonly in the current directory with
203  // directives to compile only the current method and it's inlines.
204  // The file can be passed to the command line option -XX:Flags=<filename>
205  void compile_only_this_method();
206  void compile_only_this_scope(outputStream* st, IRScope* scope);
207  void exclude_this_method();
208#endif // PRODUCT
209
210  bool is_profiling() {
211    return env()->comp_level() == CompLevel_full_profile ||
212           env()->comp_level() == CompLevel_limited_profile;
213  }
214  bool count_invocations() { return is_profiling(); }
215  bool count_backedges()   { return is_profiling(); }
216
217  // Helpers for generation of profile information
218  bool profile_branches() {
219    return env()->comp_level() == CompLevel_full_profile &&
220      C1UpdateMethodData && C1ProfileBranches;
221  }
222  bool profile_calls() {
223    return env()->comp_level() == CompLevel_full_profile &&
224      C1UpdateMethodData && C1ProfileCalls;
225  }
226  bool profile_inlined_calls() {
227    return profile_calls() && C1ProfileInlinedCalls;
228  }
229  bool profile_checkcasts() {
230    return env()->comp_level() == CompLevel_full_profile &&
231      C1UpdateMethodData && C1ProfileCheckcasts;
232  }
233};
234
235
236// Macro definitions for unified bailout-support
237// The methods bailout() and bailed_out() are present in all classes
238// that might bailout, but forward all calls to Compilation
239#define BAILOUT(msg)               { bailout(msg); return;              }
240#define BAILOUT_(msg, res)         { bailout(msg); return res;          }
241
242#define CHECK_BAILOUT()            { if (bailed_out()) return;          }
243#define CHECK_BAILOUT_(res)        { if (bailed_out()) return res;      }
244
245
246class InstructionMark: public StackObj {
247 private:
248  Compilation* _compilation;
249  Instruction*  _previous;
250
251 public:
252  InstructionMark(Compilation* compilation, Instruction* instr) {
253    _compilation = compilation;
254    _previous = _compilation->set_current_instruction(instr);
255  }
256  ~InstructionMark() {
257    _compilation->set_current_instruction(_previous);
258  }
259};
260
261
262//----------------------------------------------------------------------
263// Base class for objects allocated by the compiler in the compilation arena
264class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC {
265 public:
266  void* operator new(size_t size) { return Compilation::current()->arena()->Amalloc(size); }
267  void* operator new(size_t size, Arena* arena) {
268    return arena->Amalloc(size);
269  }
270  void  operator delete(void* p) {} // nothing to do
271};
272
273
274//----------------------------------------------------------------------
275// Class for aggregating exception handler information.
276
277// Effectively extends XHandlers class with PC offset of
278// potentially exception-throwing instruction.
279// This class is used at the end of the compilation to build the
280// ExceptionHandlerTable.
281class ExceptionInfo: public CompilationResourceObj {
282 private:
283  int             _pco;                // PC of potentially exception-throwing instruction
284  XHandlers*      _exception_handlers; // flat list of exception handlers covering this PC
285
286 public:
287  ExceptionInfo(int pco, XHandlers* exception_handlers)
288    : _pco(pco)
289    , _exception_handlers(exception_handlers)
290  { }
291
292  int pco()                                      { return _pco; }
293  XHandlers* exception_handlers()                { return _exception_handlers; }
294};
295
296#endif // SHARE_VM_C1_C1_COMPILATION_HPP
297