annotate src/share/vm/opto/graphKit.cpp @ 1721:413ad0331a0c

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