annotate src/share/vm/opto/graphKit.cpp @ 2007:5ddfcf4b079e

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