annotate src/share/vm/opto/callGenerator.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents de95063c0e34
children 45467c53f178
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17467
55fb97c4c58d 8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents: 13081
diff changeset
2 * Copyright (c) 2000, 2013, 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"
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
27 #include "ci/ciCallSite.hpp"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
28 #include "ci/ciObjArray.hpp"
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
29 #include "ci/ciMemberName.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "ci/ciMethodHandle.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "classfile/javaClasses.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #include "opto/callGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
40 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
41 #include "opto/subnode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Utility function.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 const TypeFunc* CallGenerator::tf() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 return TypeFunc::make(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 //-----------------------------ParseGenerator---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Internal class which handles all direct bytecode traversal.
a61af66fc99e Initial load
duke
parents:
diff changeset
51 class ParseGenerator : public InlineCallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
52 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
53 bool _is_osr;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 float _expected_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
57 ParseGenerator(ciMethod* method, float expected_uses, bool is_osr = false)
a61af66fc99e Initial load
duke
parents:
diff changeset
58 : InlineCallGenerator(method)
a61af66fc99e Initial load
duke
parents:
diff changeset
59 {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _is_osr = is_osr;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _expected_uses = expected_uses;
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3894
diff changeset
62 assert(InlineTree::check_can_parse(method) == NULL, "parse must be possible");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 virtual bool is_parse() const { return true; }
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
66 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
67 int is_osr() { return _is_osr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 };
a61af66fc99e Initial load
duke
parents:
diff changeset
70
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
71 JVMState* ParseGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
72 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if (is_osr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // The JVMS for a OSR has a single argument (see its TypeFunc).
a61af66fc99e Initial load
duke
parents:
diff changeset
76 assert(jvms->depth() == 1, "no inline OSR");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if (C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 return NULL; // bailing out of the compile; do not try to parse
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
83 Parse parser(jvms, method(), _expected_uses, parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Grab signature for matching/allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
86 if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 assert(C->env()->system_dictionary_modification_counter_changed(),
a61af66fc99e Initial load
duke
parents:
diff changeset
89 "Must invalidate if TypeFuncs differ");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 GraphKit& exits = parser.exits();
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 if (C->failing()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 while (exits.pop_exception_state() != NULL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 assert(exits.jvms()->same_calls_as(jvms), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Simply return the exit state of the parser,
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // augmented by any exceptional states.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 return exits.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 //---------------------------DirectCallGenerator------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Internal class which handles all out-of-line calls w/o receiver type checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
109 class DirectCallGenerator : public CallGenerator {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
110 private:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
111 CallStaticJavaNode* _call_node;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
112 // Force separate memory and I/O projections for the exceptional
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
113 // paths to facilitate late inlinig.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
114 bool _separate_io_proj;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
115
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
116 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
117 DirectCallGenerator(ciMethod* method, bool separate_io_proj)
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
118 : CallGenerator(method),
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
119 _separate_io_proj(separate_io_proj)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
122 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
123
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
124 CallStaticJavaNode* call_node() const { return _call_node; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
125 };
a61af66fc99e Initial load
duke
parents:
diff changeset
126
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
127 JVMState* DirectCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
128 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 bool is_static = method()->is_static();
a61af66fc99e Initial load
duke
parents:
diff changeset
130 address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
a61af66fc99e Initial load
duke
parents:
diff changeset
131 : SharedRuntime::get_resolve_opt_virtual_call_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (kit.C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
137 CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(kit.C, tf(), target, method(), kit.bci());
6042
847da049d62f 7162094: LateInlineCallGenerator::do_late_inline crashed on uninitialized _call_node
never
parents: 4117
diff changeset
138 _call_node = call; // Save the call node in case we need it later
0
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if (!is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Make an explicit receiver null_check as part of this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Since we share a map with the caller, his JVMS gets adjusted.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
142 kit.null_check_receiver_before_call(method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // And dump it back to the caller, decorated with any exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
145 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // Mark the call node as virtual, sort of:
a61af66fc99e Initial load
duke
parents:
diff changeset
148 call->set_optimized_virtual(true);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
149 if (method()->is_method_handle_intrinsic() ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
150 method()->is_compiled_lambda_form()) {
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
151 call->set_method_handle_invoke(true);
1265
b4b440360f1e 6926782: CodeBuffer size too small after 6921352
twisti
parents: 1138
diff changeset
152 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 kit.set_arguments_for_java_call(call);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
155 kit.set_edges_for_java_call(call, false, _separate_io_proj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
156 Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
157 kit.push_node(method()->return_type()->basic_type(), ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
161 //--------------------------VirtualCallGenerator------------------------------
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
162 // Internal class which handles all out-of-line calls checking receiver type.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 class VirtualCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
165 int _vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
167 VirtualCallGenerator(ciMethod* method, int vtable_index)
a61af66fc99e Initial load
duke
parents:
diff changeset
168 : CallGenerator(method), _vtable_index(vtable_index)
a61af66fc99e Initial load
duke
parents:
diff changeset
169 {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
170 assert(vtable_index == Method::invalid_vtable_index ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
171 vtable_index >= 0, "either invalid or usable");
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 virtual bool is_virtual() const { return true; }
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
174 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
175 };
a61af66fc99e Initial load
duke
parents:
diff changeset
176
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
177 JVMState* VirtualCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
178 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 Node* receiver = kit.argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if (kit.C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 kit.C->log()->elem("virtual_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // If the receiver is a constant null, do not torture the system
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // by attempting to call through it. The compile will proceed
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // correctly, but may bail out in final_graph_reshaping, because
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // the call instruction will have a seemingly deficient out-count.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // (The bailout says something misleading about an "infinite loop".)
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (kit.gvn().type(receiver)->higher_equal(TypePtr::NULL_PTR)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 kit.inc_sp(method()->arg_size()); // restore arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
192 kit.uncommon_trap(Deoptimization::Reason_null_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
193 Deoptimization::Action_none,
a61af66fc99e Initial load
duke
parents:
diff changeset
194 NULL, "null receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
195 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Ideally we would unconditionally do a null check here and let it
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // be converted to an implicit check based on profile information.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // However currently the conversion to implicit null checks in
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Block::implicit_null_check() only looks for loads and stores, not calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
202 ciMethod *caller = kit.method();
a61af66fc99e Initial load
duke
parents:
diff changeset
203 ciMethodData *caller_md = (caller == NULL) ? NULL : caller->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (!UseInlineCaches || !ImplicitNullChecks ||
a61af66fc99e Initial load
duke
parents:
diff changeset
205 ((ImplicitNullCheckThreshold > 0) && caller_md &&
a61af66fc99e Initial load
duke
parents:
diff changeset
206 (caller_md->trap_count(Deoptimization::Reason_null_check)
a61af66fc99e Initial load
duke
parents:
diff changeset
207 >= (uint)ImplicitNullCheckThreshold))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // Make an explicit receiver null_check as part of this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // Since we share a map with the caller, his JVMS gets adjusted.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
210 receiver = kit.null_check_receiver_before_call(method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // And dump it back to the caller, decorated with any exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 assert(!method()->is_static(), "virtual call must not be to static");
a61af66fc99e Initial load
duke
parents:
diff changeset
218 assert(!method()->is_final(), "virtual call should not be to final");
a61af66fc99e Initial load
duke
parents:
diff changeset
219 assert(!method()->is_private(), "virtual call should not be to private");
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
220 assert(_vtable_index == Method::invalid_vtable_index || !UseInlineCaches,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
221 "no vtable calls if +UseInlineCaches ");
a61af66fc99e Initial load
duke
parents:
diff changeset
222 address target = SharedRuntime::get_resolve_virtual_call_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // Normal inline cache used for call
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
224 CallDynamicJavaNode *call = new (kit.C) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
225 kit.set_arguments_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 kit.set_edges_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
227 Node* ret = kit.set_results_for_java_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 kit.push_node(method()->return_type()->basic_type(), ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // Represent the effect of an implicit receiver null_check
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // as part of this call. Since we share a map with the caller,
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
233 kit.cast_not_null(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 CallGenerator* CallGenerator::for_inline(ciMethod* m, float expected_uses) {
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3894
diff changeset
238 if (InlineTree::check_can_parse(m) != NULL) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
239 return new ParseGenerator(m, expected_uses);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // As a special case, the JVMS passed to this CallGenerator is
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // for the method execution already in progress, not just the JVMS
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // of the caller. Thus, this CallGenerator cannot be mixed with others!
a61af66fc99e Initial load
duke
parents:
diff changeset
245 CallGenerator* CallGenerator::for_osr(ciMethod* m, int osr_bci) {
3900
a32de5085326 7079673: JSR 292: C1 should inline bytecoded method handle adapters
twisti
parents: 3894
diff changeset
246 if (InlineTree::check_can_parse(m) != NULL) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 float past_uses = m->interpreter_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
248 float expected_uses = past_uses;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return new ParseGenerator(m, expected_uses, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
252 CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
253 assert(!m->is_abstract(), "for_direct_call mismatch");
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
254 return new DirectCallGenerator(m, separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 assert(!m->is_static(), "for_virtual_call mismatch");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
259 assert(!m->is_method_handle_intrinsic(), "should be a direct call");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
260 return new VirtualCallGenerator(m, vtable_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
263 // Allow inlining decisions to be delayed
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
264 class LateInlineCallGenerator : public DirectCallGenerator {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
265 protected:
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
266 CallGenerator* _inline_cg;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
267
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
268 virtual bool do_late_inline_check(JVMState* jvms) { return true; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
269
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
270 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
271 LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
272 DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
273
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
274 virtual bool is_late_inline() const { return true; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
275
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
276 // Convert the CallStaticJava into an inline
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
277 virtual void do_late_inline();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
278
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
279 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
280 Compile *C = Compile::current();
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
281 C->print_inlining_skip(this);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
282
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
283 // Record that this call site should be revisited once the main
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
284 // parse is finished.
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
285 if (!is_mh_late_inline()) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
286 C->add_late_inline(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
287 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
288
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
289 // Emit the CallStaticJava and request separate projections so
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
290 // that the late inlining logic can distinguish between fall
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
291 // through and exceptional uses of the memory and io projections
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
292 // as is done for allocations and macro expansion.
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
293 return DirectCallGenerator::generate(jvms, parent_parser);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
294 }
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
295
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
296 virtual void print_inlining_late(const char* msg) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
297 CallNode* call = call_node();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
298 Compile* C = Compile::current();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
299 C->print_inlining_insert(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
300 C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
301 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
302
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
303 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
304
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
305 void LateInlineCallGenerator::do_late_inline() {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
306 // Can't inline it
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
307 CallStaticJavaNode* call = call_node();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
308 if (call == NULL || call->outcnt() == 0 ||
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
309 call->in(0) == NULL || call->in(0)->is_top()) {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
310 return;
7997
8bd61471a109 8007144: Incremental inlining mistakes some call sites for dead ones and doesn't inline them
roland
parents: 7478
diff changeset
311 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
312
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
313 const TypeTuple *r = call->tf()->domain();
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
314 for (int i1 = 0; i1 < method()->arg_size(); i1++) {
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
315 if (call->in(TypeFunc::Parms + i1)->is_top() && r->field_at(TypeFunc::Parms + i1) != Type::HALF) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
316 assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
317 return;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
318 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
319 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
320
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
321 if (call->in(TypeFunc::Memory)->is_top()) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
322 assert(Compile::current()->inlining_incrementally(), "shouldn't happen during parsing");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
323 return;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
324 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
325
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
326 Compile* C = Compile::current();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
327 // Remove inlined methods from Compiler's lists.
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
328 if (call->is_macro()) {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
329 C->remove_macro_node(call);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
330 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
331
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
332 // Make a clone of the JVMState that appropriate to use for driving a parse
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
333 JVMState* old_jvms = call->jvms();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
334 JVMState* jvms = old_jvms->clone_shallow(C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
335 uint size = call->req();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
336 SafePointNode* map = new (C) SafePointNode(size, jvms);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
337 for (uint i1 = 0; i1 < size; i1++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
338 map->init_req(i1, call->in(i1));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
339 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
340
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
341 // Make sure the state is a MergeMem for parsing.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
342 if (!map->in(TypeFunc::Memory)->is_MergeMem()) {
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
343 Node* mem = MergeMemNode::make(C, map->in(TypeFunc::Memory));
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
344 C->initial_gvn()->set_type_bottom(mem);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
345 map->set_req(TypeFunc::Memory, mem);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
346 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
347
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
348 uint nargs = method()->arg_size();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
349 // blow away old call arguments
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
350 Node* top = C->top();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
351 for (uint i1 = 0; i1 < nargs; i1++) {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
352 map->set_req(TypeFunc::Parms + i1, top);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
353 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
354 jvms->set_map(map);
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
355
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
356 // Make enough space in the expression stack to transfer
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
357 // the incoming arguments and return value.
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
358 map->ensure_stack(jvms, jvms->method()->max_stack());
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
359 for (uint i1 = 0; i1 < nargs; i1++) {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
360 map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
361 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
362
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
363 // This check is done here because for_method_handle_inline() method
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
364 // needs jvms for inlined state.
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
365 if (!do_late_inline_check(jvms)) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
366 map->disconnect_inputs(NULL, C);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
367 return;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
368 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
369
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
370 C->print_inlining_insert(this);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7194
diff changeset
371
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
372 CompileLog* log = C->log();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
373 if (log != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
374 log->head("late_inline method='%d'", log->identify(method()));
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
375 JVMState* p = jvms;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
376 while (p != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
377 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
378 p = p->caller();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
379 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
380 log->tail("late_inline");
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
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
383 // Setup default node notes to be picked up by the inlining
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
384 Node_Notes* old_nn = C->default_node_notes();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
385 if (old_nn != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
386 Node_Notes* entry_nn = old_nn->clone(C);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
387 entry_nn->set_jvms(jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
388 C->set_default_node_notes(entry_nn);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
389 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
390
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
391 // Now perform the inling using the synthesized JVMState
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
392 JVMState* new_jvms = _inline_cg->generate(jvms, NULL);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
393 if (new_jvms == NULL) return; // no change
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
394 if (C->failing()) return;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
395
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
396 // Capture any exceptional control flow
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
397 GraphKit kit(new_jvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
398
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
399 // Find the result object
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
400 Node* result = C->top();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
401 int result_size = method()->return_type()->size();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
402 if (result_size != 0 && !kit.stopped()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
403 result = (result_size == 1) ? kit.pop() : kit.pop_pair();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
404 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
405
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
406 C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
407 C->env()->notice_inlined_method(_inline_cg->method());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
408 C->set_inlining_progress(true);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
409
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
410 kit.replace_call(call, result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
411 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
412
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
413
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
414 CallGenerator* CallGenerator::for_late_inline(ciMethod* method, CallGenerator* inline_cg) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
415 return new LateInlineCallGenerator(method, inline_cg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
416 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
417
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
418 class LateInlineMHCallGenerator : public LateInlineCallGenerator {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
419 ciMethod* _caller;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
420 int _attempt;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
421 bool _input_not_const;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
422
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
423 virtual bool do_late_inline_check(JVMState* jvms);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
424 virtual bool already_attempted() const { return _attempt > 0; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
425
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
426 public:
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
427 LateInlineMHCallGenerator(ciMethod* caller, ciMethod* callee, bool input_not_const) :
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
428 LateInlineCallGenerator(callee, NULL), _caller(caller), _attempt(0), _input_not_const(input_not_const) {}
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
429
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
430 virtual bool is_mh_late_inline() const { return true; }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
431
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
432 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
433 JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
434 if (_input_not_const) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
435 // inlining won't be possible so no need to enqueue right now.
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
436 call_node()->set_generator(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
437 } else {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
438 Compile::current()->add_late_inline(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
439 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
440 return new_jvms;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
441 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
442
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
443 virtual void print_inlining_late(const char* msg) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
444 if (!_input_not_const) return;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
445 LateInlineCallGenerator::print_inlining_late(msg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
446 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
447 };
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
448
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
449 bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
450
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
451 CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
452
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
453 if (!_input_not_const) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
454 _attempt++;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
455 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
456
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
457 if (cg != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
458 assert(!cg->is_late_inline() && cg->is_inline(), "we're doing late inlining");
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
459 _inline_cg = cg;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
460 Compile::current()->dec_number_of_mh_late_inlines();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
461 return true;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
462 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
463
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
464 call_node()->set_generator(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
465 return false;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
466 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
467
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
468 CallGenerator* CallGenerator::for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
469 Compile::current()->inc_number_of_mh_late_inlines();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
470 CallGenerator* cg = new LateInlineMHCallGenerator(caller, callee, input_not_const);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
471 return cg;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
472 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
474 class LateInlineStringCallGenerator : public LateInlineCallGenerator {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
475
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
476 public:
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
477 LateInlineStringCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
478 LateInlineCallGenerator(method, inline_cg) {}
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
479
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
480 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
481 Compile *C = Compile::current();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
482 C->print_inlining_skip(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
483
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
484 C->add_string_late_inline(this);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
485
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
486 JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
487 return new_jvms;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
488 }
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
489
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
490 virtual bool is_string_late_inline() const { return true; }
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
491 };
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
492
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
493 CallGenerator* CallGenerator::for_string_late_inline(ciMethod* method, CallGenerator* inline_cg) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
494 return new LateInlineStringCallGenerator(method, inline_cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
495 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
496
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
497 class LateInlineBoxingCallGenerator : public LateInlineCallGenerator {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
498
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
499 public:
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
500 LateInlineBoxingCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
501 LateInlineCallGenerator(method, inline_cg) {}
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
502
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
503 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
504 Compile *C = Compile::current();
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
505 C->print_inlining_skip(this);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
506
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
507 C->add_boxing_late_inline(this);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
508
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
509 JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
510 return new_jvms;
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
511 }
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
512 };
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
513
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
514 CallGenerator* CallGenerator::for_boxing_late_inline(ciMethod* method, CallGenerator* inline_cg) {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
515 return new LateInlineBoxingCallGenerator(method, inline_cg);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 7997
diff changeset
516 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 //---------------------------WarmCallGenerator--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // Internal class which handles initial deferral of inlining decisions.
a61af66fc99e Initial load
duke
parents:
diff changeset
520 class WarmCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 WarmCallInfo* _call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 CallGenerator* _if_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
523 CallGenerator* _if_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
524 bool _is_virtual; // caches virtuality of if_cold
a61af66fc99e Initial load
duke
parents:
diff changeset
525 bool _is_inline; // caches inline-ness of if_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
528 WarmCallGenerator(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
529 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
530 CallGenerator* if_hot)
a61af66fc99e Initial load
duke
parents:
diff changeset
531 : CallGenerator(if_cold->method())
a61af66fc99e Initial load
duke
parents:
diff changeset
532 {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 assert(method() == if_hot->method(), "consistent choices");
a61af66fc99e Initial load
duke
parents:
diff changeset
534 _call_info = ci;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 _if_cold = if_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 _if_hot = if_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
537 _is_virtual = if_cold->is_virtual();
a61af66fc99e Initial load
duke
parents:
diff changeset
538 _is_inline = if_hot->is_inline();
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540
a61af66fc99e Initial load
duke
parents:
diff changeset
541 virtual bool is_inline() const { return _is_inline; }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 virtual bool is_virtual() const { return _is_virtual; }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 virtual bool is_deferred() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
545 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
546 };
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 CallGenerator* CallGenerator::for_warm_call(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
550 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
551 CallGenerator* if_hot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 return new WarmCallGenerator(ci, if_cold, if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
555 JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
556 Compile* C = Compile::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (C->log() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 C->log()->elem("warm_call bci='%d'", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
560 jvms = _if_cold->generate(jvms, parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
561 if (jvms != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 Node* m = jvms->map()->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if (m->is_CatchProj()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if (m->is_Catch()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (m->is_Proj()) m = m->in(0); else m = C->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 if (m->is_CallJava()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
567 _call_info->set_call(m->as_Call());
a61af66fc99e Initial load
duke
parents:
diff changeset
568 _call_info->set_hot_cg(_if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
570 if (PrintOpto || PrintOptoInlining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 tty->print_cr("Queueing for warm inlining at bci %d:", jvms->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
572 tty->print("WCI: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
573 _call_info->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
576 _call_info->set_heat(_call_info->compute_heat());
a61af66fc99e Initial load
duke
parents:
diff changeset
577 C->set_warm_calls(_call_info->insert_into(C->warm_calls()));
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 void WarmCallInfo::make_hot() {
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 337
diff changeset
584 Unimplemented();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 void WarmCallInfo::make_cold() {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // No action: Just dequeue.
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 //------------------------PredictedCallGenerator------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // Internal class which handles all out-of-line calls checking receiver type.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 class PredictedCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 ciKlass* _predicted_receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 CallGenerator* _if_missed;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 CallGenerator* _if_hit;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 float _hit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
601 PredictedCallGenerator(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
602 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
603 CallGenerator* if_hit, float hit_prob)
a61af66fc99e Initial load
duke
parents:
diff changeset
604 : CallGenerator(if_missed->method())
a61af66fc99e Initial load
duke
parents:
diff changeset
605 {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // The call profile data may predict the hit_prob as extreme as 0 or 1.
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // Remove the extremes values from the range.
a61af66fc99e Initial load
duke
parents:
diff changeset
608 if (hit_prob > PROB_MAX) hit_prob = PROB_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (hit_prob < PROB_MIN) hit_prob = PROB_MIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
610
a61af66fc99e Initial load
duke
parents:
diff changeset
611 _predicted_receiver = predicted_receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 _if_missed = if_missed;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 _if_hit = if_hit;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 _hit_prob = hit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 virtual bool is_virtual() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
618 virtual bool is_inline() const { return _if_hit->is_inline(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
619 virtual bool is_deferred() const { return _if_hit->is_deferred(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
620
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
621 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
622 };
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
626 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
627 CallGenerator* if_hit,
a61af66fc99e Initial load
duke
parents:
diff changeset
628 float hit_prob) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit, hit_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
633 JVMState* PredictedCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
634 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 PhaseGVN& gvn = kit.gvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // We need an explicit receiver null_check before checking its type.
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // We share a map with the caller, so his JVMS gets adjusted.
a61af66fc99e Initial load
duke
parents:
diff changeset
638 Node* receiver = kit.argument(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 CompileLog* log = kit.C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
641 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 log->elem("predicted_call bci='%d' klass='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
643 jvms->bci(), log->identify(_predicted_receiver));
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
646 receiver = kit.null_check_receiver_before_call(method());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 Node* exact_receiver = receiver; // will get updated in place...
a61af66fc99e Initial load
duke
parents:
diff changeset
652 Node* slow_ctl = kit.type_check_receiver(receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
653 _predicted_receiver, _hit_prob,
a61af66fc99e Initial load
duke
parents:
diff changeset
654 &exact_receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 SafePointNode* slow_map = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 JVMState* slow_jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 { PreserveJVMState pjvms(&kit);
a61af66fc99e Initial load
duke
parents:
diff changeset
659 kit.set_control(slow_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 if (!kit.stopped()) {
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
661 slow_jvms = _if_missed->generate(kit.sync_jvms(), parent_parser);
4117
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 4062
diff changeset
662 if (kit.failing())
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 4062
diff changeset
663 return NULL; // might happen because of NodeCountInliningCutoff
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 4062
diff changeset
664 assert(slow_jvms != NULL, "must be");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
665 kit.add_exception_states_from(slow_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 kit.set_map(slow_jvms->map());
a61af66fc99e Initial load
duke
parents:
diff changeset
667 if (!kit.stopped())
a61af66fc99e Initial load
duke
parents:
diff changeset
668 slow_map = kit.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671
293
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
672 if (kit.stopped()) {
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
673 // 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
674 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
675 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
676 }
c3e045194476 6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents: 0
diff changeset
677
0
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // fall through if the instance exactly matches the desired type
a61af66fc99e Initial load
duke
parents:
diff changeset
679 kit.replace_in_map(receiver, exact_receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Make the hot call:
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
682 JVMState* new_jvms = _if_hit->generate(kit.sync_jvms(), parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
683 if (new_jvms == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Inline failed, so make a direct call.
a61af66fc99e Initial load
duke
parents:
diff changeset
685 assert(_if_hit->is_inline(), "must have been a failed inline");
a61af66fc99e Initial load
duke
parents:
diff changeset
686 CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method());
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
687 new_jvms = cg->generate(kit.sync_jvms(), parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 kit.add_exception_states_from(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 kit.set_jvms(new_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // Need to merge slow and fast?
a61af66fc99e Initial load
duke
parents:
diff changeset
693 if (slow_map == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // The fast path is the only path remaining.
a61af66fc99e Initial load
duke
parents:
diff changeset
695 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 if (kit.stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // Inlined method threw an exception, so it's just the slow path after all.
a61af66fc99e Initial load
duke
parents:
diff changeset
700 kit.set_jvms(slow_jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // Finish the diamond.
a61af66fc99e Initial load
duke
parents:
diff changeset
705 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
706 RegionNode* region = new (kit.C) RegionNode(3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
707 region->init_req(1, kit.control());
a61af66fc99e Initial load
duke
parents:
diff changeset
708 region->init_req(2, slow_map->control());
a61af66fc99e Initial load
duke
parents:
diff changeset
709 kit.set_control(gvn.transform(region));
a61af66fc99e Initial load
duke
parents:
diff changeset
710 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 iophi->set_req(2, slow_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
712 kit.set_i_o(gvn.transform(iophi));
a61af66fc99e Initial load
duke
parents:
diff changeset
713 kit.merge_memory(slow_map->merged_memory(), region, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 uint tos = kit.jvms()->stkoff() + kit.sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
715 uint limit = slow_map->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
716 for (uint i = TypeFunc::Parms; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // Skip unused stack slots; fast forward to monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
718 if (i == tos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 i = kit.jvms()->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if( i >= limit ) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722 Node* m = kit.map()->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 Node* n = slow_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 if (m != n) {
17671
de95063c0e34 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 17467
diff changeset
725 const Type* t = gvn.type(m)->meet_speculative(gvn.type(n));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
726 Node* phi = PhiNode::make(region, m, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 phi->set_req(2, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 kit.map()->set_req(i, gvn.transform(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
735 CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
736 assert(callee->is_method_handle_intrinsic() ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
737 callee->is_compiled_lambda_form(), "for_method_handle_call mismatch");
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
738 bool input_not_const;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
739 CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee, input_not_const);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
740 Compile* C = Compile::current();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
741 if (cg != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
742 if (!delayed_forbidden && AlwaysIncrementalInline) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
743 return CallGenerator::for_late_inline(callee, cg);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
744 } else {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
745 return cg;
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
746 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
747 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
748 int bci = jvms->bci();
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
749 ciCallProfile profile = caller->call_profile_at_bci(bci);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
750 int call_site_count = caller->scale_count(profile.count());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
751
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
752 if (IncrementalInline && call_site_count > 0 &&
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
753 (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
754 return CallGenerator::for_mh_late_inline(caller, callee, input_not_const);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
755 } else {
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
756 // Out-of-line call.
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
757 return CallGenerator::for_direct_call(callee);
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
758 }
4117
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 4062
diff changeset
759 }
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 4062
diff changeset
760
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
761 CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
762 GraphKit kit(jvms);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
763 PhaseGVN& gvn = kit.gvn();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
764 Compile* C = kit.C;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
765 vmIntrinsics::ID iid = callee->intrinsic_id();
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
766 input_not_const = true;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
767 switch (iid) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
768 case vmIntrinsics::_invokeBasic:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
769 {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
770 // Get MethodHandle receiver:
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
771 Node* receiver = kit.argument(0);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
772 if (receiver->Opcode() == Op_ConP) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
773 input_not_const = false;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
774 const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
775 ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
776 guarantee(!target->is_method_handle_intrinsic(), "should not happen"); // XXX remove
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
777 const int vtable_index = Method::invalid_vtable_index;
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
778 CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, NULL, true, true);
13081
e74074c34312 8028159: C2: compiler stack overflow during inlining of @ForceInline methods
vlivanov
parents: 12966
diff changeset
779 assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
780 if (cg != NULL && cg->is_inline())
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
781 return cg;
3905
c26de9aef2ed 7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents: 3901
diff changeset
782 }
c26de9aef2ed 7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents: 3901
diff changeset
783 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
784 break;
3905
c26de9aef2ed 7071307: MethodHandle bimorphic inlining should consider the frequency
never
parents: 3901
diff changeset
785
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
786 case vmIntrinsics::_linkToVirtual:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
787 case vmIntrinsics::_linkToStatic:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
788 case vmIntrinsics::_linkToSpecial:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
789 case vmIntrinsics::_linkToInterface:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
790 {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6894
diff changeset
791 // Get MemberName argument:
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
792 Node* member_name = kit.argument(callee->arg_size() - 1);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
793 if (member_name->Opcode() == Op_ConP) {
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7421
diff changeset
794 input_not_const = false;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
795 const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
796 ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
3752
f918d6096e23 7050554: JSR 292 - need optimization for selectAlternative
never
parents: 2443
diff changeset
797
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
798 // In lamda forms we erase signature types to avoid resolving issues
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
799 // involving class loaders. When we optimize a method handle invoke
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
800 // to a direct call we must cast the receiver and arguments to its
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
801 // actual types.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
802 ciSignature* signature = target->signature();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
803 const int receiver_skip = target->is_static() ? 0 : 1;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
804 // Cast receiver to its type.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
805 if (!target->is_static()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
806 Node* arg = kit.argument(0);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
807 const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
808 const Type* sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
809 if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
810 Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
811 kit.set_argument(0, cast_obj);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
812 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
813 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
814 // Cast reference arguments to its type.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
815 for (int i = 0; i < signature->count(); i++) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
816 ciType* t = signature->type_at(i);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
817 if (t->is_klass()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
818 Node* arg = kit.argument(receiver_skip + i);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
819 const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
820 const Type* sig_type = TypeOopPtr::make_from_klass(t->as_klass());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
821 if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
822 Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
823 kit.set_argument(receiver_skip + i, cast_obj);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
824 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
825 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
826 }
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
827
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
828 // Try to get the most accurate receiver type
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
829 const bool is_virtual = (iid == vmIntrinsics::_linkToVirtual);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
830 const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
831 int vtable_index = Method::invalid_vtable_index;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
832 bool call_does_dispatch = false;
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
833
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
834 ciKlass* speculative_receiver_type = NULL;
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
835 if (is_virtual_or_interface) {
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
836 ciInstanceKlass* klass = target->holder();
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
837 Node* receiver_node = kit.argument(0);
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
838 const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
839 // call_does_dispatch and vtable_index are out-parameters. They might be changed.
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
840 target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
841 is_virtual,
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
842 call_does_dispatch, vtable_index); // out-parameters
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
843 // We lack profiling at this call but type speculation may
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
844 // provide us with a type
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
845 speculative_receiver_type = receiver_type->speculative_type();
7478
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
846 }
5698813d45eb 8005418: JSR 292: virtual dispatch bug in 292 impl
twisti
parents: 7473
diff changeset
847
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
848 CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true);
13081
e74074c34312 8028159: C2: compiler stack overflow during inlining of @ForceInline methods
vlivanov
parents: 12966
diff changeset
849 assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
850 if (cg != NULL && cg->is_inline())
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
851 return cg;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
852 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
853 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
854 break;
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
855
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
856 default:
6268
6c5b7a6becc8 7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents: 6266
diff changeset
857 fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6182
diff changeset
858 break;
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
859 }
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
860 return NULL;
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
861 }
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
862
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
863
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
864 //------------------------PredictedIntrinsicGenerator------------------------------
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
865 // Internal class which handles all predicted Intrinsic calls.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
866 class PredictedIntrinsicGenerator : public CallGenerator {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
867 CallGenerator* _intrinsic;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
868 CallGenerator* _cg;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
869
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
870 public:
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
871 PredictedIntrinsicGenerator(CallGenerator* intrinsic,
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
872 CallGenerator* cg)
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
873 : CallGenerator(cg->method())
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
874 {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
875 _intrinsic = intrinsic;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
876 _cg = cg;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
877 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
878
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
879 virtual bool is_virtual() const { return true; }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
880 virtual bool is_inlined() const { return true; }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
881 virtual bool is_intrinsic() const { return true; }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
882
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
883 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
884 };
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
885
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
886
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
887 CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic,
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
888 CallGenerator* cg) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
889 return new PredictedIntrinsicGenerator(intrinsic, cg);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
890 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
891
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
892
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
893 JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_parser) {
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
894 GraphKit kit(jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
895 PhaseGVN& gvn = kit.gvn();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
896
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
897 CompileLog* log = kit.C->log();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
898 if (log != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
899 log->elem("predicted_intrinsic bci='%d' method='%d'",
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
900 jvms->bci(), log->identify(method()));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
901 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
902
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
903 Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
904 if (kit.failing())
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
905 return NULL; // might happen because of NodeCountInliningCutoff
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
906
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
907 SafePointNode* slow_map = NULL;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
908 JVMState* slow_jvms;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
909 if (slow_ctl != NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
910 PreserveJVMState pjvms(&kit);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
911 kit.set_control(slow_ctl);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
912 if (!kit.stopped()) {
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
913 slow_jvms = _cg->generate(kit.sync_jvms(), parent_parser);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
914 if (kit.failing())
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
915 return NULL; // might happen because of NodeCountInliningCutoff
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
916 assert(slow_jvms != NULL, "must be");
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
917 kit.add_exception_states_from(slow_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
918 kit.set_map(slow_jvms->map());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
919 if (!kit.stopped())
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
920 slow_map = kit.stop();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
921 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
922 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
923
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
924 if (kit.stopped()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
925 // Predicate is always false.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
926 kit.set_jvms(slow_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
927 return kit.transfer_exceptions_into_jvms();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
928 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
929
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
930 // Generate intrinsic code:
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
931 JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms(), parent_parser);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
932 if (new_jvms == NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
933 // Intrinsic failed, so use slow code or make a direct call.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
934 if (slow_map == NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
935 CallGenerator* cg = CallGenerator::for_direct_call(method());
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
936 new_jvms = cg->generate(kit.sync_jvms(), parent_parser);
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
937 } else {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
938 kit.set_jvms(slow_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
939 return kit.transfer_exceptions_into_jvms();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
940 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
941 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
942 kit.add_exception_states_from(new_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
943 kit.set_jvms(new_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
944
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
945 // Need to merge slow and fast?
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
946 if (slow_map == NULL) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
947 // The fast path is the only path remaining.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
948 return kit.transfer_exceptions_into_jvms();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
949 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
950
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
951 if (kit.stopped()) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
952 // Intrinsic method threw an exception, so it's just the slow path after all.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
953 kit.set_jvms(slow_jvms);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
954 return kit.transfer_exceptions_into_jvms();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
955 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
956
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
957 // Finish the diamond.
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
958 kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
959 RegionNode* region = new (kit.C) RegionNode(3);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
960 region->init_req(1, kit.control());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
961 region->init_req(2, slow_map->control());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
962 kit.set_control(gvn.transform(region));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
963 Node* iophi = PhiNode::make(region, kit.i_o(), Type::ABIO);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
964 iophi->set_req(2, slow_map->i_o());
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
965 kit.set_i_o(gvn.transform(iophi));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
966 kit.merge_memory(slow_map->merged_memory(), region, 2);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
967 uint tos = kit.jvms()->stkoff() + kit.sp();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
968 uint limit = slow_map->req();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
969 for (uint i = TypeFunc::Parms; i < limit; i++) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
970 // Skip unused stack slots; fast forward to monoff();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
971 if (i == tos) {
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
972 i = kit.jvms()->monoff();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
973 if( i >= limit ) break;
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
974 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
975 Node* m = kit.map()->in(i);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
976 Node* n = slow_map->in(i);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
977 if (m != n) {
17671
de95063c0e34 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 17467
diff changeset
978 const Type* t = gvn.type(m)->meet_speculative(gvn.type(n));
6894
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
979 Node* phi = PhiNode::make(region, m, t);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
980 phi->set_req(2, n);
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
981 kit.map()->set_req(i, gvn.transform(phi));
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
982 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
983 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
984 return kit.transfer_exceptions_into_jvms();
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
985 }
a3ecd773a7b9 7184394: add intrinsics to use AES instructions
kvn
parents: 6804
diff changeset
986
0
a61af66fc99e Initial load
duke
parents:
diff changeset
987 //-------------------------UncommonTrapCallGenerator-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // Internal class which handles all out-of-line calls checking receiver type.
a61af66fc99e Initial load
duke
parents:
diff changeset
989 class UncommonTrapCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 Deoptimization::DeoptReason _reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
991 Deoptimization::DeoptAction _action;
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
994 UncommonTrapCallGenerator(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
995 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
996 Deoptimization::DeoptAction action)
a61af66fc99e Initial load
duke
parents:
diff changeset
997 : CallGenerator(m)
a61af66fc99e Initial load
duke
parents:
diff changeset
998 {
a61af66fc99e Initial load
duke
parents:
diff changeset
999 _reason = reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 _action = action;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 virtual bool is_virtual() const { ShouldNotReachHere(); return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 virtual bool is_trap() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
1006 virtual JVMState* generate(JVMState* jvms, Parse* parent_parser);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 CallGenerator*
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 CallGenerator::for_uncommon_trap(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 Deoptimization::DeoptAction action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 return new UncommonTrapCallGenerator(m, reason, action);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 10278
diff changeset
1018 JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 GraphKit kit(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // Take the trap with arguments pushed on the stack. (Cf. null_check_receiver).
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 int nargs = method()->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 kit.inc_sp(nargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 if (_reason == Deoptimization::Reason_class_check &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 _action == Deoptimization::Action_maybe_recompile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // Temp fix for 6529811
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // Don't allow uncommon_trap to override our decision to recompile in the event
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // of a class cast failure for a monomorphic call as it will never let us convert
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // the call to either bi-morphic or megamorphic and can lead to unc-trap loops
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 bool keep_exact_action = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 kit.uncommon_trap(_reason, _action);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 return kit.transfer_exceptions_into_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // (Note: Moved hook_up_call to GraphKit::set_edges_for_java_call.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // (Node: Merged hook_up_exits into ParseGenerator::generate.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 #define NODES_OVERHEAD_PER_METHOD (30.0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 #define NODES_PER_BYTECODE (9.5)
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 void WarmCallInfo::init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 int call_count = profile.count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 int code_size = call_method->code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // Expected execution count is based on the historical count:
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 _count = call_count < 0 ? 1 : call_site->method()->scale_count(call_count, prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // Expected profit from inlining, in units of simple call-overheads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 _profit = 1.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // Expected work performed by the call in units of call-overheads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // %%% need an empirical curve fit for "work" (time in call)
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 float bytecodes_per_call = 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 _work = 1.0 + code_size / bytecodes_per_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // Expected size of compilation graph:
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // -XX:+PrintParseStatistics once reported:
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // Methods seen: 9184 Methods parsed: 9184 Nodes created: 1582391
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // Histogram of 144298 parsed bytecodes:
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 // %%% Need an better predictor for graph size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 _size = NODES_OVERHEAD_PER_METHOD + (NODES_PER_BYTECODE * code_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // is_cold: Return true if the node should never be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // This is true if any of the key metrics are extreme.
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 bool WarmCallInfo::is_cold() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 if (count() < WarmCallMinCount) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 if (profit() < WarmCallMinProfit) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 if (work() > WarmCallMaxWork) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 if (size() > WarmCallMaxSize) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // is_hot: Return true if the node should be inlined immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // This is true if any of the key metrics are extreme.
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 bool WarmCallInfo::is_hot() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 assert(!is_cold(), "eliminate is_cold cases before testing is_hot");
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 if (count() >= HotCallCountThreshold) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 if (profit() >= HotCallProfitThreshold) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 if (work() <= HotCallTrivialWork) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 if (size() <= HotCallTrivialSize) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 // compute_heat:
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 float WarmCallInfo::compute_heat() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 assert(!is_cold(), "compute heat only on warm nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 assert(!is_hot(), "compute heat only on warm nodes");
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 int min_size = MAX2(0, (int)HotCallTrivialSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 int max_size = MIN2(500, (int)WarmCallMaxSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 float method_size = (size() - min_size) / MAX2(1, max_size - min_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 float size_factor;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (method_size < 0.05) size_factor = 4; // 2 sigmas better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 else if (method_size < 0.15) size_factor = 2; // 1 sigma better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 else if (method_size < 0.5) size_factor = 1; // better than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 else size_factor = 0.5; // worse than avg.
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 return (count() * profit() * size_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 bool WarmCallInfo::warmer_than(WarmCallInfo* that) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 assert(this != that, "compare only different WCIs");
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 assert(this->heat() != 0 && that->heat() != 0, "call compute_heat 1st");
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 if (this->heat() > that->heat()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 if (this->heat() < that->heat()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 assert(this->heat() == that->heat(), "no NaN heat allowed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // Equal heat. Break the tie some other way.
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 if (!this->call() || !that->call()) return (address)this > (address)that;
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 return this->call()->_idx > that->call()->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 //#define UNINIT_NEXT ((WarmCallInfo*)badAddress)
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 #define UNINIT_NEXT ((WarmCallInfo*)NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 WarmCallInfo* WarmCallInfo::insert_into(WarmCallInfo* head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 assert(next() == UNINIT_NEXT, "not yet on any list");
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 WarmCallInfo* prev_p = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 WarmCallInfo* next_p = head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 while (next_p != NULL && next_p->warmer_than(this)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 prev_p = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 next_p = prev_p->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Install this between prev_p and next_p.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 this->set_next(next_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 if (prev_p == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 head = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 prev_p->set_next(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 return head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1134
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 WarmCallInfo* WarmCallInfo::remove_from(WarmCallInfo* head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 WarmCallInfo* prev_p = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 WarmCallInfo* next_p = head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 while (next_p != this) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 assert(next_p != NULL, "this must be in the list somewhere");
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 prev_p = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 next_p = prev_p->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 next_p = this->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 debug_only(this->set_next(UNINIT_NEXT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // Remove this from between prev_p and next_p.
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 if (prev_p == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 head = next_p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 prev_p->set_next(next_p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 return head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
2443
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1153 WarmCallInfo WarmCallInfo::_always_hot(WarmCallInfo::MAX_VALUE(), WarmCallInfo::MAX_VALUE(),
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1154 WarmCallInfo::MIN_VALUE(), WarmCallInfo::MIN_VALUE());
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1155 WarmCallInfo WarmCallInfo::_always_cold(WarmCallInfo::MIN_VALUE(), WarmCallInfo::MIN_VALUE(),
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1156 WarmCallInfo::MAX_VALUE(), WarmCallInfo::MAX_VALUE());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1157
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 WarmCallInfo* WarmCallInfo::always_hot() {
2443
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1159 assert(_always_hot.is_hot(), "must always be hot");
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1160 return &_always_hot;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 WarmCallInfo* WarmCallInfo::always_cold() {
2443
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1164 assert(_always_cold.is_cold(), "must always be cold");
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 2357
diff changeset
1165 return &_always_cold;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 void WarmCallInfo::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 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
1173 is_cold() ? "cold" : is_hot() ? "hot " : "warm",
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 count(), profit(), work(), size(), compute_heat(), next());
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 if (call() != NULL) call()->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 void print_wci(WarmCallInfo* ci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 ci->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 void WarmCallInfo::print_all() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 for (const WarmCallInfo* p = this; p != NULL; p = p->next())
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 p->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 int WarmCallInfo::count_all() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 int cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 for (const WarmCallInfo* p = this; p != NULL; p = p->next())
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 cnt++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 #endif //PRODUCT