/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*
*/
#ifndef SHARE_VM_C1_C1_GRAPHBUILDER_HPP
#define SHARE_VM_C1_C1_GRAPHBUILDER_HPP
#include "c1/c1_Instruction.hpp"
#include "c1/c1_ValueMap.hpp"
#include "c1/c1_ValueStack.hpp"
#include "ci/ciMethodData.hpp"
#include "ci/ciStreams.hpp"
#include "compiler/compileLog.hpp"
class MemoryBuffer;
private:
// Per-scope data. These are pushed and popped as we descend into
// inlined methods. Currently in order to generate good code in the
// inliner we have to attempt to inline methods directly into the
// basic block we are parsing; this adds complexity.
private:
// bci-to-block mapping
// Scope
// Whether this scope or any parent scope has exception handlers
bool _has_handler;
// The bytecodes
// Work list
// Maximum inline size for this scope
// Expression stack depth at point where inline occurred
int _caller_stack_size;
// The continuation point for the inline. Currently only used in
// multi-block inlines, but eventually would like to use this for
// all inlines for uniformity and simplicity; in this case would
// get the continuation point from the BlockList instead of
// fabricating it anew because Invokes would be considered to be
// BlockEnds.
// Was this ScopeData created only for the parsing and inlining of
// a jsr?
bool _parsing_jsr;
// We track the destination bci of the jsr only to determine
// bailout conditions, since we only handle a subset of all of the
// possible jsr-ret control structures. Recursive invocations of a
// jsr are disallowed by the verifier.
int _jsr_entry_bci;
// We need to track the local variable in which the return address
// was stored to ensure we can handle inlining the jsr, because we
int _jsr_ret_addr_local;
// If we are parsing a jsr, the continuation point for rets
// Cloned XHandlers for jsr-related ScopeDatas
// Number of returns seen in this scope
int _num_returns;
// In order to generate profitable code for inlining, we currently
// have to perform an optimization for single-block inlined
// methods where we continue parsing into the same block. This
// allows us to perform CSE across inlined scopes and to avoid
// storing parameters to the stack. Having a global register
// allocator and being able to perform global CSE would allow this
// code to be removed and thereby simplify the inliner.
public:
// NOTE: this has a different effect when parsing jsrs
// Has side-effect of setting has_handler flag
// Whether this or any parent scope has exception handlers
// Exception handlers list to be used for this scope
// How to get a block to be parsed
// How to remove the next block to be parsed; returns NULL if none left
// Indicates parse is over
bool is_work_list_empty() const;
// Indicates whether this ScopeData was pushed only for the
// parsing and inlining of a jsr
// Must be called after scope is set up for jsr ScopeData
void setup_jsr_xhandlers();
// The jsr continuation is only used when parsing_jsr is true, and
// is different from the "normal" continuation since we can end up
// doing a return (rather than a ret) from within a subroutine
int num_returns();
void incr_num_returns();
};
// for all GraphBuilders
// for each instance of GraphBuilder
// for each call to connect_to_end; can also be set by inliner
// accessors
ValueMap* vmap() const { assert(UseLocalValueNumbering, "should not access otherwise"); return _vmap; }
// unified bailout support
// stack manipulation helpers
// instruction helpers
void load_constant();
void increment();
void ret(int local_index);
void table_switch();
void lookup_switch();
void method_return(Value x);
void call_register_finalizer();
void new_instance(int klass_index);
void new_type_array();
void new_object_array();
void check_cast(int klass_index);
void instance_of(int klass_index);
void new_multi_array(int dimensions);
// other helpers
void iterate_all_blocks(bool start_in_current_block_for_inlining = false);
bool direct_compare(ciKlass* k);
void kill_all();
// use of state copy routines (try to minimize unnecessary state
// object allocations):
// - if the instruction unconditionally needs a full copy of the
// state (for patching for example), then use copy_state_before*
// - if the instruction needs a full copy of the state only for
// handler generation (Instruction::needs_exception_state() returns
// false) then use copy_state_exhandling*
// - if the instruction needs either a full copy of the state for
// handler generation and a least a minimal copy of the state (as
// returned by Instruction::exception_state()) for debug info
// generation (that is when Instruction::needs_exception_state()
// returns true) then use copy_state_for_exception*
//
// Inlining support
//
// accessors
return_state); }
void set_inline_cleanup_info() {
}
Instruction* inline_cleanup_return_prev() const { return scope_data()->inline_cleanup_return_prev(); }
void restore_inline_cleanup_info() {
}
// inlining of synchronized methods
// inliners
bool try_inline( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
bool try_inline_full( ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
bool try_inline_jsr(int jsr_dest_bci);
// JSR 292 support
// helpers
void inline_bailout(const char* msg);
BlockBegin* setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* init_state);
void setup_osr_entry_block();
void clear_inline_bailout();
void pop_scope();
void pop_scope_for_jsr();
// Shortcuts to profiling control.
public:
NOT_PRODUCT(void print_stats();)
// initialization
static void initialize();
// public
// special handling for finalizer registration
}
// creation
};
#endif // SHARE_VM_C1_C1_GRAPHBUILDER_HPP