Path: blob/master/src/hotspot/share/c1/c1_Compilation.hpp
40930 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_C1_C1_COMPILATION_HPP25#define SHARE_C1_C1_COMPILATION_HPP2627#include "ci/ciEnv.hpp"28#include "ci/ciMethodData.hpp"29#include "code/exceptionHandlerTable.hpp"30#include "compiler/compiler_globals.hpp"31#include "compiler/compilerDirectives.hpp"32#include "memory/resourceArea.hpp"33#include "runtime/deoptimization.hpp"3435class CompilationResourceObj;36class XHandlers;37class ExceptionInfo;38class DebugInformationRecorder;39class FrameMap;40class IR;41class IRScope;42class Instruction;43class LinearScan;44class OopMap;45class LIR_Emitter;46class LIR_Assembler;47class CodeEmitInfo;48class ciEnv;49class ciMethod;50class ValueStack;51class LIR_OprDesc;52class C1_MacroAssembler;53class CFGPrinter;54class CFGPrinterOutput;55typedef LIR_OprDesc* LIR_Opr;5657typedef GrowableArray<BasicType> BasicTypeArray;58typedef GrowableArray<BasicType> BasicTypeList;59typedef GrowableArray<ExceptionInfo*> ExceptionInfoList;6061class Compilation: public StackObj {62friend class CompilationResourceObj;63private:64// compilation specifics65Arena* _arena;66int _next_id;67int _next_block_id;68AbstractCompiler* _compiler;69DirectiveSet* _directive;70ciEnv* _env;71CompileLog* _log;72ciMethod* _method;73int _osr_bci;74IR* _hir;75int _max_spills;76FrameMap* _frame_map;77C1_MacroAssembler* _masm;78bool _has_exception_handlers;79bool _has_fpu_code;80bool _has_unsafe_access;81bool _would_profile;82bool _has_method_handle_invokes; // True if this method has MethodHandle invokes.83bool _has_reserved_stack_access;84bool _install_code;85const char* _bailout_msg;86ExceptionInfoList* _exception_info_list;87ExceptionHandlerTable _exception_handler_table;88ImplicitExceptionTable _implicit_exception_table;89LinearScan* _allocator;90CodeOffsets _offsets;91CodeBuffer _code;92bool _has_access_indexed;93int _interpreter_frame_size; // Stack space needed in case of a deoptimization9495// compilation helpers96void initialize();97void build_hir();98void emit_lir();99100void emit_code_epilog(LIR_Assembler* assembler);101int emit_code_body();102103int compile_java_method();104void install_code(int frame_size);105void compile_method();106107void generate_exception_handler_table();108109ExceptionInfoList* exception_info_list() const { return _exception_info_list; }110ExceptionHandlerTable* exception_handler_table() { return &_exception_handler_table; }111112void set_allocator(LinearScan* allocator) { _allocator = allocator; }113114Instruction* _current_instruction; // the instruction currently being processed115#ifndef PRODUCT116Instruction* _last_instruction_printed; // the last instruction printed during traversal117CFGPrinterOutput* _cfg_printer_output;118#endif // PRODUCT119120public:121// creation122Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* method,123int osr_bci, BufferBlob* buffer_blob, bool install_code, DirectiveSet* directive);124~Compilation();125126127static Compilation* current() {128return (Compilation*) ciEnv::current()->compiler_data();129}130131// accessors132ciEnv* env() const { return _env; }133DirectiveSet* directive() const { return _directive; }134CompileLog* log() const { return _log; }135AbstractCompiler* compiler() const { return _compiler; }136bool has_exception_handlers() const { return _has_exception_handlers; }137bool has_fpu_code() const { return _has_fpu_code; }138bool has_unsafe_access() const { return _has_unsafe_access; }139int max_vector_size() const { return 0; }140ciMethod* method() const { return _method; }141int osr_bci() const { return _osr_bci; }142bool is_osr_compile() const { return osr_bci() >= 0; }143IR* hir() const { return _hir; }144int max_spills() const { return _max_spills; }145FrameMap* frame_map() const { return _frame_map; }146CodeBuffer* code() { return &_code; }147C1_MacroAssembler* masm() const { return _masm; }148CodeOffsets* offsets() { return &_offsets; }149Arena* arena() { return _arena; }150bool has_access_indexed() { return _has_access_indexed; }151bool should_install_code() { return _install_code && InstallMethods; }152LinearScan* allocator() { return _allocator; }153154// Instruction ids155int get_next_id() { return _next_id++; }156int number_of_instructions() const { return _next_id; }157158// BlockBegin ids159int get_next_block_id() { return _next_block_id++; }160int number_of_blocks() const { return _next_block_id; }161162// setters163void set_has_exception_handlers(bool f) { _has_exception_handlers = f; }164void set_has_fpu_code(bool f) { _has_fpu_code = f; }165void set_has_unsafe_access(bool f) { _has_unsafe_access = f; }166void set_would_profile(bool f) { _would_profile = f; }167void set_has_access_indexed(bool f) { _has_access_indexed = f; }168// Add a set of exception handlers covering the given PC offset169void add_exception_handlers_for_pco(int pco, XHandlers* exception_handlers);170// Statistics gathering171void notice_inlined_method(ciMethod* method);172173// JSR 292174bool has_method_handle_invokes() const { return _has_method_handle_invokes; }175void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; }176177bool has_reserved_stack_access() const { return _has_reserved_stack_access; }178void set_has_reserved_stack_access(bool z) { _has_reserved_stack_access = z; }179180DebugInformationRecorder* debug_info_recorder() const; // = _env->debug_info();181Dependencies* dependency_recorder() const; // = _env->dependencies()182ImplicitExceptionTable* implicit_exception_table() { return &_implicit_exception_table; }183184Instruction* current_instruction() const { return _current_instruction; }185Instruction* set_current_instruction(Instruction* instr) {186Instruction* previous = _current_instruction;187_current_instruction = instr;188return previous;189}190191#ifndef PRODUCT192void maybe_print_current_instruction();193CFGPrinterOutput* cfg_printer_output() {194guarantee(_cfg_printer_output != NULL, "CFG printer output not initialized");195return _cfg_printer_output;196}197#endif // PRODUCT198199// error handling200void bailout(const char* msg);201bool bailed_out() const { return _bailout_msg != NULL; }202const char* bailout_msg() const { return _bailout_msg; }203204static int desired_max_code_buffer_size() {205return (int)NMethodSizeLimit; // default 64K206}207static int desired_max_constant_size() {208return desired_max_code_buffer_size() / 10;209}210211static bool setup_code_buffer(CodeBuffer* cb, int call_stub_estimate);212213// timers214static void print_timers();215216#ifndef PRODUCT217// debugging support.218// produces a file named c1compileonly in the current directory with219// directives to compile only the current method and it's inlines.220// The file can be passed to the command line option -XX:Flags=<filename>221void compile_only_this_method();222void compile_only_this_scope(outputStream* st, IRScope* scope);223void exclude_this_method();224#endif // PRODUCT225226bool is_profiling() {227return env()->comp_level() == CompLevel_full_profile ||228env()->comp_level() == CompLevel_limited_profile;229}230bool count_invocations() { return is_profiling(); }231bool count_backedges() { return is_profiling(); }232233// Helpers for generation of profile information234bool profile_branches() {235return env()->comp_level() == CompLevel_full_profile &&236C1UpdateMethodData && C1ProfileBranches;237}238bool profile_calls() {239return env()->comp_level() == CompLevel_full_profile &&240C1UpdateMethodData && C1ProfileCalls;241}242bool profile_inlined_calls() {243return profile_calls() && C1ProfileInlinedCalls;244}245bool profile_checkcasts() {246return env()->comp_level() == CompLevel_full_profile &&247C1UpdateMethodData && C1ProfileCheckcasts;248}249bool profile_parameters() {250return env()->comp_level() == CompLevel_full_profile &&251C1UpdateMethodData && MethodData::profile_parameters();252}253bool profile_arguments() {254return env()->comp_level() == CompLevel_full_profile &&255C1UpdateMethodData && MethodData::profile_arguments();256}257bool profile_return() {258return env()->comp_level() == CompLevel_full_profile &&259C1UpdateMethodData && MethodData::profile_return();260}261bool age_code() const {262return _method->profile_aging();263}264265// will compilation make optimistic assumptions that might lead to266// deoptimization and that the runtime will account for?267bool is_optimistic() {268return CompilerConfig::is_c1_only_no_jvmci() && !is_profiling() &&269(RangeCheckElimination || UseLoopInvariantCodeMotion) &&270method()->method_data()->trap_count(Deoptimization::Reason_none) == 0;271}272273ciKlass* cha_exact_type(ciType* type);274275// Dump inlining replay data to the stream.276void dump_inline_data(outputStream* out) { /* do nothing now */ }277278// How much stack space would the interpreter need in case of a279// deoptimization (worst case)280void update_interpreter_frame_size(int size) {281if (_interpreter_frame_size < size) {282_interpreter_frame_size = size;283}284}285286int interpreter_frame_size() const {287return _interpreter_frame_size;288}289};290291292// Macro definitions for unified bailout-support293// The methods bailout() and bailed_out() are present in all classes294// that might bailout, but forward all calls to Compilation295#define BAILOUT(msg) { bailout(msg); return; }296#define BAILOUT_(msg, res) { bailout(msg); return res; }297298#define CHECK_BAILOUT() { if (bailed_out()) return; }299#define CHECK_BAILOUT_(res) { if (bailed_out()) return res; }300301// BAILOUT check with reset of bound labels302#define CHECK_BAILOUT1(l1) { if (bailed_out()) { l1.reset(); return; } }303#define CHECK_BAILOUT2(l1, l2) { if (bailed_out()) { l1.reset(); l2.reset(); return; } }304#define CHECK_BAILOUT3(l1, l2, l3) { if (bailed_out()) { l1.reset(); l2.reset(); l3.reset(); return; } }305306307class InstructionMark: public StackObj {308private:309Compilation* _compilation;310Instruction* _previous;311312public:313InstructionMark(Compilation* compilation, Instruction* instr) {314_compilation = compilation;315_previous = _compilation->set_current_instruction(instr);316}317~InstructionMark() {318_compilation->set_current_instruction(_previous);319}320};321322323//----------------------------------------------------------------------324// Base class for objects allocated by the compiler in the compilation arena325class CompilationResourceObj ALLOCATION_SUPER_CLASS_SPEC {326public:327void* operator new(size_t size) throw() { return Compilation::current()->arena()->Amalloc(size); }328void* operator new(size_t size, Arena* arena) throw() {329return arena->Amalloc(size);330}331void operator delete(void* p) {} // nothing to do332};333334335//----------------------------------------------------------------------336// Class for aggregating exception handler information.337338// Effectively extends XHandlers class with PC offset of339// potentially exception-throwing instruction.340// This class is used at the end of the compilation to build the341// ExceptionHandlerTable.342class ExceptionInfo: public CompilationResourceObj {343private:344int _pco; // PC of potentially exception-throwing instruction345XHandlers* _exception_handlers; // flat list of exception handlers covering this PC346347public:348ExceptionInfo(int pco, XHandlers* exception_handlers)349: _pco(pco)350, _exception_handlers(exception_handlers)351{ }352353int pco() { return _pco; }354XHandlers* exception_handlers() { return _exception_handlers; }355};356357#endif // SHARE_C1_C1_COMPILATION_HPP358359360