annotate src/share/vm/opto/graphKit.cpp @ 14649:f6301b007a16

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 bb9356ec5967
children 16c705d792be
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
14223
de6a9e811145 8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents: 12966
diff changeset
2 * Copyright (c) 2001, 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: 1397
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1397
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: 1397
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: 1965
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
26 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
27 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
28 #include "gc_implementation/g1/heapRegion.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
29 #include "gc_interface/collectedHeap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
30 #include "memory/barrierSet.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
31 #include "memory/cardTableModRefBS.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
32 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
33 #include "opto/graphKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
34 #include "opto/idealKit.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
35 #include "opto/locknode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
36 #include "opto/machnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
37 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
38 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
39 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
40 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1965
diff changeset
41 #include "runtime/sharedRuntime.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 //----------------------------GraphKit-----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Main utility constructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 GraphKit::GraphKit(JVMState* jvms)
a61af66fc99e Initial load
duke
parents:
diff changeset
46 : Phase(Phase::Parser),
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _env(C->env()),
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _gvn(*C->initial_gvn())
a61af66fc99e Initial load
duke
parents:
diff changeset
49 {
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _exceptions = jvms->map()->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
51 if (_exceptions != NULL) jvms->map()->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Private constructor for parser.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 GraphKit::GraphKit()
a61af66fc99e Initial load
duke
parents:
diff changeset
57 : Phase(Phase::Parser),
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _env(C->env()),
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _gvn(*C->initial_gvn())
a61af66fc99e Initial load
duke
parents:
diff changeset
60 {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _exceptions = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 set_map(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 debug_only(_sp = -99);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 debug_only(set_bci(-99));
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 //---------------------------clean_stack---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Clear away rubbish from the stack area of the JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // This destroys any arguments that may be waiting on the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 void GraphKit::clean_stack(int from_sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 SafePointNode* map = this->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
74 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 int stk_size = jvms->stk_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
76 int stkoff = jvms->stkoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 Node* top = this->top();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 for (int i = from_sp; i < stk_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if (map->in(stkoff + i) != top) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 map->set_req(stkoff + i, top);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 //--------------------------------sync_jvms-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Make sure our current jvms agrees with our parse state.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 JVMState* GraphKit::sync_jvms() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
90 jvms->set_bci(bci()); // Record the new bci in the JVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
91 jvms->set_sp(sp()); // Record the new sp in the JVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
92 assert(jvms_in_sync(), "jvms is now in sync");
a61af66fc99e Initial load
duke
parents:
diff changeset
93 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
96 //--------------------------------sync_jvms_for_reexecute---------------------
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
97 // Make sure our current jvms agrees with our parse state. This version
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
98 // uses the reexecute_sp for reexecuting bytecodes.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
99 JVMState* GraphKit::sync_jvms_for_reexecute() {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
100 JVMState* jvms = this->jvms();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
101 jvms->set_bci(bci()); // Record the new bci in the JVMState
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
102 jvms->set_sp(reexecute_sp()); // Record the new sp in the JVMState
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
103 return jvms;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
104 }
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
105
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
107 bool GraphKit::jvms_in_sync() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 Parse* parse = is_Parse();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (parse == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (bci() != jvms()->bci()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (sp() != (int)jvms()->sp()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (jvms()->method() != parse->method()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (jvms()->bci() != parse->bci()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 int jvms_sp = jvms()->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
117 if (jvms_sp != parse->sp()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 int jvms_depth = jvms()->depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (jvms_depth != parse->depth()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Local helper checks for special internal merge points
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // used to accumulate and merge exception states.
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // They are marked by the region's in(0) edge being the map itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Such merge points must never "escape" into the parser at large,
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // until they have been handed to gvn.transform.
a61af66fc99e Initial load
duke
parents:
diff changeset
128 static bool is_hidden_merge(Node* reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
129 if (reg == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (reg->is_Phi()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 reg = reg->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (reg == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 return reg->is_Region() && reg->in(0) != NULL && reg->in(0)->is_Root();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 void GraphKit::verify_map() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (map() == NULL) return; // null map is OK
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(map()->req() <= jvms()->endoff(), "no extra garbage on map");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert(!map()->has_exceptions(), "call add_exception_states_from 1st");
a61af66fc99e Initial load
duke
parents:
diff changeset
141 assert(!is_hidden_merge(control()), "call use_exception_state, not set_map");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 void GraphKit::verify_exception_state(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 assert(ex_map->next_exception() == NULL, "not already part of a chain");
a61af66fc99e Initial load
duke
parents:
diff changeset
146 assert(has_saved_ex_oop(ex_map), "every exception state has an ex_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 //---------------------------stop_and_kill_map---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Set _map to NULL, signalling a stop to further bytecode execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // First smash the current map's control to a constant, to mark it dead.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 void GraphKit::stop_and_kill_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 SafePointNode* dead_map = stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (dead_map != NULL) {
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 7194
diff changeset
156 dead_map->disconnect_inputs(NULL, C); // Mark the map as killed.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
157 assert(dead_map->is_killed(), "must be so marked");
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 //--------------------------------stopped--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Tell if _map is NULL, or control is top.
a61af66fc99e Initial load
duke
parents:
diff changeset
164 bool GraphKit::stopped() {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (map() == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 else if (control() == top()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 else return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 //-----------------------------has_ex_handler----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Tell if this method or any caller method has exception handlers.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 bool GraphKit::has_ex_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 for (JVMState* jvmsp = jvms(); jvmsp != NULL; jvmsp = jvmsp->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (jvmsp->has_method() && jvmsp->method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 //------------------------------save_ex_oop------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Save an exception without blowing stack contents or other JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 void GraphKit::set_saved_ex_oop(SafePointNode* ex_map, Node* ex_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 assert(!has_saved_ex_oop(ex_map), "clear ex-oop before setting again");
a61af66fc99e Initial load
duke
parents:
diff changeset
186 ex_map->add_req(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 debug_only(verify_exception_state(ex_map));
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 inline static Node* common_saved_ex_oop(SafePointNode* ex_map, bool clear_it) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(GraphKit::has_saved_ex_oop(ex_map), "ex_oop must be there");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 Node* ex_oop = ex_map->in(ex_map->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if (clear_it) ex_map->del_req(ex_map->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 return ex_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 //-----------------------------saved_ex_oop------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Recover a saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Node* GraphKit::saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 return common_saved_ex_oop(ex_map, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 //--------------------------clear_saved_ex_oop---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // Erase a previously saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
205 Node* GraphKit::clear_saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 return common_saved_ex_oop(ex_map, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
210 //---------------------------has_saved_ex_oop----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Erase a previously saved exception from its map.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 bool GraphKit::has_saved_ex_oop(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return ex_map->req() == ex_map->jvms()->endoff()+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 //-------------------------make_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Turn the current JVM state into an exception state, appending the ex_oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
219 SafePointNode* GraphKit::make_exception_state(Node* ex_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 SafePointNode* ex_map = stop(); // do not manipulate this map any more
a61af66fc99e Initial load
duke
parents:
diff changeset
222 set_saved_ex_oop(ex_map, ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return ex_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226
a61af66fc99e Initial load
duke
parents:
diff changeset
227 //--------------------------add_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // Add an exception to my list of exceptions.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 void GraphKit::add_exception_state(SafePointNode* ex_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 if (ex_map == NULL || ex_map->control() == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
234 verify_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 if (has_exceptions()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 assert(ex_map->jvms()->same_calls_as(_exceptions->jvms()), "all collected exceptions must come from the same place");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // If there is already an exception of exactly this type, merge with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // In particular, null-checks and other low-level exceptions common up here.
a61af66fc99e Initial load
duke
parents:
diff changeset
242 Node* ex_oop = saved_ex_oop(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 const Type* ex_type = _gvn.type(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (ex_oop == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // No action needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 assert(ex_type->isa_instptr(), "exception must be an instance");
a61af66fc99e Initial load
duke
parents:
diff changeset
249 for (SafePointNode* e2 = _exceptions; e2 != NULL; e2 = e2->next_exception()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 const Type* ex_type2 = _gvn.type(saved_ex_oop(e2));
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // We check sp also because call bytecodes can generate exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // both before and after arguments are popped!
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (ex_type2 == ex_type
a61af66fc99e Initial load
duke
parents:
diff changeset
254 && e2->_jvms->sp() == ex_map->_jvms->sp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 combine_exception_states(ex_map, e2);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // No pre-existing exception of the same type. Chain it on the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 push_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 //-----------------------add_exception_states_from-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void GraphKit::add_exception_states_from(JVMState* jvms) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 SafePointNode* ex_map = jvms->map()->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (ex_map != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 jvms->map()->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 for (SafePointNode* next_map; ex_map != NULL; ex_map = next_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 next_map = ex_map->next_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 ex_map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 add_exception_state(ex_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 //-----------------------transfer_exceptions_into_jvms-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
278 JVMState* GraphKit::transfer_exceptions_into_jvms() {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if (map() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // We need a JVMS to carry the exceptions, but the map has gone away.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Create a scratch JVMS, cloned from any of the exception states...
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (has_exceptions()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 _map = _exceptions;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 _map = clone_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
285 _map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 clear_saved_ex_oop(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 debug_only(verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
288 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // ...or created from scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
290 JVMState* jvms = new (C) JVMState(_method, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 jvms->set_bci(_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 jvms->set_sp(_sp);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
293 jvms->set_map(new (C) SafePointNode(TypeFunc::Parms, jvms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
294 set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 for (uint i = 0; i < map()->req(); i++) map()->init_req(i, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
296 set_all_memory(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
297 while (map()->req() < jvms->endoff()) map()->add_req(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // (This is a kludge, in case you didn't notice.)
a61af66fc99e Initial load
duke
parents:
diff changeset
300 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 JVMState* jvms = sync_jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 assert(!jvms->map()->has_exceptions(), "no exceptions on this map yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
304 jvms->map()->set_next_exception(_exceptions);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 _exceptions = NULL; // done with this set of exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
306 return jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 static inline void add_n_reqs(Node* dstphi, Node* srcphi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 assert(is_hidden_merge(dstphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
311 assert(is_hidden_merge(srcphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
312 uint limit = srcphi->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
313 for (uint i = PhiNode::Input; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 dstphi->add_req(srcphi->in(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 static inline void add_one_req(Node* dstphi, Node* src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 assert(is_hidden_merge(dstphi), "must be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
319 assert(!is_hidden_merge(src), "must not be a special merge node");
a61af66fc99e Initial load
duke
parents:
diff changeset
320 dstphi->add_req(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 //-----------------------combine_exception_states------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // This helper function combines exception states by building phis on a
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // specially marked state-merging region. These regions and phis are
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // untransformed, and can build up gradually. The region is marked by
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // having a control input of its exception map, rather than NULL. Such
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // regions do not appear except in this function, and in use_exception_state.
a61af66fc99e Initial load
duke
parents:
diff changeset
329 void GraphKit::combine_exception_states(SafePointNode* ex_map, SafePointNode* phi_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 if (failing()) return; // dying anyway...
a61af66fc99e Initial load
duke
parents:
diff changeset
331 JVMState* ex_jvms = ex_map->_jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 assert(ex_jvms->same_calls_as(phi_map->_jvms), "consistent call chains");
a61af66fc99e Initial load
duke
parents:
diff changeset
333 assert(ex_jvms->stkoff() == phi_map->_jvms->stkoff(), "matching locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
334 assert(ex_jvms->sp() == phi_map->_jvms->sp(), "matching stack sizes");
a61af66fc99e Initial load
duke
parents:
diff changeset
335 assert(ex_jvms->monoff() == phi_map->_jvms->monoff(), "matching JVMS");
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
336 assert(ex_jvms->scloff() == phi_map->_jvms->scloff(), "matching scalar replaced objects");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
337 assert(ex_map->req() == phi_map->req(), "matching maps");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 uint tos = ex_jvms->stkoff() + ex_jvms->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 Node* hidden_merge_mark = root();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 Node* region = phi_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
341 MergeMemNode* phi_mem = phi_map->merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
342 MergeMemNode* ex_mem = ex_map->merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (region->in(0) != hidden_merge_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // The control input is not (yet) a specially-marked region in phi_map.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Make it so, and build some phis.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
346 region = new (C) RegionNode(2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
347 _gvn.set_type(region, Type::CONTROL);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 region->set_req(0, hidden_merge_mark); // marks an internal ex-state
a61af66fc99e Initial load
duke
parents:
diff changeset
349 region->init_req(1, phi_map->control());
a61af66fc99e Initial load
duke
parents:
diff changeset
350 phi_map->set_control(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 Node* io_phi = PhiNode::make(region, phi_map->i_o(), Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 record_for_igvn(io_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 _gvn.set_type(io_phi, Type::ABIO);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 phi_map->set_i_o(io_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 for (MergeMemStream mms(phi_mem); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 Node* m = mms.memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
357 Node* m_phi = PhiNode::make(region, m, Type::MEMORY, mms.adr_type(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
358 record_for_igvn(m_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 _gvn.set_type(m_phi, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 mms.set_memory(m_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // Either or both of phi_map and ex_map might already be converted into phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
365 Node* ex_control = ex_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // if there is special marking on ex_map also, we add multiple edges from src
a61af66fc99e Initial load
duke
parents:
diff changeset
367 bool add_multiple = (ex_control->in(0) == hidden_merge_mark);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // how wide was the destination phi_map, originally?
a61af66fc99e Initial load
duke
parents:
diff changeset
369 uint orig_width = region->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 if (add_multiple) {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 add_n_reqs(region, ex_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 add_n_reqs(phi_map->i_o(), ex_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
374 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // ex_map has no merges, so we just add single edges everywhere
a61af66fc99e Initial load
duke
parents:
diff changeset
376 add_one_req(region, ex_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
377 add_one_req(phi_map->i_o(), ex_map->i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 for (MergeMemStream mms(phi_mem, ex_mem); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (mms.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // get a copy of the base memory, and patch some inputs into it
a61af66fc99e Initial load
duke
parents:
diff changeset
382 const TypePtr* adr_type = mms.adr_type(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 Node* phi = mms.force_memory()->as_Phi()->slice_memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 assert(phi->as_Phi()->region() == mms.base_memory()->in(0), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
385 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Prepare to append interesting stuff onto the newly sliced phi:
a61af66fc99e Initial load
duke
parents:
diff changeset
387 while (phi->req() > orig_width) phi->del_req(phi->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // Append stuff from ex_map:
a61af66fc99e Initial load
duke
parents:
diff changeset
390 if (add_multiple) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 add_n_reqs(mms.memory(), mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
392 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
393 add_one_req(mms.memory(), mms.memory2());
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396 uint limit = ex_map->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 for (uint i = TypeFunc::Parms; i < limit; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // Skip everything in the JVMS after tos. (The ex_oop follows.)
a61af66fc99e Initial load
duke
parents:
diff changeset
399 if (i == tos) i = ex_jvms->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 Node* src = ex_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
401 Node* dst = phi_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if (src != dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 if (dst->in(0) != region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 dst = phi = PhiNode::make(region, dst, _gvn.type(dst));
a61af66fc99e Initial load
duke
parents:
diff changeset
406 record_for_igvn(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 _gvn.set_type(phi, phi->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
408 phi_map->set_req(i, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Prepare to append interesting stuff onto the new phi:
a61af66fc99e Initial load
duke
parents:
diff changeset
410 while (dst->req() > orig_width) dst->del_req(dst->req()-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 assert(dst->is_Phi(), "nobody else uses a hidden region");
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
413 phi = dst->as_Phi();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (add_multiple && src->in(0) == ex_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // Both are phis.
a61af66fc99e Initial load
duke
parents:
diff changeset
417 add_n_reqs(dst, src);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 while (dst->req() < region->req()) add_one_req(dst, src);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 const Type* srctype = _gvn.type(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 if (phi->type() != srctype) {
14383
5ec7dace41a6 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 14223
diff changeset
423 const Type* dsttype = phi->type()->meet_speculative(srctype);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
424 if (phi->type() != dsttype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 phi->set_type(dsttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 _gvn.set_type(phi, dsttype);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 //--------------------------use_exception_state--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
434 Node* GraphKit::use_exception_state(SafePointNode* phi_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 if (failing()) { stop(); return top(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
436 Node* region = phi_map->control();
a61af66fc99e Initial load
duke
parents:
diff changeset
437 Node* hidden_merge_mark = root();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 assert(phi_map->jvms()->map() == phi_map, "sanity: 1-1 relation");
a61af66fc99e Initial load
duke
parents:
diff changeset
439 Node* ex_oop = clear_saved_ex_oop(phi_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (region->in(0) == hidden_merge_mark) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Special marking for internal ex-states. Process the phis now.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 region->set_req(0, region); // now it's an ordinary region
a61af66fc99e Initial load
duke
parents:
diff changeset
443 set_jvms(phi_map->jvms()); // ...so now we can use it as a map
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // Note: Setting the jvms also sets the bci and sp.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 set_control(_gvn.transform(region));
a61af66fc99e Initial load
duke
parents:
diff changeset
446 uint tos = jvms()->stkoff() + sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
447 for (uint i = 1; i < tos; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 Node* x = phi_map->in(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 if (x->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 assert(x->is_Phi(), "expected a special phi");
a61af66fc99e Initial load
duke
parents:
diff changeset
451 phi_map->set_req(i, _gvn.transform(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 for (MergeMemStream mms(merged_memory()); mms.next_non_empty(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 Node* x = mms.memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
456 if (x->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 assert(x->is_Phi(), "nobody else uses a hidden region");
a61af66fc99e Initial load
duke
parents:
diff changeset
458 mms.set_memory(_gvn.transform(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (ex_oop->in(0) == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 assert(ex_oop->is_Phi(), "expected a special phi");
a61af66fc99e Initial load
duke
parents:
diff changeset
463 ex_oop = _gvn.transform(ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 set_jvms(phi_map->jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 assert(!is_hidden_merge(phi_map->control()), "hidden ex. states cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
470 assert(!is_hidden_merge(phi_map->i_o()), "hidden ex. states cleared");
a61af66fc99e Initial load
duke
parents:
diff changeset
471 return ex_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 //---------------------------------java_bc-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
475 Bytecodes::Code GraphKit::java_bc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 ciMethod* method = this->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
477 int bci = this->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (method != NULL && bci != InvocationEntryBci)
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return method->java_code_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 else
a61af66fc99e Initial load
duke
parents:
diff changeset
481 return Bytecodes::_illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
484 void GraphKit::uncommon_trap_if_should_post_on_exceptions(Deoptimization::DeoptReason reason,
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
485 bool must_throw) {
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
486 // if the exception capability is set, then we will generate code
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
487 // to check the JavaThread.should_post_on_exceptions flag to see
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
488 // if we actually need to report exception events (for this
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
489 // thread). If we don't need to report exception events, we will
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
490 // take the normal fast path provided by add_exception_events. If
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
491 // exception event reporting is enabled for this thread, we will
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
492 // take the uncommon_trap in the BuildCutout below.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
493
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
494 // first must access the should_post_on_exceptions_flag in this thread's JavaThread
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
495 Node* jthread = _gvn.transform(new (C) ThreadLocalNode());
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
496 Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
497 Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, MemNode::unordered);
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
498
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
499 // Test the should_post_on_exceptions_flag vs. 0
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
500 Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
501 Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) );
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
502
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
503 // Branch to slow_path if should_post_on_exceptions_flag was true
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
504 { BuildCutout unless(this, tst, PROB_MAX);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
505 // Do not try anything fancy if we're notifying the VM on every throw.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
506 // Cf. case Bytecodes::_athrow in parse2.cpp.
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
507 uncommon_trap(reason, Deoptimization::Action_none,
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
508 (ciKlass*)NULL, (char*)NULL, must_throw);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
509 }
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
510
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
511 }
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
512
0
a61af66fc99e Initial load
duke
parents:
diff changeset
513 //------------------------------builtin_throw----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
514 void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 bool must_throw = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
516
1213
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
517 if (env()->jvmti_can_post_on_exceptions()) {
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
518 // check if we must post exception events, take uncommon trap if so
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
519 uncommon_trap_if_should_post_on_exceptions(reason, must_throw);
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
520 // here if should_post_on_exceptions is false
6deeaebad47a 6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents: 1166
diff changeset
521 // continue on with the normal codegen
0
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // If this particular condition has not yet happened at this
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // bytecode, then use the uncommon trap mechanism, and allow for
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // a future recompilation if several traps occur here.
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // If the throw is hot, try to use a more complicated inline mechanism
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // which keeps execution inside the compiled code.
a61af66fc99e Initial load
duke
parents:
diff changeset
529 bool treat_throw_as_hot = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 ciMethodData* md = method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if (ProfileTraps) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (too_many_traps(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 treat_throw_as_hot = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // (If there is no MDO at all, assume it is early in
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // execution, and that any deopts are part of the
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // startup transient, and don't need to be remembered.)
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Also, if there is a local exception handler, treat all throws
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // as hot if there has been at least one in this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
542 if (C->trap_count(reason) != 0
a61af66fc99e Initial load
duke
parents:
diff changeset
543 && method()->method_data()->trap_count(reason) != 0
a61af66fc99e Initial load
duke
parents:
diff changeset
544 && has_ex_handler()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 treat_throw_as_hot = true;
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 // If this throw happens frequently, an uncommon trap might cause
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // a performance pothole. If there is a local exception handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // and if this particular bytecode appears to be deoptimizing often,
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // let us handle the throw inline, with a preconstructed instance.
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // Note: If the deopt count has blown up, the uncommon trap
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // runtime is going to flush this nmethod, not matter what.
a61af66fc99e Initial load
duke
parents:
diff changeset
555 if (treat_throw_as_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
556 && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // If the throw is local, we use a pre-existing instance and
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // punt on the backtrace. This would lead to a missing backtrace
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // (a repeat of 4292742) if the backtrace object is ever asked
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // for its backtrace.
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // Fixing this remaining case of 4292742 requires some flavor of
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // escape analysis. Leave that for the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 ciInstance* ex_obj = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
564 switch (reason) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 case Deoptimization::Reason_null_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
566 ex_obj = env()->NullPointerException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
567 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
568 case Deoptimization::Reason_div0_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
569 ex_obj = env()->ArithmeticException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
570 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 case Deoptimization::Reason_range_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
572 ex_obj = env()->ArrayIndexOutOfBoundsException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
573 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 case Deoptimization::Reason_class_check:
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (java_bc() == Bytecodes::_aastore) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 ex_obj = env()->ArrayStoreException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
577 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 ex_obj = env()->ClassCastException_instance();
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if (failing()) { stop(); return; } // exception allocation might fail
a61af66fc99e Initial load
duke
parents:
diff changeset
583 if (ex_obj != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // Cheat with a preallocated exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 if (C->log() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
586 C->log()->elem("hot_throw preallocated='1' reason='%s'",
a61af66fc99e Initial load
duke
parents:
diff changeset
587 Deoptimization::trap_reason_name(reason));
a61af66fc99e Initial load
duke
parents:
diff changeset
588 const TypeInstPtr* ex_con = TypeInstPtr::make(ex_obj);
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
589 Node* ex_node = _gvn.transform( ConNode::make(C, ex_con) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
590
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Clear the detail message of the preallocated exception object.
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // Weblogic sometimes mutates the detail message of exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // using reflection.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 int offset = java_lang_Throwable::get_detailMessage_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
595 const TypePtr* adr_typ = ex_con->add_offset(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 Node *adr = basic_plus_adr(ex_node, ex_node, offset);
1965
f264f4c42799 7000491: assert(false) failed: should be optimized out in SharedRuntime::g1_wb_pre
kvn
parents: 1786
diff changeset
598 const TypeOopPtr* val_type = TypeOopPtr::make_from_klass(env()->String_klass());
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
599 // Conservatively release stores of object references.
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
600 Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), val_type, T_OBJECT, MemNode::release);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602 add_exception_state(make_exception_state(ex_node));
a61af66fc99e Initial load
duke
parents:
diff changeset
603 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // %%% Maybe add entry to OptoRuntime which directly throws the exc.?
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // It won't be much cheaper than bailing to the interp., since we'll
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // have to pass up all the debug-info, and the runtime will have to
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // create the stack trace.
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // Usual case: Bail to interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // Reserve the right to recompile if we haven't seen anything yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615 Deoptimization::DeoptAction action = Deoptimization::Action_maybe_recompile;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 if (treat_throw_as_hot
a61af66fc99e Initial load
duke
parents:
diff changeset
617 && (method()->method_data()->trap_recompiled_at(bci())
a61af66fc99e Initial load
duke
parents:
diff changeset
618 || C->too_many_traps(reason))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // We cannot afford to take more traps here. Suffer in the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
620 if (C->log() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
621 C->log()->elem("hot_throw preallocated='0' reason='%s' mcount='%d'",
a61af66fc99e Initial load
duke
parents:
diff changeset
622 Deoptimization::trap_reason_name(reason),
a61af66fc99e Initial load
duke
parents:
diff changeset
623 C->trap_count(reason));
a61af66fc99e Initial load
duke
parents:
diff changeset
624 action = Deoptimization::Action_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // "must_throw" prunes the JVM state to include only the stack, if there
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // are no local exception handlers. This should cut down on register
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // allocation time and code size, by drastically reducing the number
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // of in-edges on the call to the uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 uncommon_trap(reason, action, (ciKlass*)NULL, (char*)NULL, must_throw);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 //----------------------------PreserveJVMState---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
637 PreserveJVMState::PreserveJVMState(GraphKit* kit, bool clone_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 debug_only(kit->verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
639 _kit = kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
640 _map = kit->map(); // preserve the map
a61af66fc99e Initial load
duke
parents:
diff changeset
641 _sp = kit->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
642 kit->set_map(clone_map ? kit->clone_map() : NULL);
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
643 Compile::current()->inc_preserve_jvm_state();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
644 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _bci = kit->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
646 Parse* parser = kit->is_Parse();
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 366
diff changeset
647 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648 _block = block;
a61af66fc99e Initial load
duke
parents:
diff changeset
649 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651 PreserveJVMState::~PreserveJVMState() {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 GraphKit* kit = _kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
653 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
654 assert(kit->bci() == _bci, "bci must not shift");
a61af66fc99e Initial load
duke
parents:
diff changeset
655 Parse* parser = kit->is_Parse();
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 366
diff changeset
656 int block = (parser == NULL || parser->block() == NULL) ? -1 : parser->block()->rpo();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
657 assert(block == _block, "block must not shift");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
659 kit->set_map(_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 kit->set_sp(_sp);
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
661 Compile::current()->dec_preserve_jvm_state();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 //-----------------------------BuildCutout-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
666 BuildCutout::BuildCutout(GraphKit* kit, Node* p, float prob, float cnt)
a61af66fc99e Initial load
duke
parents:
diff changeset
667 : PreserveJVMState(kit)
a61af66fc99e Initial load
duke
parents:
diff changeset
668 {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(p->is_Con() || p->is_Bool(), "test must be a bool");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 SafePointNode* outer_map = _map; // preserved map is caller's
a61af66fc99e Initial load
duke
parents:
diff changeset
671 SafePointNode* inner_map = kit->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
672 IfNode* iff = kit->create_and_map_if(outer_map->control(), p, prob, cnt);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
673 outer_map->set_control(kit->gvn().transform( new (kit->C) IfTrueNode(iff) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
674 inner_map->set_control(kit->gvn().transform( new (kit->C) IfFalseNode(iff) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676 BuildCutout::~BuildCutout() {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 GraphKit* kit = _kit;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 assert(kit->stopped(), "cutout code must stop, throw, return, etc.");
a61af66fc99e Initial load
duke
parents:
diff changeset
679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
680
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
681 //---------------------------PreserveReexecuteState----------------------------
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
682 PreserveReexecuteState::PreserveReexecuteState(GraphKit* kit) {
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
683 assert(!kit->stopped(), "must call stopped() before");
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
684 _kit = kit;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
685 _sp = kit->sp();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
686 _reexecute = kit->jvms()->_reexecute;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
687 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
688 PreserveReexecuteState::~PreserveReexecuteState() {
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
689 if (_kit->stopped()) return;
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
690 _kit->jvms()->_reexecute = _reexecute;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
691 _kit->set_sp(_sp);
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
692 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 //------------------------------clone_map--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // Implementation of PreserveJVMState
a61af66fc99e Initial load
duke
parents:
diff changeset
696 //
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // Only clone_map(...) here. If this function is only used in the
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // PreserveJVMState class we may want to get rid of this extra
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // function eventually and do it all there.
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 SafePointNode* GraphKit::clone_map() {
a61af66fc99e Initial load
duke
parents:
diff changeset
702 if (map() == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // Clone the memory edge first
a61af66fc99e Initial load
duke
parents:
diff changeset
705 Node* mem = MergeMemNode::make(C, map()->memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
706 gvn().set_type_bottom(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 SafePointNode *clonemap = (SafePointNode*)map()->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
709 JVMState* jvms = this->jvms();
a61af66fc99e Initial load
duke
parents:
diff changeset
710 JVMState* clonejvms = jvms->clone_shallow(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 clonemap->set_memory(mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 clonemap->set_jvms(clonejvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 clonejvms->set_map(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 record_for_igvn(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
715 gvn().set_type_bottom(clonemap);
a61af66fc99e Initial load
duke
parents:
diff changeset
716 return clonemap;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 //-----------------------------set_map_clone-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
721 void GraphKit::set_map_clone(SafePointNode* m) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 _map = m;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 _map = clone_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
724 _map->set_next_exception(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 debug_only(verify_map());
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 //----------------------------kill_dead_locals---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // Detect any locals which are known to be dead, and force them to top.
a61af66fc99e Initial load
duke
parents:
diff changeset
731 void GraphKit::kill_dead_locals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // Consult the liveness information for the locals. If any
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // of them are unused, then they can be replaced by top(). This
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
736
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // This call is made from many of the bytecode handling
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // subroutines called from the Big Switch in do_one_bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // Every bytecode which might include a slow path is responsible
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // for killing its dead locals. The more consistent we
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // are about killing deads, the fewer useless phis will be
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // constructed for them at various merge points.
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // bci can be -1 (InvocationEntryBci). We return the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // liveness for the method.
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 if (method() == NULL || method()->code_size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // We are building a graph for a call to a native method.
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // All locals are live.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // Consult the liveness information for the locals. If any
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // of them are unused, then they can be replaced by top(). This
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
759 MethodLivenessResult live_locals = method()->liveness_at_bci(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 int len = (int)live_locals.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
762 assert(len <= jvms()->loc_size(), "too many live locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
763 for (int local = 0; local < len; local++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 if (!live_locals.at(local)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 set_local(local, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
771 //-------------------------dead_locals_are_killed------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Return true if all dead locals are set to top in the map.
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // Used to assert "clean" debug info at various points.
a61af66fc99e Initial load
duke
parents:
diff changeset
774 bool GraphKit::dead_locals_are_killed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (method() == NULL || method()->code_size() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // No locals need to be dead, so all is as it should be.
a61af66fc99e Initial load
duke
parents:
diff changeset
777 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // Make sure somebody called kill_dead_locals upstream.
a61af66fc99e Initial load
duke
parents:
diff changeset
781 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 for (JVMState* jvms = this->jvms(); jvms != NULL; jvms = jvms->caller()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (jvms->loc_size() == 0) continue; // no locals to consult
a61af66fc99e Initial load
duke
parents:
diff changeset
784 SafePointNode* map = jvms->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
785 ciMethod* method = jvms->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
786 int bci = jvms->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if (jvms == this->jvms()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 bci = this->bci(); // it might not yet be synched
a61af66fc99e Initial load
duke
parents:
diff changeset
789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
790 MethodLivenessResult live_locals = method->liveness_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 int len = (int)live_locals.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
792 if (!live_locals.is_valid() || len == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
793 // This method is trivial, or is poisoned by a breakpoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
794 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
795 assert(len == jvms->loc_size(), "live map consistent with locals map");
a61af66fc99e Initial load
duke
parents:
diff changeset
796 for (int local = 0; local < len; local++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 if (!live_locals.at(local) && map->local(jvms, local) != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
799 tty->print_cr("Zombie local %d: ", local);
a61af66fc99e Initial load
duke
parents:
diff changeset
800 jvms->dump();
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
806 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
810
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
811 // Helper function for enforcing certain bytecodes to reexecute if
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
812 // deoptimization happens
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
813 static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
814 ciMethod* cur_method = jvms->method();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
815 int cur_bci = jvms->bci();
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
816 if (cur_method != NULL && cur_bci != InvocationEntryBci) {
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
817 Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
818 return Interpreter::bytecode_should_reexecute(code) ||
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
819 is_anewarray && code == Bytecodes::_multianewarray;
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
820 // Reexecute _multianewarray bytecode which was replaced with
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
821 // sequence of [a]newarray. See Parse::do_multianewarray().
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
822 //
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
823 // Note: interpreter should not have it set since this optimization
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
824 // is limited by dimensions and guarded by flag so in some cases
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
825 // multianewarray() runtime calls will be generated and
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
826 // the bytecode should not be reexecutes (stack will not be reset).
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
827 } else
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
828 return false;
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
829 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
830
0
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // Helper function for adding JVMState and debug information to node
a61af66fc99e Initial load
duke
parents:
diff changeset
832 void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // Add the safepoint edges to the call (or other safepoint).
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // Make sure dead locals are set to top. This
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // should help register allocation time and cut down on the size
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // of the deoptimization information.
a61af66fc99e Initial load
duke
parents:
diff changeset
838 assert(dead_locals_are_killed(), "garbage in debug info before safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // Walk the inline list to fill in the correct set of JVMState's
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // Also fill in the associated edges for each JVMState.
a61af66fc99e Initial load
duke
parents:
diff changeset
842
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
843 // If the bytecode needs to be reexecuted we need to put
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
844 // the arguments back on the stack.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
845 const bool should_reexecute = jvms()->should_reexecute();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
846 JVMState* youngest_jvms = should_reexecute ? sync_jvms_for_reexecute() : sync_jvms();
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
847
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
848 // NOTE: set_bci (called from sync_jvms) might reset the reexecute bit to
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
849 // undefined if the bci is different. This is normal for Parse but it
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
850 // should not happen for LibraryCallKit because only one bci is processed.
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
851 assert(!is_LibraryCallKit() || (jvms()->should_reexecute() == should_reexecute),
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
852 "in LibraryCallKit the reexecute bit should not change");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // If we are guaranteed to throw, we can prune everything but the
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // input to the current bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
856 bool can_prune_locals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
857 uint stack_slots_not_pruned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
858 int inputs = 0, depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 if (must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 assert(method() == youngest_jvms->method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (compute_stack_effects(inputs, depth)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 can_prune_locals = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
863 stack_slots_not_pruned = inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866
14477
96d2c94bbdd0 8035493: JVMTI PopFrame capability must instruct compilers not to prune locals
mgronlun
parents: 14223
diff changeset
867 if (env()->should_retain_local_variables()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // At any safepoint, this method can get breakpointed, which would
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // then require an immediate deoptimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 can_prune_locals = false; // do not prune locals
a61af66fc99e Initial load
duke
parents:
diff changeset
871 stack_slots_not_pruned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
873
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // do not scribble on the input jvms
a61af66fc99e Initial load
duke
parents:
diff changeset
875 JVMState* out_jvms = youngest_jvms->clone_deep(C);
a61af66fc99e Initial load
duke
parents:
diff changeset
876 call->set_jvms(out_jvms); // Start jvms list for call node
a61af66fc99e Initial load
duke
parents:
diff changeset
877
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
878 // For a known set of bytecodes, the interpreter should reexecute them if
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
879 // deoptimization happens. We set the reexecute state for them here
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
880 if (out_jvms->is_reexecute_undefined() && //don't change if already specified
1252
f516d5d7a019 6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
kvn
parents: 1166
diff changeset
881 should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) {
900
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
882 out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
883 }
9987d9d5eb0e 6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents: 851
diff changeset
884
0
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Presize the call:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
886 DEBUG_ONLY(uint non_debug_edges = call->req());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
887 call->add_req_batch(top(), youngest_jvms->debug_depth());
a61af66fc99e Initial load
duke
parents:
diff changeset
888 assert(call->req() == non_debug_edges + youngest_jvms->debug_depth(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // Set up edges so that the call looks like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // Call [state:] ctl io mem fptr retadr
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // [parms:] parm0 ... parmN
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // [root:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // [...mid:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN [...]
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // [young:] loc0 ... locN stk0 ... stkSP mon0 obj0 ... monN objN
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // Note that caller debug info precedes callee debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // Fill pointer walks backwards from "young:" to "root:" in the diagram above:
a61af66fc99e Initial load
duke
parents:
diff changeset
899 uint debug_ptr = call->req();
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // Loop over the map input edges associated with jvms, add them
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // to the call node, & reset all offsets to match call node array.
a61af66fc99e Initial load
duke
parents:
diff changeset
903 for (JVMState* in_jvms = youngest_jvms; in_jvms != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
904 uint debug_end = debug_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 uint debug_start = debug_ptr - in_jvms->debug_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
906 debug_ptr = debug_start; // back up the ptr
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 uint p = debug_start; // walks forward in [debug_start, debug_end)
a61af66fc99e Initial load
duke
parents:
diff changeset
909 uint j, k, l;
a61af66fc99e Initial load
duke
parents:
diff changeset
910 SafePointNode* in_map = in_jvms->map();
a61af66fc99e Initial load
duke
parents:
diff changeset
911 out_jvms->set_map(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 if (can_prune_locals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 assert(in_jvms->method() == out_jvms->method(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
915 // If the current throw can reach an exception handler in this JVMS,
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // then we must keep everything live that can reach that handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // As a quick and dirty approximation, we look for any handlers at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (in_jvms->method()->has_exception_handlers()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 can_prune_locals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // Add the Locals
a61af66fc99e Initial load
duke
parents:
diff changeset
924 k = in_jvms->locoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
925 l = in_jvms->loc_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 out_jvms->set_locoff(p);
1397
b4776199210f 6943485: JVMTI always on capabilities change code generation too much
never
parents: 1257
diff changeset
927 if (!can_prune_locals) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
928 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
929 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
930 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 p += l; // already set to top above by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // Add the Expression Stack
a61af66fc99e Initial load
duke
parents:
diff changeset
935 k = in_jvms->stkoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
936 l = in_jvms->sp();
a61af66fc99e Initial load
duke
parents:
diff changeset
937 out_jvms->set_stkoff(p);
1397
b4776199210f 6943485: JVMTI always on capabilities change code generation too much
never
parents: 1257
diff changeset
938 if (!can_prune_locals) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
939 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
940 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
941 } else if (can_prune_locals && stack_slots_not_pruned != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // Divide stack into {S0,...,S1}, where S0 is set to top.
a61af66fc99e Initial load
duke
parents:
diff changeset
943 uint s1 = stack_slots_not_pruned;
a61af66fc99e Initial load
duke
parents:
diff changeset
944 stack_slots_not_pruned = 0; // for next iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
945 if (s1 > l) s1 = l;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 uint s0 = l - s1;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 p += s0; // skip the tops preinstalled by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
948 for (j = s0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
949 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
950 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
951 p += l; // already set to top above by add_req_batch
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 // Add the Monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
955 k = in_jvms->monoff();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 l = in_jvms->mon_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
957 out_jvms->set_monoff(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
958 for (j = 0; j < l; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
959 call->set_req(p++, in_map->in(k+j));
a61af66fc99e Initial load
duke
parents:
diff changeset
960
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
961 // Copy any scalar object fields.
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
962 k = in_jvms->scloff();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
963 l = in_jvms->scl_size();
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
964 out_jvms->set_scloff(p);
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
965 for (j = 0; j < l; j++)
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
966 call->set_req(p++, in_map->in(k+j));
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
967
0
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // Finish the new jvms.
a61af66fc99e Initial load
duke
parents:
diff changeset
969 out_jvms->set_endoff(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 assert(out_jvms->endoff() == debug_end, "fill ptr must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
972 assert(out_jvms->depth() == in_jvms->depth(), "depth must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
973 assert(out_jvms->loc_size() == in_jvms->loc_size(), "size must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
974 assert(out_jvms->mon_size() == in_jvms->mon_size(), "size must match");
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 29
diff changeset
975 assert(out_jvms->scl_size() == in_jvms->scl_size(), "size must match");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
976 assert(out_jvms->debug_size() == in_jvms->debug_size(), "size must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // Update the two tail pointers in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
979 out_jvms = out_jvms->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
980 in_jvms = in_jvms->caller();
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 assert(debug_ptr == non_debug_edges, "debug info must fit exactly");
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // Test the correctness of JVMState::debug_xxx accessors:
a61af66fc99e Initial load
duke
parents:
diff changeset
986 assert(call->jvms()->debug_start() == non_debug_edges, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
987 assert(call->jvms()->debug_end() == call->req(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
988 assert(call->jvms()->debug_depth() == call->req() - non_debug_edges, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
991 bool GraphKit::compute_stack_effects(int& inputs, int& depth) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
992 Bytecodes::Code code = java_bc();
a61af66fc99e Initial load
duke
parents:
diff changeset
993 if (code == Bytecodes::_wide) {
a61af66fc99e Initial load
duke
parents:
diff changeset
994 code = method()->java_code_at_bci(bci() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 BasicType rtype = T_ILLEGAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 int rsize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 if (code != Bytecodes::_illegal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 depth = Bytecodes::depth(code); // checkcast=0, athrow=-1
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 rtype = Bytecodes::result_type(code); // checkcast=P, athrow=V
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 if (rtype < T_CONFLICT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 rsize = type2size[rtype];
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 case Bytecodes::_illegal:
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 case Bytecodes::_ldc:
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 case Bytecodes::_ldc_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 case Bytecodes::_ldc2_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 inputs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 case Bytecodes::_dup: inputs = 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 case Bytecodes::_dup_x1: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 case Bytecodes::_dup_x2: inputs = 3; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 case Bytecodes::_dup2: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 case Bytecodes::_dup2_x1: inputs = 3; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 case Bytecodes::_dup2_x2: inputs = 4; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 case Bytecodes::_swap: inputs = 2; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 case Bytecodes::_arraylength: inputs = 1; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 case Bytecodes::_getstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 case Bytecodes::_putstatic:
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 case Bytecodes::_getfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 case Bytecodes::_putfield:
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 {
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1031 bool ignored_will_link;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1032 ciField* field = method()->get_field_at_bci(bci(), ignored_will_link);
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1033 int size = field->type()->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 bool is_get = (depth >= 0), is_static = (depth & 1);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1035 inputs = (is_static ? 0 : 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if (is_get) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 depth = size - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 inputs += size; // putxxx pops the value from the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 depth = - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1044
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 case Bytecodes::_invokestatic:
726
be93aad57795 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 647
diff changeset
1048 case Bytecodes::_invokedynamic:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 {
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1051 bool ignored_will_link;
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1052 ciSignature* declared_signature = NULL;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1053 ciMethod* ignored_callee = method()->get_method_at_bci(bci(), ignored_will_link, &declared_signature);
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1054 assert(declared_signature != NULL, "cannot be null");
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1055 inputs = declared_signature->arg_size_for_bc(code);
6634
7f813940ac35 7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents: 6266
diff changeset
1056 int size = declared_signature->return_type()->size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 depth = size - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 case Bytecodes::_multianewarray:
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 ciBytecodeStream iter(method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 iter.reset_to_bci(bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 inputs = iter.get_dimensions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 assert(rsize == 1, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 depth = rsize - inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 case Bytecodes::_ireturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 case Bytecodes::_lreturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 case Bytecodes::_freturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 case Bytecodes::_dreturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 case Bytecodes::_areturn:
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 assert(rsize = -depth, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 inputs = rsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 case Bytecodes::_jsr:
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 case Bytecodes::_jsr_w:
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 inputs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 depth = 1; // S.B. depth=1, not zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // bytecode produces a typed result
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 inputs = rsize - depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 assert(inputs >= 0, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // spot check
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 int outputs = depth + inputs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 assert(outputs >= 0, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 switch (code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 case Bytecodes::_checkcast: assert(inputs == 1 && outputs == 1, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 case Bytecodes::_athrow: assert(inputs == 1 && outputs == 0, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 case Bytecodes::_aload_0: assert(inputs == 0 && outputs == 1, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 case Bytecodes::_return: assert(inputs == 0 && outputs == 0, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 case Bytecodes::_drem: assert(inputs == 4 && outputs == 2, ""); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 //------------------------------basic_plus_adr---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 if (offset == intcon(0)) return ptr;
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1116 return _gvn.transform( new (C) AddPNode(base, ptr, offset) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 Node* GraphKit::ConvI2L(Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 jint offset_con = find_int_con(offset, Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 if (offset_con != Type::OffsetBot) {
6846
377508648226 8000313: C2 should use jlong for 64bit values
vlivanov
parents: 6804
diff changeset
1123 return longcon((jlong) offset_con);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1125 return _gvn.transform( new (C) ConvI2LNode(offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 Node* GraphKit::ConvL2I(Node* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // short-circuit a common case
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 jlong offset_con = find_long_con(offset, (jlong)Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 if (offset_con != (jlong)Type::OffsetBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 return intcon((int) offset_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1133 return _gvn.transform( new (C) ConvL2INode(offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 //-------------------------load_object_klass-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 Node* GraphKit::load_object_klass(Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // Special-case a fresh allocation to avoid building nodes:
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 Node* akls = AllocateNode::Ideal_klass(obj, &_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if (akls != NULL) return akls;
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
1142 return _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), k_adr, TypeInstPtr::KLASS) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 //-------------------------load_array_length-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 Node* GraphKit::load_array_length(Node* array) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // Special-case a fresh allocation to avoid building nodes:
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1148 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(array, &_gvn);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1149 Node *alen;
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1150 if (alloc == NULL) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1151 Node *r_adr = basic_plus_adr(array, arrayOopDesc::length_offset_in_bytes());
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1152 alen = _gvn.transform( new (C) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS));
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1153 } else {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1154 alen = alloc->Ideal_length();
954
0f1c19b7a52d 6875619: CTW fails with /hotspot/src/share/vm/opto/type.hpp
kvn
parents: 950
diff changeset
1155 Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn);
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1156 if (ccast != alen) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1157 alen = _gvn.transform(ccast);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1158 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1159 }
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
1160 return alen;
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 //------------------------------do_null_check----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // Helper function to do a NULL pointer check. Returned value is
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // the incoming address with NULL casted away. You are allowed to use the
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // not-null value only if you are control dependent on the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 extern int explicit_null_checks_inserted,
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 explicit_null_checks_elided;
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 Node* GraphKit::null_check_common(Node* value, BasicType type,
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // optional arguments for variations:
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 bool assert_null,
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 Node* *null_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 assert(!assert_null || null_control == NULL, "not both at once");
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 if (stopped()) return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 if (!GenerateCompilerNullChecks && !assert_null && null_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // For some performance testing, we may wish to suppress null checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 value = cast_not_null(value); // Make it appear to be non-null (4962416).
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 explicit_null_checks_inserted++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // Construct NULL check
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 Node *chk = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 switch(type) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1185 case T_LONG : chk = new (C) CmpLNode(value, _gvn.zerocon(T_LONG)); break;
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1186 case T_INT : chk = new (C) CmpINode(value, _gvn.intcon(0)); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 case T_ARRAY : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 type = T_OBJECT; // simplify further tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 case T_OBJECT : {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 const Type *t = _gvn.type( value );
a61af66fc99e Initial load
duke
parents:
diff changeset
1191
950
8fe1963e3964 6875577: CTW fails with /hotspot/src/share/vm/opto/memnode.cpp
kvn
parents: 900
diff changeset
1192 const TypeOopPtr* tp = t->isa_oopptr();
955
26fbe81d30cf 6880052: SIGSEGV in GraphKit::null_check_common()
kvn
parents: 954
diff changeset
1193 if (tp != NULL && tp->klass() != NULL && !tp->klass()->is_loaded()
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Only for do_null_check, not any of its siblings:
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 && !assert_null && null_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Usually, any field access or invocation on an unloaded oop type
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // will simply fail to link, since the statically linked class is
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // likely also to be unloaded. However, in -Xcomp mode, sometimes
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // the static class is loaded but the sharper oop type is not.
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Rather than checking for this obscure case in lots of places,
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // we simply observe that a null check on an unloaded class
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // will always be followed by a nonsense operation, so we
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 // can just issue the uncommon trap here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // Our access to the unloaded class will only be correct
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // after it has been loaded and initialized, which requires
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // a trip through the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (WizardMode) { tty->print("Null check of unloaded "); tp->klass()->print(); tty->cr(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 uncommon_trap(Deoptimization::Reason_unloaded,
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 Deoptimization::Action_reinterpret,
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 tp->klass(), "!loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // See if the type is contained in NULL_PTR.
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // If so, then the value is already null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 if (t->higher_equal(TypePtr::NULL_PTR)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 return value; // Elided null assert quickly!
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // See if mixing in the NULL pointer changes type.
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // If so, then the NULL pointer was not allowed in the original
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // type. In other words, "value" was not-null.
14383
5ec7dace41a6 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 14223
diff changeset
1227 if (t->meet(TypePtr::NULL_PTR) != t->remove_speculative()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // same as: if (!TypePtr::NULL_PTR->higher_equal(t)) ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 return value; // Elided null check quickly!
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1233 chk = new (C) CmpPNode( value, null() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1237 default:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1238 fatal(err_msg_res("unexpected type: %s", type2name(type)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 assert(chk != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 chk = _gvn.transform(chk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 BoolTest::mask btest = assert_null ? BoolTest::eq : BoolTest::ne;
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1244 BoolNode *btst = new (C) BoolNode( chk, btest);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 Node *tst = _gvn.transform( btst );
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 //-----------
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
1248 // if peephole optimizations occurred, a prior test existed.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // If a prior test existed, maybe it dominates as we can avoid this test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 if (tst != btst && type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // At this point we want to scan up the CFG to see if we can
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 // find an identical test (and so avoid this test altogether).
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 Node *cfg = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 int depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 while( depth < 16 ) { // Limit search depth for speed
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 if( cfg->Opcode() == Op_IfTrue &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 cfg->in(0)->in(1) == tst ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // Found prior test. Use "cast_not_null" to construct an identical
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // CastPP (and hence hash to) as already exists for the prior test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Return that casted value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 replace_in_map(value, null());
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 return null(); // do not issue the redundant test
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 Node *oldcontrol = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 set_control(cfg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 Node *res = cast_not_null(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 set_control(oldcontrol);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 cfg = IfNode::up_one_dom(cfg, /*linear_only=*/ true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 if (cfg == NULL) break; // Quit at region nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 depth++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1277
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 //-----------
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // Branch to failure if null
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 float ok_prob = PROB_MAX; // a priori estimate: nulls never happen
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 Deoptimization::DeoptReason reason;
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 if (assert_null)
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 reason = Deoptimization::Reason_null_assert;
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 else if (type == T_OBJECT)
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 reason = Deoptimization::Reason_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 reason = Deoptimization::Reason_div0_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1289 // %%% Since Reason_unhandled is not recorded on a per-bytecode basis,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1290 // ciMethodData::has_trap_at will return a conservative -1 if any
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1291 // must-be-null assertion has failed. This could cause performance
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1292 // problems for a method after its first do_null_assert failure.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1293 // Consider using 'Reason_class_check' instead?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1294
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // To cause an implicit null check, we set the not-null probability
605
98cb887364d3 6810672: Comment typos
twisti
parents: 570
diff changeset
1296 // to the maximum (PROB_MAX). For an explicit check the probability
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // is set to a smaller value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 if (null_control != NULL || too_many_traps(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // probability is less likely
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 ok_prob = PROB_LIKELY_MAG(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 } else if (!assert_null &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 (ImplicitNullCheckThreshold > 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 method() != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 (method()->method_data()->trap_count(reason)
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 >= (uint)ImplicitNullCheckThreshold)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 ok_prob = PROB_LIKELY_MAG(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if (null_control != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 IfNode* iff = create_and_map_if(control(), tst, ok_prob, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1311 Node* null_true = _gvn.transform( new (C) IfFalseNode(iff));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1312 set_control( _gvn.transform( new (C) IfTrueNode(iff)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 if (null_true == top())
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 (*null_control) = null_true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 BuildCutout unless(this, tst, ok_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // Check for optimizer eliding test at parse time
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // Failure not possible; do not bother making uncommon trap.
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 explicit_null_checks_elided++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 } else if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 uncommon_trap(reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 Deoptimization::Action_make_not_entrant,
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 NULL, "assert_null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 } else {
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 196
diff changeset
1327 replace_in_map(value, zerocon(type));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 builtin_throw(reason);
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // Must throw exception, fall-thru not possible?
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if (stopped()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 return top(); // No result
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 if (assert_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // Cast obj to null on this path.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 replace_in_map(value, zerocon(type));
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 return zerocon(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // Cast obj to not-null on this path, if there is no null_control.
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // (If there is a null_control, a non-null value may come back to haunt us.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 if (type == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 Node* cast = cast_not_null(value, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (null_control == NULL || (*null_control) == top())
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 replace_in_map(value, cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 value = cast;
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 //------------------------------cast_not_null----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // Cast obj to not-null on this path
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 const Type *t = _gvn.type(obj);
14383
5ec7dace41a6 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 14223
diff changeset
1360 const Type *t_not_null = t->join_speculative(TypePtr::NOTNULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // Object is already not-null?
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 if( t == t_not_null ) return obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1364 Node *cast = new (C) CastPPNode(obj,t_not_null);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 cast->init_req(0, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 cast = _gvn.transform( cast );
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // Scan for instances of 'obj' in the current JVM mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // These instances are known to be not-null after the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 if (do_replace_in_map)
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 replace_in_map(obj, cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
1372
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 return cast; // Return casted value
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 //--------------------------replace_in_map-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 void GraphKit::replace_in_map(Node* old, Node* neww) {
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1379 if (old == neww) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1380 return;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1381 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1382
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1383 map()->replace_edge(old, neww);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // Note: This operation potentially replaces any edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // on the map. This includes locals, stack, and monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // of the current (innermost) JVM state.
a61af66fc99e Initial load
duke
parents:
diff changeset
1388
12956
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1389 if (!ReplaceInParentMaps) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1390 return;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1391 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1392
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1393 // PreserveJVMState doesn't do a deep copy so we can't modify
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1394 // parents
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1395 if (Compile::current()->has_preserve_jvm_state()) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1396 return;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1397 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1398
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1399 Parse* parser = is_Parse();
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1400 bool progress = true;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1401 Node* ctrl = map()->in(0);
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1402 // Follow the chain of parsers and see whether the update can be
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1403 // done in the map of callers. We can do the replace for a caller if
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1404 // the current control post dominates the control of a caller.
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1405 while (parser != NULL && parser->caller() != NULL && progress) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1406 progress = false;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1407 Node* parent_map = parser->caller()->map();
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1408 assert(parser->exits().map()->jvms()->depth() == parser->caller()->depth(), "map mismatch");
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1409
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1410 Node* parent_ctrl = parent_map->in(0);
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1411
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1412 while (parent_ctrl->is_Region()) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1413 Node* n = parent_ctrl->as_Region()->is_copy();
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1414 if (n == NULL) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1415 break;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1416 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1417 parent_ctrl = n;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1418 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1419
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1420 for (;;) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1421 if (ctrl == parent_ctrl) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1422 // update the map of the exits which is the one that will be
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1423 // used when compilation resume after inlining
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1424 parser->exits().map()->replace_edge(old, neww);
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1425 progress = true;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1426 break;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1427 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1428 if (ctrl->is_Proj() && ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1429 ctrl = ctrl->in(0)->in(0);
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1430 } else if (ctrl->is_Region()) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1431 Node* n = ctrl->as_Region()->is_copy();
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1432 if (n == NULL) {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1433 break;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1434 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1435 ctrl = n;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1436 } else {
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1437 break;
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1438 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1439 }
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1440
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1441 parser = parser->parent_parser();
3213ba4d3dff 8024069: replace_in_map() should operate on parent maps
roland
parents: 12886
diff changeset
1442 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 //--------------------------------memory---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 Node* GraphKit::memory(uint alias_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 MergeMemNode* mem = merged_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 Node* p = mem->memory_at(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 _gvn.set_type(p, Type::MEMORY); // must be mapped
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1454
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 //-----------------------------reset_memory------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 Node* GraphKit::reset_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 Node* mem = map()->memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // do not use this node for any more parsing!
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 debug_only( map()->set_memory((Node*)NULL) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 return _gvn.transform( mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 //------------------------------set_all_memory---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 void GraphKit::set_all_memory(Node* newmem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 Node* mergemem = MergeMemNode::make(C, newmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 gvn().set_type_bottom(mergemem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 map()->set_memory(mergemem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1469
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 //------------------------------set_all_memory_call----------------------------
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1471 void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1472 Node* newmem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory, separate_io_proj) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 set_all_memory(newmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // parser factory methods for MemNodes
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // These are layered on top of the factory methods in LoadNode and StoreNode,
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // and integrate with the parser's memory state and _gvn engine.
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // factory methods in "int adr_idx"
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 int adr_idx,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1487 MemNode::MemOrd mo, bool require_atomic_access) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 const TypePtr* adr_type = NULL; // debug-mode-only argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 Node* mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 Node* ld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 if (require_atomic_access && bt == T_LONG) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1494 ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 } else {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1496 ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 }
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1498 ld = _gvn.transform(ld);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1499 if ((bt == T_OBJECT) && C->do_escape_analysis() || C->eliminate_boxing()) {
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1500 // Improve graph before escape analysis and boxing elimination.
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1501 record_for_igvn(ld);
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1502 }
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
1503 return ld;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1505
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 int adr_idx,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1508 MemNode::MemOrd mo,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 bool require_atomic_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 const TypePtr* adr_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 debug_only(adr_type = C->get_adr_type(adr_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 Node *mem = memory(adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 Node* st;
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 if (require_atomic_access && bt == T_LONG) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1516 st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 } else {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1518 st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 st = _gvn.transform(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 set_memory(st, adr_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // Back-to-back stores can only remove intermediate store with DU info
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // so push on worklist for optimizer.
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 if (mem->req() > MemNode::Address && adr == mem->in(MemNode::Address))
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 record_for_igvn(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1530
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1531 void GraphKit::pre_barrier(bool do_load,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1532 Node* ctl,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 Node* obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 Node* adr,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1535 uint adr_idx,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1536 Node* val,
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1537 const TypeOopPtr* val_type,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1538 Node* pre_val,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 BasicType bt) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1540
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 set_control(ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 switch (bs->kind()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1544 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1545 case BarrierSet::G1SATBCTLogging:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1546 g1_write_barrier_pre(do_load, obj, adr, adr_idx, val, val_type, pre_val, bt);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1547 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1553
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1557
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1561 bool GraphKit::can_move_pre_barrier() const {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1562 BarrierSet* bs = Universe::heap()->barrier_set();
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1563 switch (bs->kind()) {
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1564 case BarrierSet::G1SATBCT:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1565 case BarrierSet::G1SATBCTLogging:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1566 return true; // Can move it if no safepoint
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1567
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1568 case BarrierSet::CardTableModRef:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1569 case BarrierSet::CardTableExtension:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1570 case BarrierSet::ModRef:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1571 return true; // There is no pre-barrier
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1572
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1573 case BarrierSet::Other:
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1574 default :
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1575 ShouldNotReachHere();
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1576 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1577 return false;
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1578 }
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
1579
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 void GraphKit::post_barrier(Node* ctl,
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 Node* store,
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 Node* obj,
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 Node* adr,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1584 uint adr_idx,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1585 Node* val,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 BasicType bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 bool use_precise) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 set_control(ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 switch (bs->kind()) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1591 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1592 case BarrierSet::G1SATBCTLogging:
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1593 g1_write_barrier_post(store, obj, adr, adr_idx, val, bt, use_precise);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
1594 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1595
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 case BarrierSet::CardTableExtension:
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
1598 write_barrier_post(store, obj, adr, adr_idx, val, use_precise);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1603
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1607
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1611 Node* GraphKit::store_oop(Node* ctl,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1612 Node* obj,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1613 Node* adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1614 const TypePtr* adr_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1615 Node* val,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1616 const TypeOopPtr* val_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1617 BasicType bt,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1618 bool use_precise,
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1619 MemNode::MemOrd mo) {
4894
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1620 // Transformation of a value which could be NULL pointer (CastPP #NULL)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1621 // could be delayed during Parse (for example, in adjust_map_after_if()).
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1622 // Execute transformation here to avoid barrier generation in such case.
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1623 if (_gvn.type(val) == TypePtr::NULL_PTR)
b9bc6cae88f2 7143491: G1 C2 CTW: assert(p2x->outcnt() == 2) failed: expects 2 users: Xor and URShift nodes
kvn
parents: 4763
diff changeset
1624 val = _gvn.makecon(TypePtr::NULL_PTR);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1625
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1626 set_control(ctl);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1627 if (stopped()) return top(); // Dead path ?
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1628
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1629 assert(bt == T_OBJECT, "sanity");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1630 assert(val != NULL, "not dead path");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 uint adr_idx = C->get_alias_index(adr_type);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1632 assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1633
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1634 pre_barrier(true /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1635 control(), obj, adr, adr_idx, val, val_type,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1636 NULL /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1637 bt);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
1638
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1639 Node* store = store_to_memory(control(), adr, val, bt, adr_idx, mo);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1640 post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 return store;
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1644 // Could be an array or object we don't know at compile time (unsafe ref.)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 Node* GraphKit::store_oop_to_unknown(Node* ctl,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1646 Node* obj, // containing obj
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1647 Node* adr, // actual adress to store val at
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1648 const TypePtr* adr_type,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
1649 Node* val,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1650 BasicType bt,
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1651 MemNode::MemOrd mo) {
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1652 Compile::AliasType* at = C->alias_type(adr_type);
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1653 const TypeOopPtr* val_type = NULL;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1654 if (adr_type->isa_instptr()) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1655 if (at->field() != NULL) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1656 // known field. This code is a copy of the do_put_xxx logic.
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1657 ciField* field = at->field();
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1658 if (!field->type()->is_loaded()) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1659 val_type = TypeInstPtr::BOTTOM;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1660 } else {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1661 val_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1662 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1663 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1664 } else if (adr_type->isa_aryptr()) {
827
bf3489cc0aa0 6856025: assert(_base >= OopPtr && _base <= KlassPtr,"Not a Java pointer")
never
parents: 825
diff changeset
1665 val_type = adr_type->is_aryptr()->elem()->make_oopptr();
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1666 }
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1667 if (val_type == NULL) {
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1668 val_type = TypeInstPtr::BOTTOM;
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
1669 }
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1670 return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true, mo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 //-------------------------array_element_address-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 const TypeInt* sizetype) {
29
d5fc211aea19 6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents: 23
diff changeset
1677 uint shift = exact_log2(type2aelembytes(elembt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 uint header = arrayOopDesc::base_offset_in_bytes(elembt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 // short-circuit a common case (saves lots of confusing waste motion)
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 jint idx_con = find_int_con(idx, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 if (idx_con >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 intptr_t offset = header + ((intptr_t)idx_con << shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 return basic_plus_adr(ary, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // must be correct type for alignment purposes
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 Node* base = basic_plus_adr(ary, header);
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // The scaled index operand to AddP must be a clean 64-bit value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // Java allows a 32-bit int to be incremented to a negative
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // value, which appears in a 64-bit register as a large
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 // positive number. Using that large positive number as an
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // operand in pointer arithmetic has bad consequences.
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // On the other hand, 32-bit overflow is rare, and the possibility
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // can often be excluded, if we annotate the ConvI2L node with
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 // a type assertion that its value is known to be a small positive
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // number. (The prior range check has ensured this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // This assertion is used by ConvI2LNode::Ideal.
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 int index_max = max_jint - 1; // array size is max_jint, index is one less
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 if (sizetype != NULL) index_max = sizetype->_hi - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1703 idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 #endif
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1705 Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 return basic_plus_adr(ary, base, scale);
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 //-------------------------load_array_element-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 Node* GraphKit::load_array_element(Node* ctl, Node* ary, Node* idx, const TypeAryPtr* arytype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 const Type* elemtype = arytype->elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 BasicType elembt = elemtype->array_element_basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 Node* adr = array_element_address(ary, idx, elembt, arytype->size());
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1714 Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 return ld;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1717
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 //-------------------------set_arguments_for_java_call-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // Arguments (pre-popped from the stack) are taken from the JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 void GraphKit::set_arguments_for_java_call(CallJavaNode* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // Add the call arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 uint nargs = call->method()->arg_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 for (uint i = 0; i < nargs; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 Node* arg = argument(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 call->init_req(i + TypeFunc::Parms, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 //---------------------------set_edges_for_java_call---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // Connect a newly created call into the current JVMS.
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 // A return value node (if any) is returned from set_edges_for_java_call.
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1732 void GraphKit::set_edges_for_java_call(CallJavaNode* call, bool must_throw, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // Add the predefined inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 call->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 call->init_req( TypeFunc::I_O , i_o() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 call->init_req( TypeFunc::Memory , reset_memory() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 call->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 call->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 add_safepoint_edges(call, must_throw);
a61af66fc99e Initial load
duke
parents:
diff changeset
1742
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 Node* xcall = _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 if (xcall == top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 assert(xcall == call, "call identity is stable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1750
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // Re-use the current map to produce the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1752
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1753 set_control(_gvn.transform(new (C) ProjNode(call, TypeFunc::Control)));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1754 set_i_o( _gvn.transform(new (C) ProjNode(call, TypeFunc::I_O , separate_io_proj)));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1755 set_all_memory_call(xcall, separate_io_proj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 //return xcall; // no need, caller already has it
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1759
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1760 Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_proj) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 if (stopped()) return top(); // maybe the call folded up?
a61af66fc99e Initial load
duke
parents:
diff changeset
1762
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // Capture the return value, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 Node* ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 if (call->method() == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 call->method()->return_type()->basic_type() == T_VOID)
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 ret = top();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1768 else ret = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1769
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // Note: Since any out-of-line call can produce an exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // we always insert an I_O projection from the call into the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1772
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1773 make_slow_call_ex(call, env()->Throwable_klass(), separate_io_proj);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1774
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1775 if (separate_io_proj) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1776 // The caller requested separate projections be used by the fall
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1777 // through and exceptional paths, so replace the projections for
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1778 // the fall through path.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1779 set_i_o(_gvn.transform( new (C) ProjNode(call, TypeFunc::I_O) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1780 set_all_memory(_gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ));
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1781 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1784
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 //--------------------set_predefined_input_for_runtime_call--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // Reading and setting the memory state is way conservative here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // The real problem is that I am not doing real Type analysis on memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // so I cannot distinguish card mark stores from other stores. Across a GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // point the Store Barrier and the card mark memory has to agree. I cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // have a card mark store and its barrier split across the GC point from
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // either above or below. Here I get that to happen by reading ALL of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 // A better answer would be to separate out card marks from other memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // For now, return the input memory state, so that it can be reused
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // after the call, if this call has restricted memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // Set fixed predefined input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 Node* memory = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 call->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 call->init_req( TypeFunc::I_O, top() ); // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 call->init_req( TypeFunc::Memory, memory ); // may gc ptrs
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 call->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 call->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 return memory;
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1805
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 //-------------------set_predefined_output_for_runtime_call--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 // Set control and memory (not i_o) from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // If keep_mem is not NULL, use it for the output state,
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // except for the RawPtr output of the call, if hook_mem is TypeRawPtr::BOTTOM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // If hook_mem is NULL, this call produces no memory effects at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 // If hook_mem is a Java-visible memory slice (such as arraycopy operands),
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 // then only that memory slice is taken from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // In the last case, we must put an appropriate memory barrier before
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // the call, so as to create the correct anti-dependencies on loads
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // preceding the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 void GraphKit::set_predefined_output_for_runtime_call(Node* call,
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 Node* keep_mem,
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 const TypePtr* hook_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 // no i/o
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1820 set_control(_gvn.transform( new (C) ProjNode(call,TypeFunc::Control) ));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 if (keep_mem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // First clone the existing memory state
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 set_all_memory(keep_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (hook_mem != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 // Make memory for the call
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1826 Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 // Set the RawPtr memory state only. This covers all the heap top/GC stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // We also use hook_mem to extract specific effects from arraycopy stubs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 set_memory(mem, hook_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // ...else the call has NO memory effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // Make sure the call advertises its memory effects precisely.
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 // This lets us build accurate anti-dependences in gcm.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 assert(C->alias_type(call->adr_type()) == C->alias_type(hook_mem),
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 "call node must be constructed correctly");
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 assert(hook_mem == NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // This is not a "slow path" call; all memory comes from the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 set_all_memory_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1844
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1845 // Replace the call with the current state of the kit.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1846 void GraphKit::replace_call(CallNode* call, Node* result) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1847 JVMState* ejvms = NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1848 if (has_exceptions()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1849 ejvms = transfer_exceptions_into_jvms();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1850 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1851
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1852 SafePointNode* final_state = stop();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1853
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1854 // Find all the needed outputs of this call
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1855 CallProjections callprojs;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1856 call->extract_projections(&callprojs, true);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1857
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1858 Node* init_mem = call->in(TypeFunc::Memory);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1859 Node* final_mem = final_state->in(TypeFunc::Memory);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1860 Node* final_ctl = final_state->in(TypeFunc::Control);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1861 Node* final_io = final_state->in(TypeFunc::I_O);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1862
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1863 // Replace all the old call edges with the edges from the inlining result
7421
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1864 if (callprojs.fallthrough_catchproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1865 C->gvn_replace_by(callprojs.fallthrough_catchproj, final_ctl);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1866 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1867 if (callprojs.fallthrough_memproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1868 C->gvn_replace_by(callprojs.fallthrough_memproj, final_mem);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1869 }
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1870 if (callprojs.fallthrough_ioproj != NULL) {
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1871 C->gvn_replace_by(callprojs.fallthrough_ioproj, final_io);
ad5dd04754ee 8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents: 7196
diff changeset
1872 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1873
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1874 // Replace the result with the new result if it exists and is used
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1875 if (callprojs.resproj != NULL && result != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1876 C->gvn_replace_by(callprojs.resproj, result);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1877 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1878
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1879 if (ejvms == NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1880 // No exception edges to simply kill off those paths
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1881 if (callprojs.catchall_catchproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1882 C->gvn_replace_by(callprojs.catchall_catchproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1883 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1884 if (callprojs.catchall_memproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1885 C->gvn_replace_by(callprojs.catchall_memproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1886 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1887 if (callprojs.catchall_ioproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1888 C->gvn_replace_by(callprojs.catchall_ioproj, C->top());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1889 }
1099
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1890 // Replace the old exception object with top
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1891 if (callprojs.exobj != NULL) {
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1892 C->gvn_replace_by(callprojs.exobj, C->top());
c5d3d979ae27 6908167: jbb2005, OptimizeStringConcat causes assert in EA
never
parents: 1080
diff changeset
1893 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1894 } else {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1895 GraphKit ekit(ejvms);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1896
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1897 // Load my combined exception state into the kit, with all phis transformed:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1898 SafePointNode* ex_map = ekit.combine_and_pop_all_exception_states();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1899
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1900 Node* ex_oop = ekit.use_exception_state(ex_map);
7473
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1901 if (callprojs.catchall_catchproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1902 C->gvn_replace_by(callprojs.catchall_catchproj, ekit.control());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1903 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1904 if (callprojs.catchall_memproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1905 C->gvn_replace_by(callprojs.catchall_memproj, ekit.reset_memory());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1906 }
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1907 if (callprojs.catchall_ioproj != NULL) {
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1908 C->gvn_replace_by(callprojs.catchall_ioproj, ekit.i_o());
d092d1b31229 8005071: Incremental inlining for JSR 292
roland
parents: 7428
diff changeset
1909 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1910
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1911 // Replace the old exception object with the newly created one
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1912 if (callprojs.exobj != NULL) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1913 C->gvn_replace_by(callprojs.exobj, ex_oop);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1914 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1915 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1916
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1917 // Disconnect the call from the graph
7196
2aff40cb4703 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 7194
diff changeset
1918 call->disconnect_inputs(NULL, C);
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1919 C->gvn_replace_by(call, C->top());
1786
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1920
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1921 // Clean up any MergeMems that feed other MergeMems since the
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1922 // optimizer doesn't like that.
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1923 if (final_mem->is_MergeMem()) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1924 Node_List wl;
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1925 for (SimpleDUIterator i(final_mem); i.has_next(); i.next()) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1926 Node* m = i.get();
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1927 if (m->is_MergeMem() && !wl.contains(m)) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1928 wl.push(m);
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1929 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1930 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1931 while (wl.size() > 0) {
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1932 _gvn.transform(wl.pop());
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1933 }
f9883ee8ce39 6965815: OptimizeStringConcat: assert(!q->is_MergeMem()) failed with specjbb2000
never
parents: 1748
diff changeset
1934 }
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1935 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1936
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 1027
diff changeset
1937
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 //------------------------------increment_counter------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 // for statistics: increment a VM counter by 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1940
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 void GraphKit::increment_counter(address counter_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 Node* adr1 = makecon(TypeRawPtr::make(counter_addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 increment_counter(adr1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 void GraphKit::increment_counter(Node* counter_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 int adr_type = Compile::AliasIdxRaw;
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
1948 Node* ctrl = control();
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1949 Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
1950 Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
1951 store_to_memory(ctrl, counter_addr, incr, T_INT, adr_type, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1953
a61af66fc99e Initial load
duke
parents:
diff changeset
1954
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 //------------------------------uncommon_trap----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // Bail out to the interpreter in mid-method. Implemented by calling the
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // uncommon_trap blob. This helper function inserts a runtime call with the
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // right debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 void GraphKit::uncommon_trap(int trap_request,
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 ciKlass* klass, const char* comment,
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 bool must_throw,
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 bool keep_exact_action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 if (failing()) stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 if (stopped()) return; // trap reachable?
a61af66fc99e Initial load
duke
parents:
diff changeset
1965
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 // Note: If ProfileTraps is true, and if a deopt. actually
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 // occurs here, the runtime will make sure an MDO exists. There is
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 1972
diff changeset
1968 // no need to call method()->ensure_method_data() at this point.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1969
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1970 // Set the stack pointer to the right value for reexecution:
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1971 set_sp(reexecute_sp());
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1972
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 if (!must_throw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 // Make sure the stack has at least enough depth to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 // the current bytecode.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1977 int inputs, ignored_depth;
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1978 if (compute_stack_effects(inputs, ignored_depth)) {
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1979 assert(sp() >= inputs, err_msg_res("must have enough JVMS stack to execute %s: sp=%d, inputs=%d",
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
1980 Bytecodes::name(java_bc()), sp(), inputs));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(trap_request);
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(trap_request);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 switch (action) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 case Deoptimization::Action_maybe_recompile:
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 case Deoptimization::Action_reinterpret:
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 // Temporary fix for 6529811 to allow virtual calls to be sure they
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 // get the chance to go from mono->bi->mega
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 if (!keep_exact_action &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 Deoptimization::trap_request_index(trap_request) < 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 too_many_recompiles(reason)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // This BCI is causing too many recompilations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 action = Deoptimization::Action_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 trap_request = Deoptimization::make_trap_request(reason, action);
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 C->set_trap_can_recompile(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 case Deoptimization::Action_make_not_entrant:
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 C->set_trap_can_recompile(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 case Deoptimization::Action_none:
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 case Deoptimization::Action_make_not_compilable:
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 default:
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
2011 fatal(err_msg_res("unknown action %d: %s", action, Deoptimization::trap_action_name(action)));
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
2012 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 if (TraceOptoParse) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 tty->print_cr("Uncommon trap %s at bci:%d",
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 trap_request), bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 CompileLog* log = C->log();
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 if (log != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 int kid = (klass == NULL)? -1: log->identify(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 log->begin_elem("uncommon_trap bci='%d'", bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 char buf[100];
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 log->print(" %s", Deoptimization::format_trap_request(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 trap_request));
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 if (kid >= 0) log->print(" klass='%d'", kid);
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 if (comment != NULL) log->print(" comment='%s'", comment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 log->end_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2034
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // Make sure any guarding test views this path as very unlikely
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 Node *i0 = control()->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 if (i0 != NULL && i0->is_If()) { // Found a guarding if test?
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 IfNode *iff = i0->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 float f = iff->_prob; // Get prob
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 if (control()->Opcode() == Op_IfTrue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 if (f > PROB_UNLIKELY_MAG(4))
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 iff->_prob = PROB_MIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 if (f < PROB_LIKELY_MAG(4))
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 iff->_prob = PROB_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // Clear out dead values from the debug info.
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 kill_dead_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
2051
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 // Now insert the uncommon trap subroutine call
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1746
diff changeset
2053 address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 const TypePtr* no_memory_effects = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // Pass the index of the class to be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 Node* call = make_runtime_call(RC_NO_LEAF | RC_UNCOMMON |
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 (must_throw ? RC_MUST_THROW : 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 OptoRuntime::uncommon_trap_Type(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 call_addr, "uncommon_trap", no_memory_effects,
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 intcon(trap_request));
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 assert(call->as_CallStaticJava()->uncommon_trap_request() == trap_request,
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 "must extract request correctly from the graph");
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 assert(trap_request != 0, "zero value reserved by uncommon_trap_request");
a61af66fc99e Initial load
duke
parents:
diff changeset
2064
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 call->set_req(TypeFunc::ReturnAdr, returnadr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // The debug info is the only real input to this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2067
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 // Halt-and-catch fire here. The above call should never return!
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2069 HaltNode* halt = new(C) HaltNode(control(), frameptr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 _gvn.set_type_bottom(halt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 root()->add_req(halt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2072
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 stop_and_kill_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 //--------------------------just_allocated_object------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 // Report the object that was just allocated.
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // It must be the case that there are no intervening safepoints.
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // We use this to determine if an object is so "fresh" that
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // it does not require card marks.
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 Node* GraphKit::just_allocated_object(Node* current_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 if (C->recent_alloc_ctl() == current_control)
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 return C->recent_alloc_obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2087
a61af66fc99e Initial load
duke
parents:
diff changeset
2088
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 void GraphKit::round_double_arguments(ciMethod* dest_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // (Note: TypeFunc::make has a cache that makes this fast.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 const TypeFunc* tf = TypeFunc::make(dest_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 int nargs = tf->_domain->_cnt - TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 for (int j = 0; j < nargs; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 const Type *targ = tf->_domain->field_at(j + TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 if( targ->basic_type() == T_DOUBLE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // If any parameters are doubles, they must be rounded before
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // the call, dstore_rounding does gvn.transform
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 Node *arg = argument(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 arg = dstore_rounding(arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 set_argument(j, arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2105 /**
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2106 * Record profiling data exact_kls for Node n with the type system so
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2107 * that it can propagate it (speculation)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2108 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2109 * @param n node that the type applies to
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2110 * @param exact_kls type from profiling
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2111 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2112 * @return node with improved type
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2113 */
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2114 Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2115 const TypeOopPtr* current_type = _gvn.type(n)->isa_oopptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2116 assert(UseTypeSpeculation, "type speculation must be on");
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2117 if (exact_kls != NULL &&
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2118 // nothing to improve if type is already exact
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2119 (current_type == NULL ||
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2120 (!current_type->klass_is_exact() &&
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2121 (current_type->speculative() == NULL ||
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2122 !current_type->speculative()->klass_is_exact())))) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2123 const TypeKlassPtr* tklass = TypeKlassPtr::make(exact_kls);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2124 const TypeOopPtr* xtype = tklass->as_instance_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2125 assert(xtype->klass_is_exact(), "Should be exact");
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2126
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2127 // Build a type with a speculative type (what we think we know
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2128 // about the type but will need a guard when we use it)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2129 const TypeOopPtr* spec_type = TypeOopPtr::make(TypePtr::BotPTR, Type::OffsetBot, TypeOopPtr::InstanceBot, xtype);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2130 // We're changing the type, we need a new cast node to carry the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2131 // new type. The new type depends on the control: what profiling
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2132 // tells us is only valid from here as far as we can tell.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2133 Node* cast = new(C) CastPPNode(n, spec_type);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2134 cast->init_req(0, control());
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2135 cast = _gvn.transform(cast);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2136 replace_in_map(n, cast);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2137 n = cast;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2138 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2139 return n;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2140 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2141
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2142 /**
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2143 * Record profiling data from receiver profiling at an invoke with the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2144 * type system so that it can propagate it (speculation)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2145 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2146 * @param n receiver node
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2147 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2148 * @return node with improved type
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2149 */
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2150 Node* GraphKit::record_profiled_receiver_for_speculation(Node* n) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2151 if (!UseTypeSpeculation) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2152 return n;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2153 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2154 ciKlass* exact_kls = profile_has_unique_klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2155 return record_profile_for_speculation(n, exact_kls);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2156 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2157
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2158 /**
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2159 * Record profiling data from argument profiling at an invoke with the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2160 * type system so that it can propagate it (speculation)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2161 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2162 * @param dest_method target method for the call
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2163 * @param bc what invoke bytecode is this?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2164 */
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2165 void GraphKit::record_profiled_arguments_for_speculation(ciMethod* dest_method, Bytecodes::Code bc) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2166 if (!UseTypeSpeculation) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2167 return;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2168 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2169 const TypeFunc* tf = TypeFunc::make(dest_method);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2170 int nargs = tf->_domain->_cnt - TypeFunc::Parms;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2171 int skip = Bytecodes::has_receiver(bc) ? 1 : 0;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2172 for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2173 const Type *targ = tf->_domain->field_at(j + TypeFunc::Parms);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2174 if (targ->basic_type() == T_OBJECT || targ->basic_type() == T_ARRAY) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2175 ciKlass* better_type = method()->argument_profiled_type(bci(), i);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2176 if (better_type != NULL) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2177 record_profile_for_speculation(argument(j), better_type);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2178 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2179 i++;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2180 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2181 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2182 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2183
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2184 /**
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2185 * Record profiling data from parameter profiling at an invoke with
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2186 * the type system so that it can propagate it (speculation)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2187 */
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2188 void GraphKit::record_profiled_parameters_for_speculation() {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2189 if (!UseTypeSpeculation) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2190 return;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2191 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2192 for (int i = 0, j = 0; i < method()->arg_size() ; i++) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2193 if (_gvn.type(local(i))->isa_oopptr()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2194 ciKlass* better_type = method()->parameter_profiled_type(j);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2195 if (better_type != NULL) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2196 record_profile_for_speculation(local(i), better_type);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2197 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2198 j++;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2199 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2200 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2201 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2202
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 void GraphKit::round_double_result(ciMethod* dest_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 // A non-strict method may return a double value which has an extended
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // exponent, but this must not be visible in a caller which is 'strict'
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 // If a strict caller invokes a non-strict callee, round a double result
a61af66fc99e Initial load
duke
parents:
diff changeset
2207
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 BasicType result_type = dest_method->return_type()->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 assert( method() != NULL, "must have caller context");
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 if( result_type == T_DOUBLE && method()->is_strict() && !dest_method->is_strict() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 // Destination method's return value is on top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 // dstore_rounding() does gvn.transform
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 Node *result = pop_pair();
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 result = dstore_rounding(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 push_pair(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2218
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // rounding for strict float precision conformance
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 Node* GraphKit::precision_rounding(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 return UseStrictFP && _method->flags().is_strict()
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2223 ? _gvn.transform( new (C) RoundFloatNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2226
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // rounding for strict double precision conformance
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 Node* GraphKit::dprecision_rounding(Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 return UseStrictFP && _method->flags().is_strict()
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2231 ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // rounding for non-strict double stores
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 Node* GraphKit::dstore_rounding(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 return Matcher::strict_fp_requires_explicit_rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 && UseSSE <= 1
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2239 ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 : n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // Generate a fast path/slow path idiom. Graph looks like:
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 // [foo] indicates that 'foo' is a parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 // [in] NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 // \ /
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 // CmpP
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // Bool ne
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // If
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 // / \
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 // True False-<2>
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 // / |
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // / cast_not_null
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 // Load | | ^
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // [fast_test] | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 // gvn to opt_test | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 // / \ | <1>
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // True False |
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 // | \\ |
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 // [slow_call] \[fast_result]
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // Ctl Val \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 // Catch <1> \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // / \ ^ \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 // Ex No_Ex | \ \
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 // | \ \ | \ <2> \
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 // ... \ [slow_res] | | \ [null_result]
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // \ \--+--+--- | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // \ | / \ | /
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 // --------Region Phi
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 // Code is structured as a series of driver functions all called 'do_XXX' that
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 // call a set of helper functions. Helper functions first, then drivers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2277
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 //------------------------------null_check_oop---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 // Null check oop. Set null-path control into Region in slot 3.
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 // Make a cast-not-nullness use the other not-null control. Return cast.
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 Node* GraphKit::null_check_oop(Node* value, Node* *null_control,
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2282 bool never_see_null, bool safe_for_replace) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 // Initial NULL check taken path
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 (*null_control) = top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 Node* cast = null_check_common(value, T_OBJECT, false, null_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
2286
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // Generate uncommon_trap:
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 if (never_see_null && (*null_control) != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // If we see an unexpected null at a check-cast we record it and force a
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // recompile; the offending check-cast will be compiled to handle NULLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // If we see more than one offending BCI, then all checkcasts in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // method will be compiled to handle NULLs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 set_control(*null_control);
332
c792b641b8bd 6746907: Improve implicit null check generation
kvn
parents: 196
diff changeset
2295 replace_in_map(value, null());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 uncommon_trap(Deoptimization::Reason_null_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 Deoptimization::Action_make_not_entrant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 (*null_control) = top(); // NULL path is dead
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 }
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2300 if ((*null_control) == top() && safe_for_replace) {
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2301 replace_in_map(value, cast);
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2302 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2303
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 // Cast away null-ness on the result
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 return cast;
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2307
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 //------------------------------opt_iff----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 // Optimize the fast-check IfNode. Set the fast-path region slot 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 // Return slow-path control.
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 Node* GraphKit::opt_iff(Node* region, Node* iff) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 IfNode *opt_iff = _gvn.transform(iff)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2313
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // Fast path taken; set region slot 2
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2315 Node *fast_taken = _gvn.transform( new (C) IfFalseNode(opt_iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 region->init_req(2,fast_taken); // Capture fast-control
a61af66fc99e Initial load
duke
parents:
diff changeset
2317
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 // Fast path not-taken, i.e. slow path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2319 Node *slow_taken = _gvn.transform( new (C) IfTrueNode(opt_iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 return slow_taken;
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2322
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 //-----------------------------make_runtime_call-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 Node* GraphKit::make_runtime_call(int flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 const TypeFunc* call_type, address call_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 const char* call_name,
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 const TypePtr* adr_type,
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // The following parms are all optional.
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // The first NULL ends the list.
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 Node* parm0, Node* parm1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 Node* parm2, Node* parm3,
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 Node* parm4, Node* parm5,
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 Node* parm6, Node* parm7) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // Slow-path call
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 bool is_leaf = !(flags & RC_NO_LEAF);
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 bool has_io = (!is_leaf && !(flags & RC_NO_IO));
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 if (call_name == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 assert(!is_leaf, "must supply name for leaf");
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 call_name = OptoRuntime::stub_name(call_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 CallNode* call;
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 if (!is_leaf) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2343 call = new(C) CallStaticJavaNode(call_type, call_addr, call_name,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 bci(), adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 } else if (flags & RC_NO_FP) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2346 call = new(C) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2348 call = new(C) CallLeafNode(call_type, call_addr, call_name, adr_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // The following is similar to set_edges_for_java_call,
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 // except that the memory effects of the call are restricted to AliasIdxRaw.
a61af66fc99e Initial load
duke
parents:
diff changeset
2353
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // Slow path call has no side-effects, uses few values
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 bool wide_in = !(flags & RC_NARROW_MEM);
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 bool wide_out = (C->get_alias_index(adr_type) == Compile::AliasIdxBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
2357
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 Node* prev_mem = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 if (wide_in) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 prev_mem = set_predefined_input_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 assert(!wide_out, "narrow in => narrow out");
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 Node* narrow_mem = memory(adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 prev_mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 map()->set_memory(narrow_mem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 set_predefined_input_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2368
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 // Hook each parm in order. Stop looking at the first NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 if (parm0 != NULL) { call->init_req(TypeFunc::Parms+0, parm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 if (parm1 != NULL) { call->init_req(TypeFunc::Parms+1, parm1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 if (parm2 != NULL) { call->init_req(TypeFunc::Parms+2, parm2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 if (parm3 != NULL) { call->init_req(TypeFunc::Parms+3, parm3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 if (parm4 != NULL) { call->init_req(TypeFunc::Parms+4, parm4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 if (parm5 != NULL) { call->init_req(TypeFunc::Parms+5, parm5);
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 if (parm6 != NULL) { call->init_req(TypeFunc::Parms+6, parm6);
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 if (parm7 != NULL) { call->init_req(TypeFunc::Parms+7, parm7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 /* close each nested if ===> */ } } } } } } } }
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 assert(call->in(call->req()-1) != NULL, "must initialize all parms");
a61af66fc99e Initial load
duke
parents:
diff changeset
2380
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 if (!is_leaf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // Non-leaves can block and take safepoints:
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 add_safepoint_edges(call, ((flags & RC_MUST_THROW) != 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // Non-leaves can throw exceptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 if (has_io) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 call->set_req(TypeFunc::I_O, i_o());
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2389
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 if (flags & RC_UNCOMMON) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 // Set the count to a tiny probability. Cf. Estimate_Block_Frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 // (An "if" probability corresponds roughly to an unconditional count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 // Sort of.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 call->set_cnt(PROB_UNLIKELY_MAG(4));
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2396
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 Node* c = _gvn.transform(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 assert(c == call, "cannot disappear");
a61af66fc99e Initial load
duke
parents:
diff changeset
2399
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 if (wide_out) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // Slow path call has full side-effects.
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 set_predefined_output_for_runtime_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 // Slow path call has few side-effects, and/or sets few values.
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 set_predefined_output_for_runtime_call(call, prev_mem, adr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2407
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 if (has_io) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2409 set_i_o(_gvn.transform(new (C) ProjNode(call, TypeFunc::I_O)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 return call;
a61af66fc99e Initial load
duke
parents:
diff changeset
2412
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2414
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 //------------------------------merge_memory-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 // Merge memory from one path into the current memory state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 void GraphKit::merge_memory(Node* new_mem, Node* region, int new_path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 for (MergeMemStream mms(merged_memory(), new_mem->as_MergeMem()); mms.next_non_empty2(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 Node* old_slice = mms.force_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 Node* new_slice = mms.memory2();
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 if (old_slice != new_slice) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 PhiNode* phi;
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 if (new_slice->is_Phi() && new_slice->as_Phi()->region() == region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 phi = new_slice->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 if (old_slice->is_Phi() && old_slice->as_Phi()->region() == region)
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 old_slice = old_slice->in(new_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 // Caller is responsible for ensuring that any pre-existing
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 // phis are already aware of old memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 int old_path = (new_path > 1) ? 1 : 2; // choose old_path != new_path
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 assert(phi->in(old_path) == old_slice, "pre-existing phis OK");
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 mms.set_memory(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 phi = PhiNode::make(region, old_slice, Type::MEMORY, mms.adr_type(C));
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 _gvn.set_type(phi, Type::MEMORY);
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 phi->set_req(new_path, new_slice);
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 mms.set_memory(_gvn.transform(phi)); // assume it is complete
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2443
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 //------------------------------make_slow_call_ex------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 // Make the exception handler hookups for the slow call
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 if (stopped()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2448
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 // Make a catch node with just two handlers: fall-through and catch-all
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2450 Node* i_o = _gvn.transform( new (C) ProjNode(call, TypeFunc::I_O, separate_io_proj) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2451 Node* catc = _gvn.transform( new (C) CatchNode(control(), i_o, 2) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2452 Node* norm = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2453 Node* excp = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2454
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 { PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 set_control(excp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 set_i_o(i_o);
a61af66fc99e Initial load
duke
parents:
diff changeset
2458
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 if (excp != top()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 // Create an exception state also.
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 // Use an exact type if the caller has specified a specific exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2463 Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 add_exception_state(make_exception_state(_gvn.transform(ex_oop)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2467
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 // Get the no-exception control from the CatchNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 set_control(norm);
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2471
a61af66fc99e Initial load
duke
parents:
diff changeset
2472
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 //-------------------------------gen_subtype_check-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 // Generate a subtyping check. Takes as input the subtype and supertype.
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 // Returns 2 values: sets the default control() to the true path and returns
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 // the false path. Only reads invariant memory; sets no (visible) memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 // The PartialSubtypeCheckNode sets the hidden 1-word cache in the encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 // but that's not exposed to the optimizer. This call also doesn't take in an
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 // Object; if you wish to check an Object you need to load the Object's class
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 // prior to coming here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 Node* GraphKit::gen_subtype_check(Node* subklass, Node* superklass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 // Fast check for identical types, perhaps identical constants.
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 // The types can even be identical non-constants, in cases
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 // involving Array.newInstance, Object.clone, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 if (subklass == superklass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 return top(); // false path is dead; no test needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2487
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 if (_gvn.type(superklass)->singleton()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 ciKlass* superk = _gvn.type(superklass)->is_klassptr()->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 ciKlass* subk = _gvn.type(subklass)->is_klassptr()->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2491
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 // In the common case of an exact superklass, try to fold up the
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 // test before generating code. You may ask, why not just generate
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 // the code and then let it fold up? The answer is that the generated
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 // code will necessarily include null checks, which do not always
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 // completely fold away. If they are also needless, then they turn
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 // into a performance loss. Example:
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 // Foo[] fa = blah(); Foo x = fa[0]; fa[1] = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 // Here, the type of 'fa' is often exact, so the store check
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // of fa[1]=x will fold up, without testing the nullness of x.
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 switch (static_subtype_check(superk, subk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 case SSC_always_false:
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 Node* always_fail = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 set_control(top());
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 return always_fail;
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 case SSC_always_true:
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 return top();
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 case SSC_easy_test:
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 // Just do a direct pointer compare and be done.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2513 Node* cmp = _gvn.transform( new(C) CmpPNode(subklass, superklass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2514 Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2516 set_control( _gvn.transform( new(C) IfTrueNode (iff) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2517 return _gvn.transform( new(C) IfFalseNode(iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 case SSC_full_test:
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2525
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 // %%% Possible further optimization: Even if the superklass is not exact,
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 // if the subklass is the unique subtype of the superklass, the check
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 // will always succeed. We could leave a dependency behind to ensure this.
a61af66fc99e Initial load
duke
parents:
diff changeset
2529
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 // First load the super-klass's check-offset
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
2531 Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) );
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
2532 Node *chk_off = _gvn.transform(new (C) LoadINode(NULL, memory(p1), p1, _gvn.type(p1)->is_ptr(),
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
2533 TypeInt::INT, MemNode::unordered));
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
2534 int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
2536
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 // Load from the sub-klass's super-class display list, or a 1-word cache of
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 // the secondary superclass list, or a failing value with a sentinel offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 // if the super-klass is an interface or exceptionally deep in the Java
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 // hierarchy and we have to scan the secondary superclass list the hard way.
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 // Worst-case type is a little odd: NULL is allowed as a result (usually
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 // klass loads can never produce a NULL).
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 Node *chk_off_X = ConvI2X(chk_off);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2544 Node *p2 = _gvn.transform( new (C) AddPNode(subklass,subklass,chk_off_X) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // For some types like interfaces the following loadKlass is from a 1-word
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // cache which is mutable so can't use immutable memory. Other
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 // types load from the super-class display table which is immutable.
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
164
c436414a719e 6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents: 113
diff changeset
2549 Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // Compile speed common case: ARE a subtype and we canNOT fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 if( superklass == nkls )
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 return top(); // false path is dead; no test needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2554
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 // See if we get an immediate positive hit. Happens roughly 83% of the
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // time. Test to see if the value loaded just previously from the subklass
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // is exactly the superklass.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2558 Node *cmp1 = _gvn.transform( new (C) CmpPNode( superklass, nkls ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2559 Node *bol1 = _gvn.transform( new (C) BoolNode( cmp1, BoolTest::eq ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2561 Node *iftrue1 = _gvn.transform( new (C) IfTrueNode ( iff1 ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2562 set_control( _gvn.transform( new (C) IfFalseNode( iff1 ) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2563
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 // Compile speed common case: Check for being deterministic right now. If
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 // chk_off is a constant and not equal to cacheoff then we are NOT a
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 // subklass. In this case we need exactly the 1 test above and we can
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 // return those results immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 if (!might_be_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 Node* not_subtype_ctrl = control();
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 set_control(iftrue1); // We need exactly the 1 test above
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 return not_subtype_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2573
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 // Gather the various success & failures here
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2575 RegionNode *r_ok_subtype = new (C) RegionNode(4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 record_for_igvn(r_ok_subtype);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2577 RegionNode *r_not_subtype = new (C) RegionNode(3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 record_for_igvn(r_not_subtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
2579
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 r_ok_subtype->init_req(1, iftrue1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2581
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // Check for immediate negative hit. Happens roughly 11% of the time (which
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 // is roughly 63% of the remaining cases). Test to see if the loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 // check-offset points into the subklass display list or the 1-element
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // cache. If it points to the display (and NOT the cache) and the display
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 // missed then it's not a subtype.
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 Node *cacheoff = _gvn.intcon(cacheoff_con);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2588 Node *cmp2 = _gvn.transform( new (C) CmpINode( chk_off, cacheoff ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2589 Node *bol2 = _gvn.transform( new (C) BoolNode( cmp2, BoolTest::ne ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2591 r_not_subtype->init_req(1, _gvn.transform( new (C) IfTrueNode (iff2) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2592 set_control( _gvn.transform( new (C) IfFalseNode(iff2) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2593
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2594 // Check for self. Very rare to get here, but it is taken 1/3 the time.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 // No performance impact (too rare) but allows sharing of secondary arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 // which has some footprint reduction.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2597 Node *cmp3 = _gvn.transform( new (C) CmpPNode( subklass, superklass ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2598 Node *bol3 = _gvn.transform( new (C) BoolNode( cmp3, BoolTest::eq ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2600 r_ok_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode ( iff3 ) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2601 set_control( _gvn.transform( new (C) IfFalseNode( iff3 ) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2602
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2603 // -- Roads not taken here: --
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2604 // We could also have chosen to perform the self-check at the beginning
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2605 // of this code sequence, as the assembler does. This would not pay off
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2606 // the same way, since the optimizer, unlike the assembler, can perform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2607 // static type analysis to fold away many successful self-checks.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2608 // Non-foldable self checks work better here in second position, because
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2609 // the initial primary superclass check subsumes a self-check for most
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2610 // types. An exception would be a secondary type like array-of-interface,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2611 // which does not appear in its own primary supertype display.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2612 // Finally, we could have chosen to move the self-check into the
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2613 // PartialSubtypeCheckNode, and from there out-of-line in a platform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2614 // dependent manner. But it is worthwhile to have the check here,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2615 // where it can be perhaps be optimized. The cost in code space is
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2616 // small (register compare, branch).
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2617
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // Now do a linear scan of the secondary super-klass array. Again, no real
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 // performance impact (too rare) but it's gotta be done.
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 // Since the code is rarely used, there is no penalty for moving it
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2621 // out of line, and it can only improve I-cache density.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2622 // The decision to inline or out-of-line this final check is platform
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 605
diff changeset
2623 // dependent, and is found in the AD file definition of PartialSubtypeCheck.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 Node* psc = _gvn.transform(
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2625 new (C) PartialSubtypeCheckNode(control(), subklass, superklass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2626
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2627 Node *cmp4 = _gvn.transform( new (C) CmpPNode( psc, null() ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2628 Node *bol4 = _gvn.transform( new (C) BoolNode( cmp4, BoolTest::ne ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN );
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2630 r_not_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode (iff4) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2631 r_ok_subtype ->init_req(3, _gvn.transform( new (C) IfFalseNode(iff4) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2632
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 // Return false path; set default control to true path.
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 set_control( _gvn.transform(r_ok_subtype) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 return _gvn.transform(r_not_subtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2637
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 //----------------------------static_subtype_check-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 // Shortcut important common cases when superklass is exact:
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 // (0) superklass is java.lang.Object (can occur in reflective code)
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 // (1) subklass is already limited to a subtype of superklass => always ok
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 // (2) subklass does not overlap with superklass => always fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 // (3) superklass has NO subtypes and we can check with a simple compare.
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 int GraphKit::static_subtype_check(ciKlass* superk, ciKlass* subk) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 if (StressReflectiveCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 return SSC_full_test; // Let caller generate the general case.
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2648
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 if (superk == env()->Object_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 return SSC_always_true; // (0) this test cannot fail
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2652
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 ciType* superelem = superk;
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 if (superelem->is_array_klass())
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 superelem = superelem->as_array_klass()->base_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2656
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 if (!subk->is_interface()) { // cannot trust static interface types yet
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 if (subk->is_subtype_of(superk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 return SSC_always_true; // (1) false path dead; no dynamic test needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 if (!(superelem->is_klass() && superelem->as_klass()->is_interface()) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 !superk->is_subtype_of(subk)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 return SSC_always_false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2666
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 // If casting to an instance klass, it must have no subtypes
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 if (superk->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 // Cannot trust interfaces yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 // %%% S.B. superk->nof_implementors() == 1
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 } else if (superelem->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 ciInstanceKlass* ik = superelem->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 if (!ik->has_subklass() && !ik->is_interface()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 if (!ik->is_final()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 // Add a dependency if there is a chance of a later subclass.
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 C->dependencies()->assert_leaf_type(ik);
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 return SSC_easy_test; // (3) caller can do a simple ptr comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 // A primitive array type has no subtypes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 return SSC_easy_test; // (3) caller can do a simple ptr comparison
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2684
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 return SSC_full_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2687
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 // Profile-driven exact type check:
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 Node* GraphKit::type_check_receiver(Node* receiver, ciKlass* klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 float prob,
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 Node* *casted_receiver) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 const TypeKlassPtr* tklass = TypeKlassPtr::make(klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 Node* recv_klass = load_object_klass(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 Node* want_klass = makecon(tklass);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2695 Node* cmp = _gvn.transform( new(C) CmpPNode(recv_klass, want_klass) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2696 Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2698 set_control( _gvn.transform( new(C) IfTrueNode (iff) ));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2699 Node* fail = _gvn.transform( new(C) IfFalseNode(iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2700
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 const TypeOopPtr* recv_xtype = tklass->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 assert(recv_xtype->klass_is_exact(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
2703
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // Subsume downstream occurrences of receiver with a cast to
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // recv_xtype, since now we know what the type will be.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2706 Node* cast = new(C) CheckCastPPNode(control(), receiver, recv_xtype);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 (*casted_receiver) = _gvn.transform(cast);
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 // (User must make the replace_in_map call.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2709
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 return fail;
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2712
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2714 //------------------------------seems_never_null-------------------------------
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2715 // Use null_seen information if it is available from the profile.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2716 // If we see an unexpected null at a type check we record it and force a
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2717 // recompile; the offending check will be recompiled to handle NULLs.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2718 // If we see several offending BCIs, then all checks in the
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2719 // method will be recompiled.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2720 bool GraphKit::seems_never_null(Node* obj, ciProfileData* data) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2721 if (UncommonNullCast // Cutout for this technique
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2722 && obj != null() // And not the -Xcomp stupid case?
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2723 && !too_many_traps(Deoptimization::Reason_null_check)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2724 ) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2725 if (data == NULL)
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2726 // Edge case: no mature data. Be optimistic here.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2727 return true;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2728 // If the profile has not seen a null, assume it won't happen.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2729 assert(java_bc() == Bytecodes::_checkcast ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2730 java_bc() == Bytecodes::_instanceof ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2731 java_bc() == Bytecodes::_aastore, "MDO must collect null_seen bit here");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2732 return !data->as_BitData()->null_seen();
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2733 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2734 return false;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2735 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2736
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2737 //------------------------maybe_cast_profiled_receiver-------------------------
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2738 // If the profile has seen exactly one type, narrow to exactly that type.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2739 // Subsequent type checks will always fold up.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2740 Node* GraphKit::maybe_cast_profiled_receiver(Node* not_null_obj,
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2741 ciKlass* require_klass,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2742 ciKlass* spec_klass,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2743 bool safe_for_replace) {
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2744 if (!UseTypeProfile || !TypeProfileCasts) return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2745
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2746 // Make sure we haven't already deoptimized from this tactic.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2747 if (too_many_traps(Deoptimization::Reason_class_check))
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2748 return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2749
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2750 // (No, this isn't a call, but it's enough like a virtual call
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2751 // to use the same ciMethod accessor to get the profile info...)
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2752 // If we have a speculative type use it instead of profiling (which
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2753 // may not help us)
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2754 ciKlass* exact_kls = spec_klass == NULL ? profile_has_unique_klass() : spec_klass;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2755 if (exact_kls != NULL) {// no cast failures here
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2756 if (require_klass == NULL ||
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2757 static_subtype_check(require_klass, exact_kls) == SSC_always_true) {
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2758 // If we narrow the type to match what the type profile sees or
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2759 // the speculative type, we can then remove the rest of the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2760 // cast.
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2761 // This is a win, even if the exact_kls is very specific,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2762 // because downstream operations, such as method calls,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2763 // will often benefit from the sharper type.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2764 Node* exact_obj = not_null_obj; // will get updated in place...
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2765 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2766 &exact_obj);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2767 { PreserveJVMState pjvms(this);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2768 set_control(slow_ctl);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2769 uncommon_trap(Deoptimization::Reason_class_check,
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2770 Deoptimization::Action_maybe_recompile);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2771 }
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2772 if (safe_for_replace) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2773 replace_in_map(not_null_obj, exact_obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2774 }
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2775 return exact_obj;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2776 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2777 // assert(ssc == SSC_always_true)... except maybe the profile lied to us.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2778 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2779
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2780 return NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2781 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2782
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2783 /**
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2784 * Cast obj to type and emit guard unless we had too many traps here
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2785 * already
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2786 *
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2787 * @param obj node being casted
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2788 * @param type type to cast the node to
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2789 * @param not_null true if we know node cannot be null
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2790 */
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2791 Node* GraphKit::maybe_cast_profiled_obj(Node* obj,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2792 ciKlass* type,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2793 bool not_null) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2794 // type == NULL if profiling tells us this object is always null
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2795 if (type != NULL) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2796 if (!too_many_traps(Deoptimization::Reason_null_check) &&
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2797 !too_many_traps(Deoptimization::Reason_class_check)) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2798 Node* not_null_obj = NULL;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2799 // not_null is true if we know the object is not null and
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2800 // there's no need for a null check
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2801 if (!not_null) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2802 Node* null_ctl = top();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2803 not_null_obj = null_check_oop(obj, &null_ctl, true, true);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2804 assert(null_ctl->is_top(), "no null control here");
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2805 } else {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2806 not_null_obj = obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2807 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2808
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2809 Node* exact_obj = not_null_obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2810 ciKlass* exact_kls = type;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2811 Node* slow_ctl = type_check_receiver(exact_obj, exact_kls, 1.0,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2812 &exact_obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2813 {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2814 PreserveJVMState pjvms(this);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2815 set_control(slow_ctl);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2816 uncommon_trap(Deoptimization::Reason_class_check,
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2817 Deoptimization::Action_maybe_recompile);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2818 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2819 replace_in_map(not_null_obj, exact_obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2820 obj = exact_obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2821 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2822 } else {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2823 if (!too_many_traps(Deoptimization::Reason_null_assert)) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2824 Node* exact_obj = null_assert(obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2825 replace_in_map(obj, exact_obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2826 obj = exact_obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2827 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2828 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2829 return obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2830 }
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2831
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 //-------------------------------gen_instanceof--------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 // Generate an instance-of idiom. Used by both the instance-of bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // and the reflective instance-of call.
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2835 Node* GraphKit::gen_instanceof(Node* obj, Node* superklass, bool safe_for_replace) {
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2836 kill_dead_locals(); // Benefit all the uncommon traps
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 assert( !stopped(), "dead parse path should be checked in callers" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 assert(!TypePtr::NULL_PTR->higher_equal(_gvn.type(superklass)->is_klassptr()),
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 "must check for not-null not-dead klass in callers");
a61af66fc99e Initial load
duke
parents:
diff changeset
2840
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 // Make the merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2843 RegionNode* region = new(C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2844 Node* phi = new(C) PhiNode(region, TypeInt::BOOL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2846
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2847 ciProfileData* data = NULL;
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2848 if (java_bc() == Bytecodes::_instanceof) { // Only for the bytecode
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2849 data = method()->method_data()->bci_to_data(bci());
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2850 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2851 bool never_see_null = (ProfileDynamicTypes // aggressive use of profile
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2852 && seems_never_null(obj, data));
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2853
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 // Null check; get casted pointer; set region slot 3
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 Node* null_ctl = top();
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2856 Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2857
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // If not_null_obj is dead, only null-path is taken
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 if (stopped()) { // Doing instance-of on a NULL?
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 set_control(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 return intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 region->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 phi ->init_req(_null_path, intcon(0)); // Set null path value
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2865 if (null_ctl == top()) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2866 // Do this eagerly, so that pattern matches like is_diamond_phi
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2867 // will work even during parsing.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2868 assert(_null_path == PATH_LIMIT-1, "delete last");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2869 region->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2870 phi ->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2871 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2872
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2873 // Do we know the type check always succeed?
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2874 bool known_statically = false;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2875 if (_gvn.type(superklass)->singleton()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2876 ciKlass* superk = _gvn.type(superklass)->is_klassptr()->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2877 ciKlass* subk = _gvn.type(obj)->is_oopptr()->klass();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2878 if (subk != NULL && subk->is_loaded()) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2879 int static_res = static_subtype_check(superk, subk);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2880 known_statically = (static_res == SSC_always_true || static_res == SSC_always_false);
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2881 }
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2882 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2883
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2884 if (known_statically && UseTypeSpeculation) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2885 // If we know the type check always succeed then we don't use the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2886 // profiling data at this bytecode. Don't lose it, feed it to the
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2887 // type system as a speculative type.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2888 not_null_obj = record_profiled_receiver_for_speculation(not_null_obj);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2889 } else {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2890 const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2891 // We may not have profiling here or it may not help us. If we
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2892 // have a speculative type use it to perform an exact cast.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2893 ciKlass* spec_obj_type = obj_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2894 if (spec_obj_type != NULL || (ProfileDynamicTypes && data != NULL)) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2895 Node* cast_obj = maybe_cast_profiled_receiver(not_null_obj, NULL, spec_obj_type, safe_for_replace);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2896 if (stopped()) { // Profile disagrees with this path.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2897 set_control(null_ctl); // Null is the only remaining possibility.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2898 return intcon(0);
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2899 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2900 if (cast_obj != NULL) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2901 not_null_obj = cast_obj;
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2902 }
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2903 }
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2904 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2905
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 // Load the object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 Node* obj_klass = load_object_klass(not_null_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
2908
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 // Generate the subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 Node* not_subtype_ctrl = gen_subtype_check(obj_klass, superklass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2911
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 // Plug in the success path to the general merge in slot 1.
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 region->init_req(_obj_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 phi ->init_req(_obj_path, intcon(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2915
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 // Plug in the failing path to the general merge in slot 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 region->init_req(_fail_path, not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 phi ->init_req(_fail_path, intcon(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2919
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // Return final merged results
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 set_control( _gvn.transform(region) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 return _gvn.transform(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2925
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 //-------------------------------gen_checkcast---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // Generate a checkcast idiom. Used by both the checkcast bytecode and the
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // array store bytecode. Stack must be as-if BEFORE doing the bytecode so the
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 // uncommon-trap paths work. Adjust stack after this call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // If failure_control is supplied and not null, it is filled in with
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 // the control edge for the cast failure. Otherwise, an appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // uncommon trap or exception is thrown.
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 Node* *failure_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 kill_dead_locals(); // Benefit all the uncommon traps
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 const TypeKlassPtr *tk = _gvn.type(superklass)->is_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 const Type *toop = TypeOopPtr::make_from_klass(tk->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
2938
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // Fast cutout: Check the case that the cast is vacuously true.
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // This detects the common cases where the test will short-circuit
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 // away completely. We do this before we perform the null check,
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 // because if the test is going to turn into zero code, we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 // want a residual null check left around. (Causes a slowdown,
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 // for example, in some objArray manipulations, such as a[i]=a[j].)
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 if (tk->singleton()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 const TypeOopPtr* objtp = _gvn.type(obj)->isa_oopptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 if (objtp != NULL && objtp->klass() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 switch (static_subtype_check(tk->klass(), objtp->klass())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 case SSC_always_true:
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2950 // If we know the type check always succeed then we don't use
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2951 // the profiling data at this bytecode. Don't lose it, feed it
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2952 // to the type system as a speculative type.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
2953 return record_profiled_receiver_for_speculation(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 case SSC_always_false:
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 // It needs a null check because a null will *pass* the cast check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 // A non-null value will always produce an exception.
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
2957 return null_assert(obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2961
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 ciProfileData* data = NULL;
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2963 bool safe_for_replace = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 if (failure_control == NULL) { // use MDO in regular case only
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 assert(java_bc() == Bytecodes::_aastore ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 java_bc() == Bytecodes::_checkcast,
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 "interpreter profiles type checks only for these BCs");
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 data = method()->method_data()->bci_to_data(bci());
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2969 safe_for_replace = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2971
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 // Make the merge point
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 enum { _obj_path = 1, _null_path, PATH_LIMIT };
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2974 RegionNode* region = new (C) RegionNode(PATH_LIMIT);
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
2975 Node* phi = new (C) PhiNode(region, toop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 C->set_has_split_ifs(true); // Has chance for split-if optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
2977
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 // Use null-cast information if it is available
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2979 bool never_see_null = ((failure_control == NULL) // regular case only
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2980 && seems_never_null(obj, data));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2981
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 // Null check; get casted pointer; set region slot 3
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 Node* null_ctl = top();
12869
d9043b88eeb3 8024067: Missing replace_in_map() calls following null checks
roland
parents: 12331
diff changeset
2984 Node* not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2985
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 // If not_null_obj is dead, only null-path is taken
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 if (stopped()) { // Doing instance-of on a NULL?
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 set_control(null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 return null();
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 region->init_req(_null_path, null_ctl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 phi ->init_req(_null_path, null()); // Set null path value
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2993 if (null_ctl == top()) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2994 // Do this eagerly, so that pattern matches like is_diamond_phi
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2995 // will work even during parsing.
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2996 assert(_null_path == PATH_LIMIT-1, "delete last");
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2997 region->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2998 phi ->del_req(_null_path);
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
2999 }
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3000
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3001 Node* cast_obj = NULL;
12966
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3002 const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3003 // We may not have profiling here or it may not help us. If we have
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3004 // a speculative type use it to perform an exact cast.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3005 ciKlass* spec_obj_type = obj_type->speculative_type();
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3006 if (spec_obj_type != NULL ||
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3007 (data != NULL &&
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3008 // Counter has never been decremented (due to cast failure).
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3009 // ...This is a reasonable thing to expect. It is true of
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3010 // all casts inserted by javac to implement generic types.
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3011 data->as_CounterData()->count() >= 0)) {
b2ee5dc63353 8024070: C2 needs some form of type speculation
roland
parents: 12956
diff changeset
3012 cast_obj = maybe_cast_profiled_receiver(not_null_obj, tk->klass(), spec_obj_type, safe_for_replace);
1746
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3013 if (cast_obj != NULL) {
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3014 if (failure_control != NULL) // failure is now impossible
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3015 (*failure_control) = top();
4b29a725c43c 6912064: type profiles need to be exploited more for dynamic language support
jrose
parents: 1609
diff changeset
3016 // adjust the type of the phi to the exact klass:
14383
5ec7dace41a6 8027422: assert(_gvn.type(obj)->higher_equal(tjp)) failed: cast_up is no longer needed
roland
parents: 14223
diff changeset
3017 phi->raise_bottom_type(_gvn.type(cast_obj)->meet_speculative(TypePtr::NULL_PTR));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3020
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 if (cast_obj == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // Load the object's klass
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 Node* obj_klass = load_object_klass(not_null_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3024
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 // Generate the subtype check
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass );
a61af66fc99e Initial load
duke
parents:
diff changeset
3027
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // Plug in success path into the merge
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3029 cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 not_null_obj, toop));
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 // Failure path ends in uncommon trap (or may be dead - failure impossible)
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 if (failure_control == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 if (not_subtype_ctrl != top()) { // If failure is possible
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 PreserveJVMState pjvms(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 set_control(not_subtype_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 builtin_throw(Deoptimization::Reason_class_check, obj_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 (*failure_control) = not_subtype_ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3042
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 region->init_req(_obj_path, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 phi ->init_req(_obj_path, cast_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3045
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 // A merge of NULL or Casted-NotNull obj
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 Node* res = _gvn.transform(phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
3048
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 // Note I do NOT always 'replace_in_map(obj,result)' here.
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 // if( tk->klass()->can_be_primary_super() )
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 // This means that if I successfully store an Object into an array-of-String
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 // I 'forget' that the Object is really now known to be a String. I have to
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 // do this because we don't have true union types for interfaces - if I store
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 // a Baz into an array-of-Interface and then tell the optimizer it's an
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 // Interface, I forget that it's also a Baz and cannot do Baz-like field
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 // references to it. FIX THIS WHEN UNION TYPES APPEAR!
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 // replace_in_map( obj, res );
a61af66fc99e Initial load
duke
parents:
diff changeset
3058
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 // Return final merged results
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 set_control( _gvn.transform(region) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 record_for_igvn(region);
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3064
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 //------------------------------next_monitor-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 // What number should be given to the next monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 int GraphKit::next_monitor() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 int current = jvms()->monitor_depth()* C->sync_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 int next = current + C->sync_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // Keep the toplevel high water mark current:
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 if (C->fixed_slots() < next) C->set_fixed_slots(next);
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 return current;
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3074
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 //------------------------------insert_mem_bar---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 // Memory barrier to avoid floating things around
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 // The membar serves as a pinch point between both control and all memory slices.
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 Node* GraphKit::insert_mem_bar(int opcode, Node* precedent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 MemBarNode* mb = MemBarNode::make(C, opcode, Compile::AliasIdxBot, precedent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 mb->init_req(TypeFunc::Control, control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 mb->init_req(TypeFunc::Memory, reset_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 Node* membar = _gvn.transform(mb);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
3083 set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 set_all_memory_call(membar);
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 return membar;
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3087
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 //-------------------------insert_mem_bar_volatile----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 // Memory barrier to avoid floating things around
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // The membar serves as a pinch point between both control and memory(alias_idx).
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // If you want to make a pinch point on all memory slices, do not use this
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 // function (even with AliasIdxBot); use insert_mem_bar() instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 Node* GraphKit::insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // When Parse::do_put_xxx updates a volatile field, it appends a series
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 // of MemBarVolatile nodes, one for *each* volatile field alias category.
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 // The first membar is on the same memory slice as the field store opcode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 // This forces the membar to follow the store. (Bug 6500685 broke this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 // All the other membars (for other volatile slices, including AliasIdxBot,
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // which stands for all unknown volatile slices) are control-dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // on the first membar. This prevents later volatile loads or stores
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 // from sliding up past the just-emitted store.
a61af66fc99e Initial load
duke
parents:
diff changeset
3102
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 MemBarNode* mb = MemBarNode::make(C, opcode, alias_idx, precedent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 mb->set_req(TypeFunc::Control,control());
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 if (alias_idx == Compile::AliasIdxBot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 mb->set_req(TypeFunc::Memory, merged_memory()->base_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 assert(!(opcode == Op_Initialize && alias_idx != Compile::AliasIdxRaw), "fix caller");
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 mb->set_req(TypeFunc::Memory, memory(alias_idx));
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 Node* membar = _gvn.transform(mb);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3112 set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 if (alias_idx == Compile::AliasIdxBot) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3114 merged_memory()->set_base_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 } else {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3116 set_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)),alias_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 return membar;
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3120
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 //------------------------------shared_lock------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 // Emit locking code.
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 FastLockNode* GraphKit::shared_lock(Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 // bci is either a monitorenter bc or InvocationEntryBci
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 assert(SynchronizationEntryBCI == InvocationEntryBci, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 if( !GenerateSynchronizationCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 return NULL; // Not locking things?
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 if (stopped()) // Dead monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3132
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 assert(dead_locals_are_killed(), "should kill locals before sync. point");
a61af66fc99e Initial load
duke
parents:
diff changeset
3134
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 // Box the stack location
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3136 Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 Node* mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3138
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3139 FastLockNode * flock = _gvn.transform(new (C) FastLockNode(0, obj, box) )->as_FastLock();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 if (PrintPreciseBiasedLockingStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 // Create the counters for this fast lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 // Add monitor to debug info for the slow path. If we block inside the
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 // slow path and de-opt, we need the monitor hanging around
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 map()->push_monitor( flock );
a61af66fc99e Initial load
duke
parents:
diff changeset
3147
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 const TypeFunc *tf = LockNode::lock_type();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3149 LockNode *lock = new (C) LockNode(C, tf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3150
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 lock->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 lock->init_req( TypeFunc::Memory , mem );
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 lock->init_req( TypeFunc::I_O , top() ) ; // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 lock->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 lock->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3156
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 lock->init_req(TypeFunc::Parms + 0, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 lock->init_req(TypeFunc::Parms + 1, box);
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 lock->init_req(TypeFunc::Parms + 2, flock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 add_safepoint_edges(lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3161
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 lock = _gvn.transform( lock )->as_Lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
3163
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 // lock has no side-effects, sets few values
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 set_predefined_output_for_runtime_call(lock, mem, TypeRawPtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
3166
3849
f1c12354c3f7 7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents: 3345
diff changeset
3167 insert_mem_bar(Op_MemBarAcquireLock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3168
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 // Add this to the worklist so that the lock can be eliminated
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 record_for_igvn(lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3171
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 if (PrintLockStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 // Update the counter for this lock. Don't bother using an atomic
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 // operation since we don't require absolute accuracy.
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 lock->create_lock_counter(map()->jvms());
1609
4311f23817fd 6959430: Make sure raw loads have control edge
kvn
parents: 1594
diff changeset
3177 increment_counter(lock->counter()->addr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3180
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 return flock;
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3183
a61af66fc99e Initial load
duke
parents:
diff changeset
3184
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 //------------------------------shared_unlock----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 // Emit unlocking code.
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 void GraphKit::shared_unlock(Node* box, Node* obj) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 // bci is either a monitorenter bc or InvocationEntryBci
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 assert(SynchronizationEntryBCI == InvocationEntryBci, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3191
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 if( !GenerateSynchronizationCode )
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 if (stopped()) { // Dead monitor?
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 map()->pop_monitor(); // Kill monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3198
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // Memory barrier to avoid floating things down past the locked region
3849
f1c12354c3f7 7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents: 3345
diff changeset
3200 insert_mem_bar(Op_MemBarReleaseLock);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3201
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3203 UnlockNode *unlock = new (C) UnlockNode(C, tf);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 uint raw_idx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 unlock->init_req( TypeFunc::Control, control() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 unlock->init_req( TypeFunc::Memory , memory(raw_idx) );
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 unlock->init_req( TypeFunc::I_O , top() ) ; // does no i/o
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 unlock->init_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 unlock->init_req( TypeFunc::ReturnAdr, top() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3210
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 unlock->init_req(TypeFunc::Parms + 0, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 unlock->init_req(TypeFunc::Parms + 1, box);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 unlock = _gvn.transform(unlock)->as_Unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
3214
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 Node* mem = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
3216
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 // unlock has no side-effects, sets few values
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 set_predefined_output_for_runtime_call(unlock, mem, TypeRawPtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
3219
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 // Kill monitor from debug info
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 map()->pop_monitor( );
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3223
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 //-------------------------------get_layout_helper-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 // If the given klass is a constant or known to be an array,
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 // fetch the constant layout helper value into constant_value
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 // and return (Node*)NULL. Otherwise, load the non-constant
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 // layout helper value, and return the node which represents it.
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 // This two-faced routine is useful because allocation sites
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 // almost always feature constant types.
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 if (!StressReflectiveCode && inst_klass != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 ciKlass* klass = inst_klass->klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 bool xklass = inst_klass->klass_is_exact();
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 if (xklass || klass->is_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 jint lhelper = klass->layout_helper();
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 if (lhelper != Klass::_lh_neutral_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 constant_value = lhelper;
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 return (Node*) NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 constant_value = Klass::_lh_neutral_value; // put in a known value
4762
069ab3f976d3 7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents: 3849
diff changeset
3245 Node* lhp = basic_plus_adr(klass_node, klass_node, in_bytes(Klass::layout_helper_offset()));
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3246 return make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3248
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 // We just put in an allocate/initialize with a big raw-memory effect.
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 // Hook selected additional alias categories on the initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 MergeMemNode* init_in_merge,
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 Node* init_out_raw) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 assert(init_in_merge->memory_at(alias_idx) == init_in_raw, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3256
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 Node* prevmem = kit.memory(alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 init_in_merge->set_memory_at(alias_idx, prevmem);
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 kit.set_memory(init_out_raw, alias_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3261
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 //---------------------------set_output_for_allocation-------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3264 const TypeOopPtr* oop_type) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 int rawidx = Compile::AliasIdxRaw;
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 alloc->set_req( TypeFunc::FramePtr, frameptr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 add_safepoint_edges(alloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 Node* allocx = _gvn.transform(alloc);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3269 set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 // create memory projection for i_o
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3271 set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx );
7428
2d6c433b1f38 8004741: Missing compiled exception handle table entry for multidimensional array allocation
kvn
parents: 7421
diff changeset
3272 make_slow_call_ex(allocx, env()->Throwable_klass(), true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3273
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 // create a memory projection as for the normal control path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3275 Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 set_memory(malloc, rawidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3277
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 // a normal slow-call doesn't change i_o, but an allocation does
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 // we create a separate i_o projection for the normal control path
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3280 set_i_o(_gvn.transform( new (C) ProjNode(allocx, TypeFunc::I_O, false) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3281 Node* rawoop = _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Parms) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3282
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 // put in an initialization barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx,
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 rawoop)->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 assert(alloc->initialization() == init, "2-way macro link must work");
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 assert(init ->allocation() == alloc, "2-way macro link must work");
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3288 {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 // Extract memory strands which may participate in the new object's
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 // initialization, and source them from the new InitializeNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 // This will allow us to observe initializations when they occur,
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 // and link them properly (as a group) to the InitializeNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 assert(init->in(InitializeNode::Memory) == malloc, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 MergeMemNode* minit_in = MergeMemNode::make(C, malloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 init->set_req(InitializeNode::Memory, minit_in);
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 record_for_igvn(minit_in); // fold it up later, if possible
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 Node* minit_out = memory(rawidx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 assert(minit_out->is_Proj() && minit_out->in(0) == init, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 if (oop_type->isa_aryptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot);
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 int elemidx = C->get_alias_index(telemref);
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 hook_memory_on_init(*this, elemidx, minit_in, minit_out);
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 } else if (oop_type->isa_instptr()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 ciInstanceKlass* ik = oop_type->klass()->as_instance_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 ciField* field = ik->nonstatic_field_at(i);
23
9bdad1bb1c31 6621098: "* HeapWordSize" for TrackedInitializationLimit is missing
kvn
parents: 0
diff changeset
3307 if (field->offset() >= TrackedInitializationLimit * HeapWordSize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 continue; // do not bother to track really large numbers of fields
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 // Find (or create) the alias category for this field:
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 int fieldidx = C->alias_type(field)->index();
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 hook_memory_on_init(*this, fieldidx, minit_in, minit_out);
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3315
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 // Cast raw oop to the real thing...
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3317 Node* javaoop = new (C) CheckCastPPNode(control(), rawoop, oop_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 javaoop = _gvn.transform(javaoop);
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 C->set_recent_alloc(control(), javaoop);
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 assert(just_allocated_object(control()) == javaoop, "just allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
3321
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 #ifdef ASSERT
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3323 { // Verify that the AllocateNode::Ideal_allocation recognizers work:
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3324 assert(AllocateNode::Ideal_allocation(rawoop, &_gvn) == alloc,
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3325 "Ideal_allocation works");
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3326 assert(AllocateNode::Ideal_allocation(javaoop, &_gvn) == alloc,
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3327 "Ideal_allocation works");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 if (alloc->is_AllocateArray()) {
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3329 assert(AllocateArrayNode::Ideal_array_allocation(rawoop, &_gvn) == alloc->as_AllocateArray(),
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3330 "Ideal_allocation works");
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3331 assert(AllocateArrayNode::Ideal_array_allocation(javaoop, &_gvn) == alloc->as_AllocateArray(),
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3332 "Ideal_allocation works");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 } else {
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3334 assert(alloc->in(AllocateNode::ALength)->is_top(), "no length, please");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3338
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 return javaoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3341
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 //---------------------------new_instance--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 // This routine takes a klass_node which may be constant (for a static type)
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 // or may be non-constant (for reflective code). It will work equally well
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 // for either, and the graph will fold nicely if the optimizer later reduces
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 // the type to a constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 // The optional arguments are for specialized use by intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 // - If 'extra_slow_test' if not null is an extra condition for the slow-path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 // - If 'return_size_val', report the the total object size to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 Node* GraphKit::new_instance(Node* klass_node,
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 Node* extra_slow_test,
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 Node* *return_size_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 // Compute size in doublewords
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 // The size is always an integral number of doublewords, represented
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 // as a positive bytewise size stored in the klass's layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 // The layout_helper also encodes (in a low bit) the need for a slow path.
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 jint layout_con = Klass::_lh_neutral_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 Node* layout_val = get_layout_helper(klass_node, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 int layout_is_con = (layout_val == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3360
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 if (extra_slow_test == NULL) extra_slow_test = intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 // Generate the initial go-slow test. It's either ALWAYS (return a
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 // Node for 1) or NEVER (return a NULL) or perhaps (in the reflective
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 // case) a computed value derived from the layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 Node* initial_slow_test = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 assert(!StressReflectiveCode, "stress mode does not use these paths");
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 bool must_go_slow = Klass::layout_helper_needs_slow_path(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 initial_slow_test = must_go_slow? intcon(1): extra_slow_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
3370
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 } else { // reflective case
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 // This reflective path is used by Unsafe.allocateInstance.
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 // (It may be stress-tested by specifying StressReflectiveCode.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 // Basically, we want to get into the VM is there's an illegal argument.
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 Node* bit = intcon(Klass::_lh_instance_slow_path_bit);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3376 initial_slow_test = _gvn.transform( new (C) AndINode(layout_val, bit) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 if (extra_slow_test != intcon(0)) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3378 initial_slow_test = _gvn.transform( new (C) OrINode(initial_slow_test, extra_slow_test) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 // (Macro-expander will further convert this to a Bool, if necessary.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3382
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 // Find the size in bytes. This is easy; it's the layout_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 // The size value must be valid even if the slow path is taken.
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 Node* size = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 size = MakeConX(Klass::layout_helper_size_in_bytes(layout_con));
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 } else { // reflective case
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 // This reflective path is used by clone and Unsafe.allocateInstance.
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 size = ConvI2X(layout_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
3391
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 // Clear the low bits to extract layout_helper_size_in_bytes:
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit");
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3395 size = _gvn.transform( new (C) AndXNode(size, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 if (return_size_val != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 (*return_size_val) = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3400
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 // This is a precise notnull oop of the klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 // (Actually, it need not be precise if this is a reflective allocation.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 // It's what we cast the result to.
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 const TypeKlassPtr* tklass = _gvn.type(klass_node)->isa_klassptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 if (!tklass) tklass = TypeKlassPtr::OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 const TypeOopPtr* oop_type = tklass->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3407
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 // Now generate allocation code
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3409
565
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3410 // The entire memory state is needed for slow path of the allocation
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3411 // since GC and deoptimization can happened.
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3412 Node *mem = reset_memory();
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3413 set_all_memory(mem); // Create new memory state
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3414
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 AllocateNode* alloc
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
3416 = new (C) AllocateNode(C, AllocateNode::alloc_type(Type::TOP),
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3417 control(), mem, i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3418 size, klass_node,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3419 initial_slow_test);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3420
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3421 return set_output_for_allocation(alloc, oop_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3423
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 //-------------------------------new_array-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 // helper for both newarray and anewarray
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 // The 'length' parameter is (obviously) the length of the array.
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 // See comments on new_instance for the meaning of the other arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable)
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 Node* length, // number of array elements
730
9c6be3edf0dc 6589834: deoptimization problem with -XX:+DeoptimizeALot
cfang
parents: 726
diff changeset
3430 int nargs, // number of arguments to push back for uncommon trap
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 Node* *return_size_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 jint layout_con = Klass::_lh_neutral_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 Node* layout_val = get_layout_helper(klass_node, layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 int layout_is_con = (layout_val == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3435
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 if (!layout_is_con && !StressReflectiveCode &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 !too_many_traps(Deoptimization::Reason_class_check)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 // This is a reflective array creation site.
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 // Optimistically assume that it is a subtype of Object[],
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 // so that we can fold up all the address arithmetic.
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 layout_con = Klass::array_layout_helper(T_OBJECT);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3442 Node* cmp_lh = _gvn.transform( new(C) CmpINode(layout_val, intcon(layout_con)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3443 Node* bol_lh = _gvn.transform( new(C) BoolNode(cmp_lh, BoolTest::eq) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 { BuildCutout unless(this, bol_lh, PROB_MAX);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
3445 inc_sp(nargs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 uncommon_trap(Deoptimization::Reason_class_check,
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 Deoptimization::Action_maybe_recompile);
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 layout_val = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 layout_is_con = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3452
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 // Generate the initial go-slow test. Make sure we do not overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 // if length is huge (near 2Gig) or negative! We do not need
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 // exact double-words here, just a close approximation of needed
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 // double-words. We can't add any offset or rounding bits, lest we
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 // take a size -1 of bytes and make it positive. Use an unsigned
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 // compare, so negative sizes look hugely positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 int fast_size_limit = FastAllocateSizeLimit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 assert(!StressReflectiveCode, "stress mode does not use these paths");
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 // Increase the size limit if we have exact knowledge of array type.
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 int log2_esize = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 fast_size_limit <<= (LogBytesPerLong - log2_esize);
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3466
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3467 Node* initial_slow_cmp = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3468 Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 if (initial_slow_test->is_Bool()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3473
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 // --- Size Computation ---
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 // array_size = round_to_heap(array_header + (length << elem_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 // where round_to_heap(x) == round_to(x, MinObjAlignmentInBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 // and round_to(x, y) == ((x + y-1) & ~(y-1))
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 // The rounding mask is strength-reduced, if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 int round_mask = MinObjAlignmentInBytes - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 Node* header_size = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 // (T_BYTE has the weakest alignment and size restrictions...)
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 int hsize = Klass::layout_helper_header_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 int eshift = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 BasicType etype = Klass::layout_helper_element_type(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 if ((round_mask & ~right_n_bits(eshift)) == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 round_mask = 0; // strength-reduce it if it goes away completely
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded");
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 assert(header_size_min <= hsize, "generic minimum is smallest");
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 header_size_min = hsize;
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 header_size = intcon(hsize + round_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 Node* hss = intcon(Klass::_lh_header_size_shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 Node* hsm = intcon(Klass::_lh_header_size_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3496 Node* hsize = _gvn.transform( new(C) URShiftINode(layout_val, hss) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3497 hsize = _gvn.transform( new(C) AndINode(hsize, hsm) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 Node* mask = intcon(round_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3499 header_size = _gvn.transform( new(C) AddINode(hsize, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3501
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 Node* elem_shift = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 if (layout_is_con) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 int eshift = Klass::layout_helper_log2_element_size(layout_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 if (eshift != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 elem_shift = intcon(eshift);
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 // There is no need to mask or shift this value.
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 // The semantics of LShiftINode include an implicit mask to 0x1F.
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 assert(Klass::_lh_log2_element_size_shift == 0, "use shift in place");
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 elem_shift = layout_val;
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3513
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 // Transition to native address size for all offset calculations:
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 Node* lengthx = ConvI2X(length);
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 Node* headerx = ConvI2X(header_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 { const TypeLong* tllen = _gvn.find_long_type(lengthx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 if (tllen != NULL && tllen->_lo < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 // Add a manual constraint to a positive range. Cf. array_element_address.
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 jlong size_max = arrayOopDesc::max_array_length(T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 if (size_max > tllen->_hi) size_max = tllen->_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3524 lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3528
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // Combine header size (plus rounding) and body size. Then round down.
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 // This computation cannot overflow, because it is used only in two
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 // places, one where the length is sharply limited, and the other
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 // after a successful allocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 Node* abody = lengthx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 if (elem_shift != NULL)
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3535 abody = _gvn.transform( new(C) LShiftXNode(lengthx, elem_shift) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3536 Node* size = _gvn.transform( new(C) AddXNode(headerx, abody) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 if (round_mask != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 Node* mask = MakeConX(~round_mask);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3539 size = _gvn.transform( new(C) AndXNode(size, mask) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 // else if round_mask == 0, the size computation is self-rounding
a61af66fc99e Initial load
duke
parents:
diff changeset
3542
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 if (return_size_val != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // This is the size
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 (*return_size_val) = size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3547
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 // Now generate allocation code
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3549
565
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3550 // The entire memory state is needed for slow path of the allocation
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3551 // since GC and deoptimization can happened.
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3552 Node *mem = reset_memory();
7fe62bb75bf4 6799693: Server compiler leads to data corruption when expression throws an Exception
kvn
parents: 563
diff changeset
3553 set_all_memory(mem); // Create new memory state
74
2a9af0b9cb1c 6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents: 63
diff changeset
3554
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 // Create the AllocateArrayNode and its result projections
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 AllocateArrayNode* alloc
10278
6f3fd5150b67 6934604: enable parts of EliminateAutoBox by default
kvn
parents: 10185
diff changeset
3557 = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT),
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3558 control(), mem, i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3559 size, klass_node,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3560 initial_slow_test,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3561 length);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3562
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 // Cast to correct type. Note that the klass_node may be constant or not,
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 // and in the latter case the actual array type will be inexact also.
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 // (This happens via a non-constant argument to inline_native_newArray.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 // In any case, the value of klass_node provides the desired array type.
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 const TypeInt* length_type = _gvn.find_int_type(length);
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 if (ary_type->isa_aryptr() && length_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 // Try to get a better type than POS for the size
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 ary_type = ary_type->is_aryptr()->cast_to_size(length_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3573
3278
66b0e2371912 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents: 2468
diff changeset
3574 Node* javaoop = set_output_for_allocation(alloc, ary_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3575
366
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3576 // Cast length on remaining path to be as narrow as possible
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3577 if (map()->find_edge(length) >= 0) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3578 Node* ccast = alloc->make_ideal_length(ary_type, &_gvn);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3579 if (ccast != length) {
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3580 _gvn.set_type_bottom(ccast);
8261ee795323 6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents: 332
diff changeset
3581 record_for_igvn(ccast);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 replace_in_map(length, ccast);
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3585
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 return javaoop;
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3588
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 // The following "Ideal_foo" functions are placed here because they recognize
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 // the graph shapes created by the functions immediately above.
a61af66fc99e Initial load
duke
parents:
diff changeset
3591
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 //---------------------------Ideal_allocation----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 // Given an oop pointer or raw pointer, see if it feeds from an AllocateNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 if (ptr == NULL) { // reduce dumb test in callers
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 }
11078
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3598 if (ptr->is_CheckCastPP()) { // strip only one raw-to-oop cast
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3599 ptr = ptr->in(1);
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3600 if (ptr == NULL) return NULL;
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3601 }
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3602 // Return NULL for allocations with several casts:
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3603 // j.l.reflect.Array.newInstance(jobject, jint)
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3604 // Object.clone()
2b3fe74309b6 8019247: SIGSEGV in compiled method c8e.e.t_.getArray(Ljava/lang/Class;)[Ljava/lang/Object
kvn
parents: 10278
diff changeset
3605 // to keep more precise type from last cast.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 if (ptr->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 Node* allo = ptr->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 if (allo != NULL && allo->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 return allo->as_Allocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 // Report failure to match.
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3615
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 // Fancy version which also strips off an offset (and reports it to caller).
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 AllocateNode* AllocateNode::Ideal_allocation(Node* ptr, PhaseTransform* phase,
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 intptr_t& offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 Node* base = AddPNode::Ideal_base_and_offset(ptr, phase, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 if (base == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 return Ideal_allocation(base, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3623
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 // Trace Initialize <- Proj[Parm] <- Allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 AllocateNode* InitializeNode::allocation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 Node* rawoop = in(InitializeNode::RawAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 if (rawoop->is_Proj()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 Node* alloc = rawoop->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 if (alloc->is_Allocate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 return alloc->as_Allocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3635
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 // Trace Allocate -> Proj[Parm] -> Initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 InitializeNode* AllocateNode::initialization() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 ProjNode* rawoop = proj_out(AllocateNode::RawAddress);
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 if (rawoop == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 Node* init = rawoop->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 if (init->is_Initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 assert(init->as_Initialize()->allocation() == this, "2-way link");
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 return init->as_Initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3649
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3650 //----------------------------- loop predicates ---------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3651
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3652 //------------------------------add_predicate_impl----------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3653 void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3654 // Too many traps seen?
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3655 if (too_many_traps(reason)) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3656 #ifdef ASSERT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3657 if (TraceLoopPredicate) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3658 int tc = C->trap_count(reason);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3659 tty->print("too many traps=%s tcount=%d in ",
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3660 Deoptimization::trap_reason_name(reason), tc);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3661 method()->print(); // which method has too many predicate traps
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3662 tty->cr();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3663 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3664 #endif
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3665 // We cannot afford to take more traps here,
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3666 // do not generate predicate.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3667 return;
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3668 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3669
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3670 Node *cont = _gvn.intcon(1);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3671 Node* opq = _gvn.transform(new (C) Opaque1Node(C, cont));
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3672 Node *bol = _gvn.transform(new (C) Conv2BNode(opq));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3673 IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3674 Node* iffalse = _gvn.transform(new (C) IfFalseNode(iff));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3675 C->add_predicate_opaq(opq);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3676 {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3677 PreserveJVMState pjvms(this);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3678 set_control(iffalse);
7194
beebba0acc11 7172640: C2: instrinsic implementations in LibraryCallKit should use argument() instead of pop()
twisti
parents: 6846
diff changeset
3679 inc_sp(nargs);
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3680 uncommon_trap(reason, Deoptimization::Action_maybe_recompile);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3681 }
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6725
diff changeset
3682 Node* iftrue = _gvn.transform(new (C) IfTrueNode(iff));
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3683 set_control(iftrue);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3684 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3685
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3686 //------------------------------add_predicate---------------------------------
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3687 void GraphKit::add_predicate(int nargs) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3688 if (UseLoopPredicate) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3689 add_predicate_impl(Deoptimization::Reason_predicate, nargs);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3690 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3691 // loop's limit check predicate should be near the loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3692 if (LoopLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3693 add_predicate_impl(Deoptimization::Reason_loop_limit_check, nargs);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3284
diff changeset
3694 }
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3695 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 2007
diff changeset
3696
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3697 //----------------------------- store barriers ----------------------------
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3698 #define __ ideal.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3699
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3700 void GraphKit::sync_kit(IdealKit& ideal) {
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3701 set_all_memory(__ merged_memory());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3702 set_i_o(__ i_o());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3703 set_control(__ ctrl());
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3704 }
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3705
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3706 void GraphKit::final_sync(IdealKit& ideal) {
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3707 // Final sync IdealKit and graphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3708 sync_kit(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3709 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3710
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3711 // vanilla/CMS post barrier
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3712 // Insert a write-barrier store. This is to let generational GC work; we have
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3713 // to flag all oop-stores before the next GC point.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3714 void GraphKit::write_barrier_post(Node* oop_store,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3715 Node* obj,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3716 Node* adr,
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3717 uint adr_idx,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3718 Node* val,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3719 bool use_precise) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3720 // No store check needed if we're storing a NULL or an old object
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3721 // (latter case is probably a string constant). The concurrent
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3722 // mark sweep garbage collector, however, needs to have all nonNull
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3723 // oop updates flagged via card-marks.
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3724 if (val != NULL && val->is_Con()) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3725 // must be either an oop or NULL
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3726 const Type* t = val->bottom_type();
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3727 if (t == TypePtr::NULL_PTR || t == Type::TOP)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3728 // stores of null never (?) need barriers
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3729 return;
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3730 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3731
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3732 if (use_ReduceInitialCardMarks()
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3733 && obj == just_allocated_object(control())) {
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3734 // We can skip marks on a freshly-allocated object in Eden.
1166
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3735 // Keep this code in sync with new_store_pre_barrier() in runtime.cpp.
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3736 // That routine informs GC to take appropriate compensating steps,
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3737 // upon a slow-path allocation, so as to make this card-mark
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1137
diff changeset
3738 // elision safe.
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3739 return;
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3740 }
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 985
diff changeset
3741
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3742 if (!use_precise) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3743 // All card marks for a (non-array) instance are in one place:
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3744 adr = obj;
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3745 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3746 // (Else it's an array (or unknown), and we want more precise card marks.)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3747 assert(adr != NULL, "");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3748
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3749 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3750
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3751 // Convert the pointer to an int prior to doing math on it
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3752 Node* cast = __ CastPX(__ ctrl(), adr);
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3753
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3754 // Divide by card size
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3755 assert(Universe::heap()->barrier_set()->kind() == BarrierSet::CardTableModRef,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3756 "Only one we handle so far.");
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3757 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3758
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3759 // Combine card table base and card offset
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3760 Node* card_adr = __ AddP(__ top(), byte_map_base_node(), card_offset );
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3761
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3762 // Get the alias_index for raw card-mark memory
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3763 int adr_type = Compile::AliasIdxRaw;
3282
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3764 Node* zero = __ ConI(0); // Dirty card value
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3765 BasicType bt = T_BYTE;
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3766
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3767 if (UseCondCardMark) {
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3768 // The classic GC reference write barrier is typically implemented
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3769 // as a store into the global card mark table. Unfortunately
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3770 // unconditional stores can result in false sharing and excessive
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3771 // coherence traffic as well as false transactional aborts.
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3772 // UseCondCardMark enables MP "polite" conditional card mark
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3773 // stores. In theory we could relax the load from ctrl() to
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3774 // no_ctrl, but that doesn't buy much latitude.
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3775 Node* card_val = __ load( __ ctrl(), card_adr, TypeInt::BYTE, bt, adr_type);
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3776 __ if_then(card_val, BoolTest::ne, zero);
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3777 }
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3778
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3779 // Smash zero into card
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3780 if( !UseConcMarkSweepGC ) {
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3781 __ store(__ ctrl(), card_adr, zero, bt, adr_type, MemNode::release);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3782 } else {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3783 // Specialized path for CM store barrier
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3784 __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3785 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3786
3282
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3787 if (UseCondCardMark) {
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3788 __ end_if();
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3789 }
149bb459be66 7029167: add support for conditional card marks
never
parents: 3280
diff changeset
3790
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3791 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3792 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3793 }
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3794
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3795 // G1 pre/post barriers
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3796 void GraphKit::g1_write_barrier_pre(bool do_load,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3797 Node* obj,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3798 Node* adr,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3799 uint alias_idx,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3800 Node* val,
825
8f5825e0aeaa 6818666: G1: Type lost in g1 pre-barrier
never
parents: 780
diff changeset
3801 const TypeOopPtr* val_type,
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3802 Node* pre_val,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3803 BasicType bt) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3804
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3805 // Some sanity checks
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3806 // Note: val is unused in this routine.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3807
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3808 if (do_load) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3809 // We need to generate the load of the previous value
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3810 assert(obj != NULL, "must have a base");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3811 assert(adr != NULL, "where are loading from?");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3812 assert(pre_val == NULL, "loaded already?");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3813 assert(val_type != NULL, "need a type");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3814 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3815 // In this case both val_type and alias_idx are unused.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3816 assert(pre_val != NULL, "must be loaded already");
12169
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
3817 // Nothing to be done if pre_val is null.
29aa8936f03c 8023597: Optimize G1 barriers code for unsafe load_store
kvn
parents: 12159
diff changeset
3818 if (pre_val->bottom_type() == TypePtr::NULL_PTR) return;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3819 assert(pre_val->bottom_type()->basic_type() == T_OBJECT, "or we shouldn't be here");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3820 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3821 assert(bt == T_OBJECT, "or we shouldn't be here");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3822
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3823 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3824
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3825 Node* tls = __ thread(); // ThreadLocalStorage
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3826
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3827 Node* no_ctrl = NULL;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3828 Node* no_base = __ top();
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3829 Node* zero = __ ConI(0);
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3830 Node* zeroX = __ ConX(0);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3831
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3832 float likely = PROB_LIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3833 float unlikely = PROB_UNLIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3834
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3835 BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3836 assert(in_bytes(PtrQueue::byte_width_of_active()) == 4 || in_bytes(PtrQueue::byte_width_of_active()) == 1, "flag width");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3837
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3838 // Offsets into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3839 const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 648
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3840 PtrQueue::byte_offset_of_active());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3841 const int index_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 656
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3842 PtrQueue::byte_offset_of_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3843 const int buffer_offset = in_bytes(JavaThread::satb_mark_queue_offset() + // 652
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3844 PtrQueue::byte_offset_of_buf());
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3845
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3846 // Now the actual pointers into the thread
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3847 Node* marking_adr = __ AddP(no_base, tls, __ ConX(marking_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3848 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3849 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3850
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3851 // Now some of the values
544
82a980778b92 6793828: G1: invariant: queues are empty when activated
never
parents: 372
diff changeset
3852 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3853
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3854 // if (!marking)
12886
f91a9a696e5e 8026293: Schedule part of G1 pre-barrier late
kvn
parents: 12883
diff changeset
3855 __ if_then(marking, BoolTest::ne, zero, unlikely); {
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3856 BasicType index_bt = TypeX_X->basic_type();
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3857 assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3858 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3859
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3860 if (do_load) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3861 // load original value
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3862 // alias_idx correct??
12159
b17d8f6d9ed7 8023472: C2 optimization breaks with G1
kvn
parents: 11078
diff changeset
3863 pre_val = __ load(__ ctrl(), adr, val_type, bt, alias_idx);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3864 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3865
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3866 // if (pre_val != NULL)
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3867 __ if_then(pre_val, BoolTest::ne, null()); {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3868 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3869
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3870 // is the queue for this thread full?
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3871 __ if_then(index, BoolTest::ne, zeroX, likely); {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3872
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3873 // decrement the index
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3874 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3875
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3876 // Now get the buffer location we will log the previous value into and store it
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3877 Node *log_addr = __ AddP(no_base, buffer, next_index);
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3878 __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw, MemNode::unordered);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3879 // update the index
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3880 __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw, MemNode::unordered);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3881
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3882 } __ else_(); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3883
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3884 // logging buffer is full, call the runtime
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3885 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3886 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), "g1_wb_pre", pre_val, tls);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3887 } __ end_if(); // (!index)
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2383
diff changeset
3888 } __ end_if(); // (pre_val != NULL)
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3889 } __ end_if(); // (!marking)
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3890
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3891 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3892 final_sync(ideal);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3893 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3894
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3895 //
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3896 // Update the card table and add card address to the queue
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3897 //
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3898 void GraphKit::g1_mark_card(IdealKit& ideal,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3899 Node* card_adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3900 Node* oop_store,
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3901 uint oop_alias_idx,
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3902 Node* index,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3903 Node* index_adr,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3904 Node* buffer,
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3905 const TypeFunc* tf) {
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3906
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3907 Node* zero = __ ConI(0);
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3908 Node* zeroX = __ ConX(0);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3909 Node* no_base = __ top();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3910 BasicType card_bt = T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3911 // Smash zero into card. MUST BE ORDERED WRT TO STORE
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
3912 __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3913
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3914 // Now do the queue work
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3915 __ if_then(index, BoolTest::ne, zeroX); {
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3916
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3917 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3918 Node* log_addr = __ AddP(no_base, buffer, next_index);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3919
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3920 // Order, see storeCM.
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3921 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
3922 __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw, MemNode::unordered);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3923
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3924 } __ else_(); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3925 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3926 } __ end_if();
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3927
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3928 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3929
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3930 void GraphKit::g1_write_barrier_post(Node* oop_store,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3931 Node* obj,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3932 Node* adr,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3933 uint alias_idx,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3934 Node* val,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3935 BasicType bt,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3936 bool use_precise) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3937 // If we are writing a NULL then we need no post barrier
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3938
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3939 if (val != NULL && val->is_Con() && val->bottom_type() == TypePtr::NULL_PTR) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3940 // Must be NULL
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3941 const Type* t = val->bottom_type();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3942 assert(t == Type::TOP || t == TypePtr::NULL_PTR, "must be NULL");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3943 // No post barrier if writing NULLx
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3944 return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3945 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3946
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3947 if (!use_precise) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3948 // All card marks for a (non-array) instance are in one place:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3949 adr = obj;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3950 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3951 // (Else it's an array (or unknown), and we want more precise card marks.)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3952 assert(adr != NULL, "");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3953
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
3954 IdealKit ideal(this, true);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3955
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3956 Node* tls = __ thread(); // ThreadLocalStorage
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3957
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3958 Node* no_base = __ top();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3959 float likely = PROB_LIKELY(0.999);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3960 float unlikely = PROB_UNLIKELY(0.999);
12835
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
3961 Node* young_card = __ ConI((jint)G1SATBCardTableModRefBS::g1_young_card_val());
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
3962 Node* dirty_card = __ ConI((jint)CardTableModRefBS::dirty_card_val());
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3963 Node* zeroX = __ ConX(0);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3964
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3965 // Get the alias_index for raw card-mark memory
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3966 const TypePtr* card_type = TypeRawPtr::BOTTOM;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3967
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3968 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3969
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3970 // Offsets into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3971 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3972 PtrQueue::byte_offset_of_index());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3973 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3974 PtrQueue::byte_offset_of_buf());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3975
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3976 // Pointers into the thread
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3977
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3978 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3979 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3980
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3981 // Now some values
1593
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3982 // Use ctrl to avoid hoisting these values past a safepoint, which could
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3983 // potentially reset these fields in the JavaThread.
10185
d50cc62e94ff 8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
johnc
parents: 8868
diff changeset
3984 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, TypeX_X->basic_type(), Compile::AliasIdxRaw);
1593
2458a1f25356 6953058: G1: A bigapp crashes with SIGSEGV in compiled code
johnc
parents: 1397
diff changeset
3985 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3986
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3987 // Convert the store obj pointer to an int prior to doing math on it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3988 // Must use ctrl to prevent "integerized oop" existing across safepoint
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3989 Node* cast = __ CastPX(__ ctrl(), adr);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3990
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3991 // Divide pointer by card size
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3992 Node* card_offset = __ URShiftX( cast, __ ConI(CardTableModRefBS::card_shift) );
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3993
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3994 // Combine card table base and card offset
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
3995 Node* card_adr = __ AddP(no_base, byte_map_base_node(), card_offset );
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3996
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3997 // If we know the value being stored does it cross regions?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3998
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
3999 if (val != NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4000 // Does the store cause us to cross regions?
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4001
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4002 // Should be able to do an unsigned compare of region_size instead of
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4003 // and extra shift. Do we have an unsigned compare??
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4004 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4005 Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4006
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4007 // if (xor_res == 0) same region so skip
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4008 __ if_then(xor_res, BoolTest::ne, zeroX); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4009
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4010 // No barrier if we are storing a NULL
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4011 __ if_then(val, BoolTest::ne, null(), unlikely); {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4012
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4013 // Ok must mark the card if not already dirty
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4014
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4015 // load the original value of the card
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4016 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4017
12835
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4018 __ if_then(card_val, BoolTest::ne, young_card); {
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4019 sync_kit(ideal);
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4020 // Use Op_MemBarVolatile to achieve the effect of a StoreLoad barrier.
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4021 insert_mem_bar(Op_MemBarVolatile, oop_store);
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4022 __ sync_kit(this);
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4023
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4024 Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4025 __ if_then(card_val_reload, BoolTest::ne, dirty_card); {
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4026 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
69944b868a32 8014555: G1: Memory ordering problem with Conc refinement and card marking
mgerdin
parents: 12190
diff changeset
4027 } __ end_if();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4028 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4029 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4030 } __ end_if();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4031 } else {
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
4032 // Object.clone() instrinsic uses this path.
985
685e959d09ea 6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents: 955
diff changeset
4033 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4034 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4035
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
4036 // Final sync IdealKit and GraphKit.
2444
07acc51c1d2a 7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents: 2383
diff changeset
4037 final_sync(ideal);
851
fc4be448891f 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 827
diff changeset
4038 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
4039 #undef __
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4040
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4041
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4042
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4043 Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4044 if (java_lang_String::has_offset_field()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4045 int offset_offset = java_lang_String::offset_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4046 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4047 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4048 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4049 int offset_field_idx = C->get_alias_index(offset_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4050 return make_load(ctrl,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4051 basic_plus_adr(str, str, offset_offset),
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4052 TypeInt::INT, T_INT, offset_field_idx, MemNode::unordered);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4053 } else {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4054 return intcon(0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4055 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4056 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4058 Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4059 if (java_lang_String::has_count_field()) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4060 int count_offset = java_lang_String::count_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4061 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4062 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4063 const TypePtr* count_field_type = string_type->add_offset(count_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4064 int count_field_idx = C->get_alias_index(count_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4065 return make_load(ctrl,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4066 basic_plus_adr(str, str, count_offset),
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4067 TypeInt::INT, T_INT, count_field_idx, MemNode::unordered);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4068 } else {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4069 return load_array_length(load_String_value(ctrl, str));
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4070 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4071 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4072
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4073 Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4074 int value_offset = java_lang_String::value_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4075 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4076 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4077 const TypePtr* value_field_type = string_type->add_offset(value_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4078 const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4079 TypeAry::make(TypeInt::CHAR,TypeInt::POS),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4080 ciTypeArrayKlass::make(T_CHAR), true, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4081 int value_field_idx = C->get_alias_index(value_field_type);
12190
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4082 Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset),
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4083 value_type, T_OBJECT, value_field_idx, MemNode::unordered);
12190
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4084 // String.value field is known to be @Stable.
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4085 if (UseImplicitStableValues) {
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4086 load = cast_array_to_stable(load, value_type);
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4087 }
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4088 return load;
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4089 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4090
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4091 void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4092 int offset_offset = java_lang_String::offset_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4093 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4094 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4095 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4096 int offset_field_idx = C->get_alias_index(offset_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4097 store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4098 value, T_INT, offset_field_idx, MemNode::unordered);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4099 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4100
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4101 void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4102 int value_offset = java_lang_String::value_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4103 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4104 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4105 const TypePtr* value_field_type = string_type->add_offset(value_offset);
12331
d8d059e90ec1 8025599: Missing store barrier with OptimizeStringConcat
twisti
parents: 12190
diff changeset
4106
d8d059e90ec1 8025599: Missing store barrier with OptimizeStringConcat
twisti
parents: 12190
diff changeset
4107 store_oop_to_object(ctrl, str, basic_plus_adr(str, value_offset), value_field_type,
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4108 value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4109 }
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4110
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4111 void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4112 int count_offset = java_lang_String::count_offset_in_bytes();
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4113 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4114 false, NULL, 0);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4115 const TypePtr* count_field_type = string_type->add_offset(count_offset);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4116 int count_field_idx = C->get_alias_index(count_field_type);
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4117 store_to_memory(ctrl, basic_plus_adr(str, count_offset),
14429
2113136690bc 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
goetz
parents: 12966
diff changeset
4118 value, T_INT, count_field_idx, MemNode::unordered);
6057
8f972594effc 6924259: Remove String.count/String.offset
kvn
parents: 4894
diff changeset
4119 }
12190
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4120
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4121 Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4122 // Reify the property as a CastPP node in Ideal graph to comply with monotonicity
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4123 // assumption of CCP analysis.
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4124 return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true)));
edb5ab0f3fe5 8001107: @Stable annotation for constant folding of lazily evaluated variables
vlivanov
parents: 12169
diff changeset
4125 }