--- old/src/share/vm/opto/compile.hpp 2013-04-30 19:32:12.000000000 -0700 +++ new/src/share/vm/opto/compile.hpp 2013-04-30 19:32:11.000000000 -0700 @@ -262,6 +262,7 @@ const bool _save_argument_registers; // save/restore arg regs for trampolines const bool _subsume_loads; // Load can be matched as part of a larger op. const bool _do_escape_analysis; // Do escape analysis. + const bool _eliminate_autobox; // Do autoboxing elimination. ciMethod* _method; // The method being compiled. int _entry_bci; // entry bci for osr methods. const TypeFunc* _tf; // My kind of signature @@ -287,6 +288,7 @@ bool _has_split_ifs; // True if the method _may_ have some split-if bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated + bool _has_boxed_value; // True if a boxed object is allocated int _max_vector_size; // Maximum size of generated vectors uint _trap_hist[trapHistLength]; // Cumulative traps bool _trap_can_recompile; // Have we emitted a recompiling trap? @@ -375,6 +377,8 @@ // main parsing has finished. GrowableArray _string_late_inlines; // same but for string operations + GrowableArray _boxing_late_inlines; // same but for boxing operations + int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining) uint _number_of_mh_late_inlines; // number of method handle late inlining still pending @@ -488,6 +492,10 @@ bool subsume_loads() const { return _subsume_loads; } // Do escape analysis. bool do_escape_analysis() const { return _do_escape_analysis; } + // Do autoboxing elimination. + bool eliminate_autobox() const { return _eliminate_autobox; } + // Do aggressive boxing elimination. + bool aggressive_unboxing() const { return _eliminate_autobox && AggressiveUnboxing; } bool save_argument_registers() const { return _save_argument_registers; } @@ -527,6 +535,8 @@ void set_has_unsafe_access(bool z) { _has_unsafe_access = z; } bool has_stringbuilder() const { return _has_stringbuilder; } void set_has_stringbuilder(bool z) { _has_stringbuilder = z; } + bool has_boxed_value() const { return _has_boxed_value; } + void set_has_boxed_value(bool z) { _has_boxed_value = z; } int max_vector_size() const { return _max_vector_size; } void set_max_vector_size(int s) { _max_vector_size = s; } void set_trap_count(uint r, uint c) { assert(r < trapHistLength, "oob"); _trap_hist[r] = c; } @@ -579,12 +589,12 @@ #endif } - int macro_count() { return _macro_nodes->length(); } - int predicate_count() { return _predicate_opaqs->length();} - int expensive_count() { return _expensive_nodes->length(); } - Node* macro_node(int idx) { return _macro_nodes->at(idx); } - Node* predicate_opaque1_node(int idx) { return _predicate_opaqs->at(idx);} - Node* expensive_node(int idx) { return _expensive_nodes->at(idx); } + int macro_count() const { return _macro_nodes->length(); } + int predicate_count() const { return _predicate_opaqs->length();} + int expensive_count() const { return _expensive_nodes->length(); } + Node* macro_node(int idx) const { return _macro_nodes->at(idx); } + Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);} + Node* expensive_node(int idx) const { return _expensive_nodes->at(idx); } ConnectionGraph* congraph() { return _congraph;} void set_congraph(ConnectionGraph* congraph) { _congraph = congraph;} void add_macro_node(Node * n) { @@ -766,7 +776,12 @@ // Decide how to build a call. // The profile factor is a discount to apply to this site's interp. profile. CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false); - bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); + bool should_delay_inlining(ciMethod* call_method, JVMState* jvms) { + return should_delay_string_inlining(call_method, jvms) || + should_delay_boxing_inlining(call_method, jvms); + } + bool should_delay_string_inlining(ciMethod* call_method, JVMState* jvms); + bool should_delay_boxing_inlining(ciMethod* call_method, JVMState* jvms); // Helper functions to identify inlining potential at call-site ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass, @@ -822,6 +837,10 @@ _string_late_inlines.push(cg); } + void add_boxing_late_inline(CallGenerator* cg) { + _boxing_late_inlines.push(cg); + } + void remove_useless_late_inlines(GrowableArray* inlines, Unique_Node_List &useful); void dump_inlining(); @@ -838,9 +857,11 @@ void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; } bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; } + bool has_late_inline() const { return ((_late_inlines.length() + _string_late_inlines.length()) > 0); } void inline_incrementally_one(PhaseIterGVN& igvn); void inline_incrementally(PhaseIterGVN& igvn); void inline_string_calls(bool parse_time); + void inline_boxing_calls(PhaseIterGVN& igvn); // Matching, CFG layout, allocation, code generation PhaseCFG* cfg() { return _cfg; } @@ -913,7 +934,8 @@ // replacement, entry_bci indicates the bytecode for which to compile a // continuation. Compile(ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, - int entry_bci, bool subsume_loads, bool do_escape_analysis); + int entry_bci, bool subsume_loads, bool do_escape_analysis, + bool eliminate_boxing); // Second major entry point. From the TypeFunc signature, generate code // to pass arguments from the Java calling convention to the C calling