annotate src/share/vm/opto/callGenerator.cpp @ 1994:6cd6d394f280

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children 8033953d67ff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1265
diff changeset
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1265
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1265
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1265
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "ci/bcEscapeAnalyzer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "ci/ciCPCache.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "ci/ciMethodHandle.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "classfile/javaClasses.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "opto/callGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "opto/subnode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 CallGenerator::CallGenerator(ciMethod* method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 }
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // Utility function.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 const TypeFunc* CallGenerator::tf() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 return TypeFunc::make(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 //-----------------------------ParseGenerator---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Internal class which handles all direct bytecode traversal.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class ParseGenerator : public InlineCallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
54 bool _is_osr;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 float _expected_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
58 ParseGenerator(ciMethod* method, float expected_uses, bool is_osr = false)
a61af66fc99e Initial load
duke
parents:
diff changeset
59 : InlineCallGenerator(method)
a61af66fc99e Initial load
duke
parents:
diff changeset
60 {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _is_osr = is_osr;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _expected_uses = expected_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 assert(can_parse(method, is_osr), "parse must be possible");
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // Can we build either an OSR or a regular parser for this method?
a61af66fc99e Initial load
duke
parents:
diff changeset
67 static bool can_parse(ciMethod* method, int is_osr = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 virtual bool is_parse() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 virtual JVMState* generate(JVMState* jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 int is_osr() { return _is_osr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 };
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 JVMState* ParseGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 if (is_osr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // The JVMS for a OSR has a single argument (see its TypeFunc).
a61af66fc99e Initial load
duke
parents:
diff changeset
80 assert(jvms->depth() == 1, "no inline OSR");
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 if (C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 return NULL; // bailing out of the compile; do not try to parse
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 Parse parser(jvms, method(), _expected_uses);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // Grab signature for matching/allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
89 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
90 if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 assert(C->env()->system_dictionary_modification_counter_changed(),
a61af66fc99e Initial load
duke
parents:
diff changeset
93 "Must invalidate if TypeFuncs differ");
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 GraphKit& exits = parser.exits();
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 while (exits.pop_exception_state() != NULL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 assert(exits.jvms()->same_calls_as(jvms), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Simply return the exit state of the parser,
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // augmented by any exceptional states.
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return exits.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 //---------------------------DirectCallGenerator------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Internal class which handles all out-of-line calls w/o receiver type checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 class DirectCallGenerator : public CallGenerator {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
114 private:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
115 CallStaticJavaNode* _call_node;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
116 // Force separate memory and I/O projections for the exceptional
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
117 // paths to facilitate late inlinig.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
118 bool _separate_io_proj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
119
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
120 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
121 DirectCallGenerator(ciMethod* method, bool separate_io_proj)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
122 : CallGenerator(method),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
123 _separate_io_proj(separate_io_proj)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
124 {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 virtual JVMState* generate(JVMState* jvms);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
127
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
128 CallStaticJavaNode* call_node() const { return _call_node; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
129 };
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 JVMState* DirectCallGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 bool is_static = method()->is_static();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
a61af66fc99e Initial load
duke
parents:
diff changeset
135 : SharedRuntime::get_resolve_opt_virtual_call_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (kit.C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), target, method(), kit.bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if (!is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Make an explicit receiver null_check as part of this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Since we share a map with the caller, his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 kit.null_check_receiver(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // And dump it back to the caller, decorated with any exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
148 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Mark the call node as virtual, sort of:
a61af66fc99e Initial load
duke
parents:
diff changeset
151 call->set_optimized_virtual(true);
1265
b4b440360f1e 6926782: CodeBuffer size too small after 6921352
twisti
parents: 1138
diff changeset
152 if (method()->is_method_handle_invoke()) {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
153 call->set_method_handle_invoke(true);
1265
b4b440360f1e 6926782: CodeBuffer size too small after 6921352
twisti
parents: 1138
diff changeset
154 kit.C->set_has_method_handle_invokes(true);
b4b440360f1e 6926782: CodeBuffer size too small after 6921352
twisti
parents: 1138
diff changeset
155 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 kit.set_arguments_for_java_call(call);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
158 kit.set_edges_for_java_call(call, false, _separate_io_proj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
159 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
160 kit.push_node(method()->return_type()->basic_type(), ret);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
161 _call_node = call; // Save the call node in case we need it later
0
a61af66fc99e Initial load
duke
parents:
diff changeset
162 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
165 //---------------------------DynamicCallGenerator-----------------------------
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
166 // Internal class which handles all out-of-line invokedynamic calls.
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
167 class DynamicCallGenerator : public CallGenerator {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
168 public:
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
169 DynamicCallGenerator(ciMethod* method)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
170 : CallGenerator(method)
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
171 {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
172 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
173 virtual JVMState* generate(JVMState* jvms);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
174 };
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
175
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
176 JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
177 GraphKit kit(jvms);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
178
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
179 if (kit.C->log() != NULL) {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
180 kit.C->log()->elem("dynamic_call bci='%d'", jvms->bci());
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
181 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
182
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
183 // Get the constant pool cache from the caller class.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
184 ciMethod* caller_method = jvms->method();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
185 ciBytecodeStream str(caller_method);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
186 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
187 assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
188 ciCPCache* cpcache = str.get_cpcache();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
189
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
190 // Get the offset of the CallSite from the constant pool cache
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
191 // pointer.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
192 int index = str.get_method_index();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
193 size_t call_site_offset = cpcache->get_f1_offset(index);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
194
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
195 // Load the CallSite object from the constant pool cache.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
196 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
197 Node* cpcache_adr = kit.makecon(cpcache_ptr);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
198 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
199 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
200
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
201 // Load the target MethodHandle from the CallSite object.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
202 Node* target_mh_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
203 Node* target_mh = kit.make_load(kit.control(), target_mh_adr, TypeInstPtr::BOTTOM, T_OBJECT);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
204
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
205 address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
206
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
207 CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
208 // invokedynamic is treated as an optimized invokevirtual.
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
209 call->set_optimized_virtual(true);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
210 // Take extra care (in the presence of argument motion) not to trash the SP:
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
211 call->set_method_handle_invoke(true);
1265
b4b440360f1e 6926782: CodeBuffer size too small after 6921352
twisti
parents: 1138
diff changeset
212 kit.C->set_has_method_handle_invokes(true);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
213
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
214 // Pass the target MethodHandle as first argument and shift the
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
215 // other arguments.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
216 call->init_req(0 + TypeFunc::Parms, target_mh);
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
217 uint nargs = call->method()->arg_size();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
218 for (uint i = 1; i < nargs; i++) {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
219 Node* arg = kit.argument(i - 1);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
220 call->init_req(i + TypeFunc::Parms, arg);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
221 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
222
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
223 kit.set_edges_for_java_call(call);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
224 Node* ret = kit.set_results_for_java_call(call);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
225 kit.push_node(method()->return_type()->basic_type(), ret);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
226 return kit.transfer_exceptions_into_jvms();
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
227 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
228
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
229 //--------------------------VirtualCallGenerator------------------------------
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
230 // Internal class which handles all out-of-line calls checking receiver type.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
231 class VirtualCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
233 int _vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
235 VirtualCallGenerator(ciMethod* method, int vtable_index)
a61af66fc99e Initial load
duke
parents:
diff changeset
236 : CallGenerator(method), _vtable_index(vtable_index)
a61af66fc99e Initial load
duke
parents:
diff changeset
237 {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 assert(vtable_index == methodOopDesc::invalid_vtable_index ||
a61af66fc99e Initial load
duke
parents:
diff changeset
239 vtable_index >= 0, "either invalid or usable");
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 virtual bool is_virtual() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 virtual JVMState* generate(JVMState* jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 };
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 JVMState* VirtualCallGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 Node* receiver = kit.argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 if (kit.C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 kit.C->log()->elem("virtual_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // If the receiver is a constant null, do not torture the system
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // by attempting to call through it. The compile will proceed
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // correctly, but may bail out in final_graph_reshaping, because
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // the call instruction will have a seemingly deficient out-count.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // (The bailout says something misleading about an "infinite loop".)
a61af66fc99e Initial load
duke
parents:
diff changeset
258 if (kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 kit.inc_sp(method()->arg_size()); // restore arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
260 kit.uncommon_trap(Deoptimization::Reason_null_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
261 Deoptimization::Action_none,
a61af66fc99e Initial load
duke
parents:
diff changeset
262 NULL, "null receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
263 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Ideally we would unconditionally do a null check here and let it
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // be converted to an implicit check based on profile information.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // However currently the conversion to implicit null checks in
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Block::implicit_null_check() only looks for loads and stores, not calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
270 ciMethod *caller = kit.method();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 ciMethodData *caller_md = (caller == NULL) ? NULL : caller->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 if (!UseInlineCaches || !ImplicitNullChecks ||
a61af66fc99e Initial load
duke
parents:
diff changeset
273 ((ImplicitNullCheckThreshold > 0) && caller_md &&
a61af66fc99e Initial load
duke
parents:
diff changeset
274 (caller_md->trap_count(Deoptimization::Reason_null_check)
a61af66fc99e Initial load
duke
parents:
diff changeset
275 >= (uint)ImplicitNullCheckThreshold))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Make an explicit receiver null_check as part of this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Since we share a map with the caller, his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 receiver = kit.null_check_receiver(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // And dump it back to the caller, decorated with any exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
281 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 assert(!method()->is_static(), "virtual call must not be to static");
a61af66fc99e Initial load
duke
parents:
diff changeset
286 assert(!method()->is_final(), "virtual call should not be to final");
a61af66fc99e Initial load
duke
parents:
diff changeset
287 assert(!method()->is_private(), "virtual call should not be to private");
a61af66fc99e Initial load
duke
parents:
diff changeset
288 assert(_vtable_index == methodOopDesc::invalid_vtable_index || !UseInlineCaches,
a61af66fc99e Initial load
duke
parents:
diff changeset
289 "no vtable calls if +UseInlineCaches ");
a61af66fc99e Initial load
duke
parents:
diff changeset
290 address target = SharedRuntime::get_resolve_virtual_call_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Normal inline cache used for call
a61af66fc99e Initial load
duke
parents:
diff changeset
292 CallDynamicJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
293 kit.set_arguments_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
294 kit.set_edges_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 Node* ret = kit.set_results_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 kit.push_node(method()->return_type()->basic_type(), ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Represent the effect of an implicit receiver null_check
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // as part of this call. Since we share a map with the caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 kit.cast_not_null(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 bool ParseGenerator::can_parse(ciMethod* m, int entry_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // Certain methods cannot be parsed at all:
a61af66fc99e Initial load
duke
parents:
diff changeset
307 if (!m->can_be_compiled()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (!m->has_balanced_monitors()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if (m->get_flow_analysis()->failing()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // (Methods may bail out for other reasons, after the parser is run.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // We try to avoid this, but if forced, we must return (Node*)NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // The user of the CallGenerator must check for this condition.)
a61af66fc99e Initial load
duke
parents:
diff changeset
314 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 CallGenerator* CallGenerator::for_inline(ciMethod* m, float expected_uses) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if (!ParseGenerator::can_parse(m)) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 return new ParseGenerator(m, expected_uses);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // As a special case, the JVMS passed to this CallGenerator is
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // for the method execution already in progress, not just the JVMS
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // of the caller. Thus, this CallGenerator cannot be mixed with others!
a61af66fc99e Initial load
duke
parents:
diff changeset
325 CallGenerator* CallGenerator::for_osr(ciMethod* m, int osr_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if (!ParseGenerator::can_parse(m, true)) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 float past_uses = m->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
328 float expected_uses = past_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return new ParseGenerator(m, expected_uses, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
332 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
333 assert(!m->is_abstract(), "for_direct_call mismatch");
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
334 return new DirectCallGenerator(m, separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
337 CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
338 assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
339 return new DynamicCallGenerator(m);
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
340 }
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
341
0
a61af66fc99e Initial load
duke
parents:
diff changeset
342 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 assert(!m->is_static(), "for_virtual_call mismatch");
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
344 assert(!m->is_method_handle_invoke(), "should be a direct call");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
345 return new VirtualCallGenerator(m, vtable_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
348 // Allow inlining decisions to be delayed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
349 class LateInlineCallGenerator : public DirectCallGenerator {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
350 CallGenerator* _inline_cg;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
351
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
352 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
353 LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
354 DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
355
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
356 virtual bool is_late_inline() const { return true; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
357
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
358 // Convert the CallStaticJava into an inline
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
359 virtual void do_late_inline();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
360
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
361 JVMState* generate(JVMState* jvms) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
362 // Record that this call site should be revisited once the main
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
363 // parse is finished.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
364 Compile::current()->add_late_inline(this);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
365
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
366 // Emit the CallStaticJava and request separate projections so
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
367 // that the late inlining logic can distinguish between fall
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
368 // through and exceptional uses of the memory and io projections
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
369 // as is done for allocations and macro expansion.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
370 return DirectCallGenerator::generate(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
371 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
372
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
373 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
374
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
375
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
376 void LateInlineCallGenerator::do_late_inline() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
377 // Can't inline it
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
378 if (call_node() == NULL || call_node()->outcnt() == 0 ||
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
379 call_node()->in(0) == NULL || call_node()->in(0)->is_top())
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
380 return;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
381
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
382 CallStaticJavaNode* call = call_node();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
383
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
384 // Make a clone of the JVMState that appropriate to use for driving a parse
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
385 Compile* C = Compile::current();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
386 JVMState* jvms = call->jvms()->clone_shallow(C);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
387 uint size = call->req();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
388 SafePointNode* map = new (C, size) SafePointNode(size, jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
389 for (uint i1 = 0; i1 < size; i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
390 map->init_req(i1, call->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
391 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
392
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
393 // Make sure the state is a MergeMem for parsing.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
394 if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
395 map->set_req(TypeFunc::Memory, MergeMemNode::make(C, map->in(TypeFunc::Memory)));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
396 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
397
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
398 // Make enough space for the expression stack and transfer the incoming arguments
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
399 int nargs = method()->arg_size();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
400 jvms->set_map(map);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
401 map->ensure_stack(jvms, jvms->method()->max_stack());
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
402 if (nargs > 0) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
403 for (int i1 = 0; i1 < nargs; i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
404 map->set_req(i1 + jvms->argoff(), call->in(TypeFunc::Parms + i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
405 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
406 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
407
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
408 CompileLog* log = C->log();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
409 if (log != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
410 log->head("late_inline method='%d'", log->identify(method()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
411 JVMState* p = jvms;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
412 while (p != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
413 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
414 p = p->caller();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
415 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
416 log->tail("late_inline");
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
417 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
418
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
419 // Setup default node notes to be picked up by the inlining
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
420 Node_Notes* old_nn = C->default_node_notes();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
421 if (old_nn != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
422 Node_Notes* entry_nn = old_nn->clone(C);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
423 entry_nn->set_jvms(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
424 C->set_default_node_notes(entry_nn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
425 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
426
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
427 // Now perform the inling using the synthesized JVMState
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
428 JVMState* new_jvms = _inline_cg->generate(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
429 if (new_jvms == NULL) return; // no change
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
430 if (C->failing()) return;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
431
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
432 // Capture any exceptional control flow
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
433 GraphKit kit(new_jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
434
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
435 // Find the result object
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
436 Node* result = C->top();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
437 int result_size = method()->return_type()->size();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
438 if (result_size != 0 && !kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
439 result = (result_size == 1) ? kit.pop() : kit.pop_pair();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
440 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
441
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
442 kit.replace_call(call, result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
443 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
444
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
445
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
446 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
447 return new LateInlineCallGenerator(method, inline_cg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
448 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
449
0
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 //---------------------------WarmCallGenerator--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Internal class which handles initial deferral of inlining decisions.
a61af66fc99e Initial load
duke
parents:
diff changeset
453 class WarmCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
454 WarmCallInfo* _call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
455 CallGenerator* _if_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 CallGenerator* _if_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 bool _is_virtual; // caches virtuality of if_cold
a61af66fc99e Initial load
duke
parents:
diff changeset
458 bool _is_inline; // caches inline-ness of if_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
461 WarmCallGenerator(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
462 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
463 CallGenerator* if_hot)
a61af66fc99e Initial load
duke
parents:
diff changeset
464 : CallGenerator(if_cold->method())
a61af66fc99e Initial load
duke
parents:
diff changeset
465 {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 assert(method() == if_hot->method(), "consistent choices");
a61af66fc99e Initial load
duke
parents:
diff changeset
467 _call_info = ci;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 _if_cold = if_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _if_hot = if_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 _is_virtual = if_cold->is_virtual();
a61af66fc99e Initial load
duke
parents:
diff changeset
471 _is_inline = if_hot->is_inline();
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 virtual bool is_inline() const { return _is_inline; }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 virtual bool is_virtual() const { return _is_virtual; }
a61af66fc99e Initial load
duke
parents:
diff changeset
476 virtual bool is_deferred() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 virtual JVMState* generate(JVMState* jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 };
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 CallGenerator* CallGenerator::for_warm_call(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
483 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
484 CallGenerator* if_hot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 return new WarmCallGenerator(ci, if_cold, if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 JVMState* WarmCallGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
490 if (C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 C->log()->elem("warm_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493 jvms = _if_cold->generate(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (jvms != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 Node* m = jvms->map()->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (m->is_CatchProj()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (m->is_Catch()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
498 if (m->is_Proj()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (m->is_CallJava()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 _call_info->set_call(m->as_Call());
a61af66fc99e Initial load
duke
parents:
diff changeset
501 _call_info->set_hot_cg(_if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
503 if (PrintOpto || PrintOptoInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 tty->print_cr("Queueing for warm inlining at bci %d:", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
505 tty->print("WCI: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
506 _call_info->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
509 _call_info->set_heat(_call_info->compute_heat());
a61af66fc99e Initial load
duke
parents:
diff changeset
510 C->set_warm_calls(_call_info->insert_into(C->warm_calls()));
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 void WarmCallInfo::make_hot() {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
517 Unimplemented();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 void WarmCallInfo::make_cold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // No action: Just dequeue.
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 //------------------------PredictedCallGenerator------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // Internal class which handles all out-of-line calls checking receiver type.
a61af66fc99e Initial load
duke
parents:
diff changeset
527 class PredictedCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 ciKlass* _predicted_receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 CallGenerator* _if_missed;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 CallGenerator* _if_hit;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 float _hit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
534 PredictedCallGenerator(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
535 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
536 CallGenerator* if_hit, float hit_prob)
a61af66fc99e Initial load
duke
parents:
diff changeset
537 : CallGenerator(if_missed->method())
a61af66fc99e Initial load
duke
parents:
diff changeset
538 {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // The call profile data may predict the hit_prob as extreme as 0 or 1.
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Remove the extremes values from the range.
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (hit_prob > PROB_MAX) hit_prob = PROB_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (hit_prob < PROB_MIN) hit_prob = PROB_MIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 _predicted_receiver = predicted_receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 _if_missed = if_missed;
a61af66fc99e Initial load
duke
parents:
diff changeset
546 _if_hit = if_hit;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 _hit_prob = hit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 virtual bool is_virtual() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 virtual bool is_inline() const { return _if_hit->is_inline(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 virtual bool is_deferred() const { return _if_hit->is_deferred(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 virtual JVMState* generate(JVMState* jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 };
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
559 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
560 CallGenerator* if_hit,
a61af66fc99e Initial load
duke
parents:
diff changeset
561 float hit_prob) {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit, hit_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
567 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 PhaseGVN& gvn = kit.gvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // We need an explicit receiver null_check before checking its type.
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // We share a map with the caller, so his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
571 Node* receiver = kit.argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 CompileLog* log = kit.C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
575 log->elem("predicted_call bci='%d' klass='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
576 jvms->bci(), log->identify(_predicted_receiver));
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 receiver = kit.null_check_receiver(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 Node* exact_receiver = receiver; // will get updated in place...
a61af66fc99e Initial load
duke
parents:
diff changeset
585 Node* slow_ctl = kit.type_check_receiver(receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
586 _predicted_receiver, _hit_prob,
a61af66fc99e Initial load
duke
parents:
diff changeset
587 &exact_receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 SafePointNode* slow_map = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 JVMState* slow_jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 { PreserveJVMState pjvms(&kit);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 kit.set_control(slow_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if (!kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 slow_jvms = _if_missed->generate(kit.sync_jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
595 assert(slow_jvms != NULL, "miss path must not fail to generate");
a61af66fc99e Initial load
duke
parents:
diff changeset
596 kit.add_exception_states_from(slow_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 kit.set_map(slow_jvms->map());
a61af66fc99e Initial load
duke
parents:
diff changeset
598 if (!kit.stopped())
a61af66fc99e Initial load
duke
parents:
diff changeset
599 slow_map = kit.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
603 if (kit.stopped()) {
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
604 // Instance exactly does not matches the desired type.
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
605 kit.set_jvms(slow_jvms);
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
606 return kit.transfer_exceptions_into_jvms();
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
607 }
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
608
0
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // fall through if the instance exactly matches the desired type
a61af66fc99e Initial load
duke
parents:
diff changeset
610 kit.replace_in_map(receiver, exact_receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // Make the hot call:
a61af66fc99e Initial load
duke
parents:
diff changeset
613 JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
614 if (new_jvms == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // Inline failed, so make a direct call.
a61af66fc99e Initial load
duke
parents:
diff changeset
616 assert(_if_hit->is_inline(), "must have been a failed inline");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method());
a61af66fc99e Initial load
duke
parents:
diff changeset
618 new_jvms = cg->generate(kit.sync_jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
619 }
a61af66fc99e Initial load
duke
parents:
diff changeset
620 kit.add_exception_states_from(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 kit.set_jvms(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Need to merge slow and fast?
a61af66fc99e Initial load
duke
parents:
diff changeset
624 if (slow_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // The fast path is the only path remaining.
a61af66fc99e Initial load
duke
parents:
diff changeset
626 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // Inlined method threw an exception, so it's just the slow path after all.
a61af66fc99e Initial load
duke
parents:
diff changeset
631 kit.set_jvms(slow_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // Finish the diamond.
a61af66fc99e Initial load
duke
parents:
diff changeset
636 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
637 RegionNode* region = new (kit.C, 3) RegionNode(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 region->init_req(1, kit.control());
a61af66fc99e Initial load
duke
parents:
diff changeset
639 region->init_req(2, slow_map->control());
a61af66fc99e Initial load
duke
parents:
diff changeset
640 kit.set_control(gvn.transform(region));
a61af66fc99e Initial load
duke
parents:
diff changeset
641 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
642 iophi->set_req(2, slow_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
643 kit.set_i_o(gvn.transform(iophi));
a61af66fc99e Initial load
duke
parents:
diff changeset
644 kit.merge_memory(slow_map->merged_memory(), region, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 uint tos = kit.jvms()->stkoff() + kit.sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
646 uint limit = slow_map->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
647 for (uint i = TypeFunc::Parms; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // Skip unused stack slots; fast forward to monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (i == tos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
650 i = kit.jvms()->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if( i >= limit ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
653 Node* m = kit.map()->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 Node* n = slow_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
655 if (m != n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 const Type* t = gvn.type(m)->meet(gvn.type(n));
a61af66fc99e Initial load
duke
parents:
diff changeset
657 Node* phi = PhiNode::make(region, m, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
658 phi->set_req(2, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
659 kit.map()->set_req(i, gvn.transform(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
666 //------------------------PredictedDynamicCallGenerator-----------------------
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
667 // Internal class which handles all out-of-line calls checking receiver type.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
668 class PredictedDynamicCallGenerator : public CallGenerator {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
669 ciMethodHandle* _predicted_method_handle;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
670 CallGenerator* _if_missed;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
671 CallGenerator* _if_hit;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
672 float _hit_prob;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
673
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
674 public:
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
675 PredictedDynamicCallGenerator(ciMethodHandle* predicted_method_handle,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
676 CallGenerator* if_missed,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
677 CallGenerator* if_hit,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
678 float hit_prob)
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
679 : CallGenerator(if_missed->method()),
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
680 _predicted_method_handle(predicted_method_handle),
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
681 _if_missed(if_missed),
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
682 _if_hit(if_hit),
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
683 _hit_prob(hit_prob)
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
684 {}
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
685
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
686 virtual bool is_inline() const { return _if_hit->is_inline(); }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
687 virtual bool is_deferred() const { return _if_hit->is_deferred(); }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
688
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
689 virtual JVMState* generate(JVMState* jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
690 };
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
691
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
692
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
693 CallGenerator* CallGenerator::for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
694 CallGenerator* if_missed,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
695 CallGenerator* if_hit,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
696 float hit_prob) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
697 return new PredictedDynamicCallGenerator(predicted_method_handle, if_missed, if_hit, hit_prob);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
698 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
699
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
700
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
701 JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
702 GraphKit kit(jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
703 PhaseGVN& gvn = kit.gvn();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
704
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
705 CompileLog* log = kit.C->log();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
706 if (log != NULL) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
707 log->elem("predicted_dynamic_call bci='%d'", jvms->bci());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
708 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
709
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
710 // Get the constant pool cache from the caller class.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
711 ciMethod* caller_method = jvms->method();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
712 ciBytecodeStream str(caller_method);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
713 str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
714 ciCPCache* cpcache = str.get_cpcache();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
715
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
716 // Get the offset of the CallSite from the constant pool cache
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
717 // pointer.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
718 int index = str.get_method_index();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
719 size_t call_site_offset = cpcache->get_f1_offset(index);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
720
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
721 // Load the CallSite object from the constant pool cache.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
722 const TypeOopPtr* cpcache_ptr = TypeOopPtr::make_from_constant(cpcache);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
723 Node* cpcache_adr = kit.makecon(cpcache_ptr);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
724 Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, cpcache_adr, call_site_offset);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
725 Node* call_site = kit.make_load(kit.control(), call_site_adr, TypeInstPtr::BOTTOM, T_OBJECT, Compile::AliasIdxRaw);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
726
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
727 // Load the target MethodHandle from the CallSite object.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
728 Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_dyn_CallSite::target_offset_in_bytes());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
729 Node* target_mh = kit.make_load(kit.control(), target_adr, TypeInstPtr::BOTTOM, T_OBJECT);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
730
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
731 // Check if the MethodHandle is still the same.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
732 const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
733 Node* predicted_mh = kit.makecon(predicted_mh_ptr);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
734
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
735 Node* cmp = gvn.transform(new(kit.C, 3) CmpPNode(target_mh, predicted_mh));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
736 Node* bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) );
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
737 IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
738 kit.set_control( gvn.transform(new(kit.C, 1) IfTrueNode (iff)));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
739 Node* slow_ctl = gvn.transform(new(kit.C, 1) IfFalseNode(iff));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
740
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
741 SafePointNode* slow_map = NULL;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
742 JVMState* slow_jvms;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
743 { PreserveJVMState pjvms(&kit);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
744 kit.set_control(slow_ctl);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
745 if (!kit.stopped()) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
746 slow_jvms = _if_missed->generate(kit.sync_jvms());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
747 assert(slow_jvms != NULL, "miss path must not fail to generate");
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
748 kit.add_exception_states_from(slow_jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
749 kit.set_map(slow_jvms->map());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
750 if (!kit.stopped())
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
751 slow_map = kit.stop();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
752 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
753 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
754
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
755 if (kit.stopped()) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
756 // Instance exactly does not matches the desired type.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
757 kit.set_jvms(slow_jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
758 return kit.transfer_exceptions_into_jvms();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
759 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
760
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
761 // Make the hot call:
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
762 JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
763 if (new_jvms == NULL) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
764 // Inline failed, so make a direct call.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
765 assert(_if_hit->is_inline(), "must have been a failed inline");
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
766 CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
767 new_jvms = cg->generate(kit.sync_jvms());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
768 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
769 kit.add_exception_states_from(new_jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
770 kit.set_jvms(new_jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
771
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
772 // Need to merge slow and fast?
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
773 if (slow_map == NULL) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
774 // The fast path is the only path remaining.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
775 return kit.transfer_exceptions_into_jvms();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
776 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
777
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
778 if (kit.stopped()) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
779 // Inlined method threw an exception, so it's just the slow path after all.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
780 kit.set_jvms(slow_jvms);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
781 return kit.transfer_exceptions_into_jvms();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
782 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
783
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
784 // Finish the diamond.
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
785 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
786 RegionNode* region = new (kit.C, 3) RegionNode(3);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
787 region->init_req(1, kit.control());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
788 region->init_req(2, slow_map->control());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
789 kit.set_control(gvn.transform(region));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
790 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
791 iophi->set_req(2, slow_map->i_o());
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
792 kit.set_i_o(gvn.transform(iophi));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
793 kit.merge_memory(slow_map->merged_memory(), region, 2);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
794 uint tos = kit.jvms()->stkoff() + kit.sp();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
795 uint limit = slow_map->req();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
796 for (uint i = TypeFunc::Parms; i < limit; i++) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
797 // Skip unused stack slots; fast forward to monoff();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
798 if (i == tos) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
799 i = kit.jvms()->monoff();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
800 if( i >= limit ) break;
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
801 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
802 Node* m = kit.map()->in(i);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
803 Node* n = slow_map->in(i);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
804 if (m != n) {
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
805 const Type* t = gvn.type(m)->meet(gvn.type(n));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
806 Node* phi = PhiNode::make(region, m, t);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
807 phi->set_req(2, n);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
808 kit.map()->set_req(i, gvn.transform(phi));
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
809 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
810 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
811 return kit.transfer_exceptions_into_jvms();
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
812 }
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
813
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
814
0
a61af66fc99e Initial load
duke
parents:
diff changeset
815 //-------------------------UncommonTrapCallGenerator-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // Internal class which handles all out-of-line calls checking receiver type.
a61af66fc99e Initial load
duke
parents:
diff changeset
817 class UncommonTrapCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 Deoptimization::DeoptReason _reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 Deoptimization::DeoptAction _action;
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
822 UncommonTrapCallGenerator(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
823 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
824 Deoptimization::DeoptAction action)
a61af66fc99e Initial load
duke
parents:
diff changeset
825 : CallGenerator(m)
a61af66fc99e Initial load
duke
parents:
diff changeset
826 {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 _reason = reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 _action = action;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 virtual bool is_virtual() const { ShouldNotReachHere(); return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
832 virtual bool is_trap() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 virtual JVMState* generate(JVMState* jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
835 };
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 CallGenerator*
a61af66fc99e Initial load
duke
parents:
diff changeset
839 CallGenerator::for_uncommon_trap(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
840 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
841 Deoptimization::DeoptAction action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 return new UncommonTrapCallGenerator(m, reason, action);
a61af66fc99e Initial load
duke
parents:
diff changeset
843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver).
a61af66fc99e Initial load
duke
parents:
diff changeset
849 int nargs = method()->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
850 kit.inc_sp(nargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
a61af66fc99e Initial load
duke
parents:
diff changeset
852 if (_reason == Deoptimization::Reason_class_check &&
a61af66fc99e Initial load
duke
parents:
diff changeset
853 _action == Deoptimization::Action_maybe_recompile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // Temp fix for 6529811
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // Don't allow uncommon_trap to override our decision to recompile in the event
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // of a class cast failure for a monomorphic call as it will never let us convert
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // the call to either bi-morphic or megamorphic and can lead to unc-trap loops
a61af66fc99e Initial load
duke
parents:
diff changeset
858 bool keep_exact_action = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action);
a61af66fc99e Initial load
duke
parents:
diff changeset
860 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 kit.uncommon_trap(_reason, _action);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // (Note: Moved hook_up_call to GraphKit::set_edges_for_java_call.)
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // (Node: Merged hook_up_exits into ParseGenerator::generate.)
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 #define NODES_OVERHEAD_PER_METHOD (30.0)
a61af66fc99e Initial load
duke
parents:
diff changeset
871 #define NODES_PER_BYTECODE (9.5)
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 void WarmCallInfo::init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
874 int call_count = profile.count();
a61af66fc99e Initial load
duke
parents:
diff changeset
875 int code_size = call_method->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Expected execution count is based on the historical count:
a61af66fc99e Initial load
duke
parents:
diff changeset
878 _count = call_count < 0 ? 1 : call_site->method()->scale_count(call_count, prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
879
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // Expected profit from inlining, in units of simple call-overheads.
a61af66fc99e Initial load
duke
parents:
diff changeset
881 _profit = 1.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // Expected work performed by the call in units of call-overheads.
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // %%% need an empirical curve fit for "work" (time in call)
a61af66fc99e Initial load
duke
parents:
diff changeset
885 float bytecodes_per_call = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
886 _work = 1.0 + code_size / bytecodes_per_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // Expected size of compilation graph:
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // -XX:+PrintParseStatistics once reported:
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // Methods seen: 9184 Methods parsed: 9184 Nodes created: 1582391
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // Histogram of 144298 parsed bytecodes:
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // %%% Need an better predictor for graph size.
a61af66fc99e Initial load
duke
parents:
diff changeset
893 _size = NODES_OVERHEAD_PER_METHOD + (NODES_PER_BYTECODE * code_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // is_cold: Return true if the node should never be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // This is true if any of the key metrics are extreme.
a61af66fc99e Initial load
duke
parents:
diff changeset
898 bool WarmCallInfo::is_cold() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 if (count() < WarmCallMinCount) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
900 if (profit() < WarmCallMinProfit) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 if (work() > WarmCallMaxWork) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (size() > WarmCallMaxSize) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // is_hot: Return true if the node should be inlined immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // This is true if any of the key metrics are extreme.
a61af66fc99e Initial load
duke
parents:
diff changeset
908 bool WarmCallInfo::is_hot() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 assert(!is_cold(), "eliminate is_cold cases before testing is_hot");
a61af66fc99e Initial load
duke
parents:
diff changeset
910 if (count() >= HotCallCountThreshold) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
911 if (profit() >= HotCallProfitThreshold) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if (work() <= HotCallTrivialWork) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 if (size() <= HotCallTrivialSize) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
914 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // compute_heat:
a61af66fc99e Initial load
duke
parents:
diff changeset
918 float WarmCallInfo::compute_heat() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 assert(!is_cold(), "compute heat only on warm nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
920 assert(!is_hot(), "compute heat only on warm nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
921 int min_size = MAX2(0, (int)HotCallTrivialSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
922 int max_size = MIN2(500, (int)WarmCallMaxSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
923 float method_size = (size() - min_size) / MAX2(1, max_size - min_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 float size_factor;
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (method_size < 0.05) size_factor = 4; // 2 sigmas better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
926 else if (method_size < 0.15) size_factor = 2; // 1 sigma better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
927 else if (method_size < 0.5) size_factor = 1; // better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
928 else size_factor = 0.5; // worse than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
929 return (count() * profit() * size_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 bool WarmCallInfo::warmer_than(WarmCallInfo* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 assert(this != that, "compare only different WCIs");
a61af66fc99e Initial load
duke
parents:
diff changeset
934 assert(this->heat() != 0 && that->heat() != 0, "call compute_heat 1st");
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (this->heat() > that->heat()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (this->heat() < that->heat()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 assert(this->heat() == that->heat(), "no NaN heat allowed");
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // Equal heat. Break the tie some other way.
a61af66fc99e Initial load
duke
parents:
diff changeset
939 if (!this->call() || !that->call()) return (address)this > (address)that;
a61af66fc99e Initial load
duke
parents:
diff changeset
940 return this->call()->_idx > that->call()->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 //#define UNINIT_NEXT ((WarmCallInfo*)badAddress)
a61af66fc99e Initial load
duke
parents:
diff changeset
944 #define UNINIT_NEXT ((WarmCallInfo*)NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946 WarmCallInfo* WarmCallInfo::insert_into(WarmCallInfo* head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 assert(next() == UNINIT_NEXT, "not yet on any list");
a61af66fc99e Initial load
duke
parents:
diff changeset
948 WarmCallInfo* prev_p = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 WarmCallInfo* next_p = head;
a61af66fc99e Initial load
duke
parents:
diff changeset
950 while (next_p != NULL && next_p->warmer_than(this)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
951 prev_p = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 next_p = prev_p->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // Install this between prev_p and next_p.
a61af66fc99e Initial load
duke
parents:
diff changeset
955 this->set_next(next_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 if (prev_p == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
957 head = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 else
a61af66fc99e Initial load
duke
parents:
diff changeset
959 prev_p->set_next(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
960 return head;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
962
a61af66fc99e Initial load
duke
parents:
diff changeset
963 WarmCallInfo* WarmCallInfo::remove_from(WarmCallInfo* head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 WarmCallInfo* prev_p = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 WarmCallInfo* next_p = head;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 while (next_p != this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 assert(next_p != NULL, "this must be in the list somewhere");
a61af66fc99e Initial load
duke
parents:
diff changeset
968 prev_p = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 next_p = prev_p->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
971 next_p = this->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
972 debug_only(this->set_next(UNINIT_NEXT));
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // Remove this from between prev_p and next_p.
a61af66fc99e Initial load
duke
parents:
diff changeset
974 if (prev_p == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
975 head = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 else
a61af66fc99e Initial load
duke
parents:
diff changeset
977 prev_p->set_next(next_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 return head;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 WarmCallInfo* WarmCallInfo::_always_hot = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 WarmCallInfo* WarmCallInfo::_always_cold = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 WarmCallInfo* WarmCallInfo::always_hot() {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if (_always_hot == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
986 static double bits[sizeof(WarmCallInfo) / sizeof(double) + 1] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
987 WarmCallInfo* ci = (WarmCallInfo*) bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
988 ci->_profit = ci->_count = MAX_VALUE();
a61af66fc99e Initial load
duke
parents:
diff changeset
989 ci->_work = ci->_size = MIN_VALUE();
a61af66fc99e Initial load
duke
parents:
diff changeset
990 _always_hot = ci;
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 assert(_always_hot->is_hot(), "must always be hot");
a61af66fc99e Initial load
duke
parents:
diff changeset
993 return _always_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
995
a61af66fc99e Initial load
duke
parents:
diff changeset
996 WarmCallInfo* WarmCallInfo::always_cold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if (_always_cold == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 static double bits[sizeof(WarmCallInfo) / sizeof(double) + 1] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
999 WarmCallInfo* ci = (WarmCallInfo*) bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 ci->_profit = ci->_count = MIN_VALUE();
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 ci->_work = ci->_size = MAX_VALUE();
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 _always_cold = ci;
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 assert(_always_cold->is_cold(), "must always be cold");
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 return _always_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 void WarmCallInfo::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 tty->print("%s : C=%6.1f P=%6.1f W=%6.1f S=%6.1f H=%6.1f -> %p",
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 is_cold() ? "cold" : is_hot() ? "hot " : "warm",
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 count(), profit(), work(), size(), compute_heat(), next());
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 if (call() != NULL) call()->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 void print_wci(WarmCallInfo* ci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 ci->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 void WarmCallInfo::print_all() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 for (const WarmCallInfo* p = this; p != NULL; p = p->next())
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 p->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 int WarmCallInfo::count_all() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 int cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 for (const WarmCallInfo* p = this; p != NULL; p = p->next())
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 cnt++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 #endif //PRODUCT