Mercurial > hg > truffle
annotate src/share/vm/opto/compile.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | cfe522e6461c |
children | 2aff40cb4703 |
rev | line source |
---|---|
0 | 1 /* |
5948
ee138854b3a6
7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents:
4767
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/assembler.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "code/exceptionHandlerTable.hpp" | |
29 #include "code/nmethod.hpp" | |
30 #include "compiler/compileLog.hpp" | |
31 #include "compiler/oopMap.hpp" | |
32 #include "opto/addnode.hpp" | |
33 #include "opto/block.hpp" | |
34 #include "opto/c2compiler.hpp" | |
35 #include "opto/callGenerator.hpp" | |
36 #include "opto/callnode.hpp" | |
37 #include "opto/cfgnode.hpp" | |
38 #include "opto/chaitin.hpp" | |
39 #include "opto/compile.hpp" | |
40 #include "opto/connode.hpp" | |
41 #include "opto/divnode.hpp" | |
42 #include "opto/escape.hpp" | |
43 #include "opto/idealGraphPrinter.hpp" | |
44 #include "opto/loopnode.hpp" | |
45 #include "opto/machnode.hpp" | |
46 #include "opto/macro.hpp" | |
47 #include "opto/matcher.hpp" | |
48 #include "opto/memnode.hpp" | |
49 #include "opto/mulnode.hpp" | |
50 #include "opto/node.hpp" | |
51 #include "opto/opcodes.hpp" | |
52 #include "opto/output.hpp" | |
53 #include "opto/parse.hpp" | |
54 #include "opto/phaseX.hpp" | |
55 #include "opto/rootnode.hpp" | |
56 #include "opto/runtime.hpp" | |
57 #include "opto/stringopts.hpp" | |
58 #include "opto/type.hpp" | |
59 #include "opto/vectornode.hpp" | |
60 #include "runtime/arguments.hpp" | |
61 #include "runtime/signature.hpp" | |
62 #include "runtime/stubRoutines.hpp" | |
63 #include "runtime/timer.hpp" | |
64 #include "utilities/copy.hpp" | |
65 #ifdef TARGET_ARCH_MODEL_x86_32 | |
66 # include "adfiles/ad_x86_32.hpp" | |
67 #endif | |
68 #ifdef TARGET_ARCH_MODEL_x86_64 | |
69 # include "adfiles/ad_x86_64.hpp" | |
70 #endif | |
71 #ifdef TARGET_ARCH_MODEL_sparc | |
72 # include "adfiles/ad_sparc.hpp" | |
73 #endif | |
74 #ifdef TARGET_ARCH_MODEL_zero | |
75 # include "adfiles/ad_zero.hpp" | |
76 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
77 #ifdef TARGET_ARCH_MODEL_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
78 # include "adfiles/ad_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
79 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
80 #ifdef TARGET_ARCH_MODEL_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
81 # include "adfiles/ad_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2091
diff
changeset
|
82 #endif |
0 | 83 |
2008 | 84 |
85 // -------------------- Compile::mach_constant_base_node ----------------------- | |
86 // Constant table base node singleton. | |
87 MachConstantBaseNode* Compile::mach_constant_base_node() { | |
88 if (_mach_constant_base_node == NULL) { | |
89 _mach_constant_base_node = new (C) MachConstantBaseNode(); | |
90 _mach_constant_base_node->add_req(C->root()); | |
91 } | |
92 return _mach_constant_base_node; | |
93 } | |
94 | |
95 | |
0 | 96 /// Support for intrinsics. |
97 | |
98 // Return the index at which m must be inserted (or already exists). | |
99 // The sort order is by the address of the ciMethod, with is_virtual as minor key. | |
100 int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { | |
101 #ifdef ASSERT | |
102 for (int i = 1; i < _intrinsics->length(); i++) { | |
103 CallGenerator* cg1 = _intrinsics->at(i-1); | |
104 CallGenerator* cg2 = _intrinsics->at(i); | |
105 assert(cg1->method() != cg2->method() | |
106 ? cg1->method() < cg2->method() | |
107 : cg1->is_virtual() < cg2->is_virtual(), | |
108 "compiler intrinsics list must stay sorted"); | |
109 } | |
110 #endif | |
111 // Binary search sorted list, in decreasing intervals [lo, hi]. | |
112 int lo = 0, hi = _intrinsics->length()-1; | |
113 while (lo <= hi) { | |
114 int mid = (uint)(hi + lo) / 2; | |
115 ciMethod* mid_m = _intrinsics->at(mid)->method(); | |
116 if (m < mid_m) { | |
117 hi = mid-1; | |
118 } else if (m > mid_m) { | |
119 lo = mid+1; | |
120 } else { | |
121 // look at minor sort key | |
122 bool mid_virt = _intrinsics->at(mid)->is_virtual(); | |
123 if (is_virtual < mid_virt) { | |
124 hi = mid-1; | |
125 } else if (is_virtual > mid_virt) { | |
126 lo = mid+1; | |
127 } else { | |
128 return mid; // exact match | |
129 } | |
130 } | |
131 } | |
132 return lo; // inexact match | |
133 } | |
134 | |
135 void Compile::register_intrinsic(CallGenerator* cg) { | |
136 if (_intrinsics == NULL) { | |
137 _intrinsics = new GrowableArray<CallGenerator*>(60); | |
138 } | |
139 // This code is stolen from ciObjectFactory::insert. | |
140 // Really, GrowableArray should have methods for | |
141 // insert_at, remove_at, and binary_search. | |
142 int len = _intrinsics->length(); | |
143 int index = intrinsic_insertion_index(cg->method(), cg->is_virtual()); | |
144 if (index == len) { | |
145 _intrinsics->append(cg); | |
146 } else { | |
147 #ifdef ASSERT | |
148 CallGenerator* oldcg = _intrinsics->at(index); | |
149 assert(oldcg->method() != cg->method() || oldcg->is_virtual() != cg->is_virtual(), "don't register twice"); | |
150 #endif | |
151 _intrinsics->append(_intrinsics->at(len-1)); | |
152 int pos; | |
153 for (pos = len-2; pos >= index; pos--) { | |
154 _intrinsics->at_put(pos+1,_intrinsics->at(pos)); | |
155 } | |
156 _intrinsics->at_put(index, cg); | |
157 } | |
158 assert(find_intrinsic(cg->method(), cg->is_virtual()) == cg, "registration worked"); | |
159 } | |
160 | |
161 CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) { | |
162 assert(m->is_loaded(), "don't try this on unloaded methods"); | |
163 if (_intrinsics != NULL) { | |
164 int index = intrinsic_insertion_index(m, is_virtual); | |
165 if (index < _intrinsics->length() | |
166 && _intrinsics->at(index)->method() == m | |
167 && _intrinsics->at(index)->is_virtual() == is_virtual) { | |
168 return _intrinsics->at(index); | |
169 } | |
170 } | |
171 // Lazily create intrinsics for intrinsic IDs well-known in the runtime. | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
647
diff
changeset
|
172 if (m->intrinsic_id() != vmIntrinsics::_none && |
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
647
diff
changeset
|
173 m->intrinsic_id() <= vmIntrinsics::LAST_COMPILER_INLINE) { |
0 | 174 CallGenerator* cg = make_vm_intrinsic(m, is_virtual); |
175 if (cg != NULL) { | |
176 // Save it for next time: | |
177 register_intrinsic(cg); | |
178 return cg; | |
179 } else { | |
180 gather_intrinsic_statistics(m->intrinsic_id(), is_virtual, _intrinsic_disabled); | |
181 } | |
182 } | |
183 return NULL; | |
184 } | |
185 | |
186 // Compile:: register_library_intrinsics and make_vm_intrinsic are defined | |
187 // in library_call.cpp. | |
188 | |
189 | |
190 #ifndef PRODUCT | |
191 // statistics gathering... | |
192 | |
193 juint Compile::_intrinsic_hist_count[vmIntrinsics::ID_LIMIT] = {0}; | |
194 jubyte Compile::_intrinsic_hist_flags[vmIntrinsics::ID_LIMIT] = {0}; | |
195 | |
196 bool Compile::gather_intrinsic_statistics(vmIntrinsics::ID id, bool is_virtual, int flags) { | |
197 assert(id > vmIntrinsics::_none && id < vmIntrinsics::ID_LIMIT, "oob"); | |
198 int oflags = _intrinsic_hist_flags[id]; | |
199 assert(flags != 0, "what happened?"); | |
200 if (is_virtual) { | |
201 flags |= _intrinsic_virtual; | |
202 } | |
203 bool changed = (flags != oflags); | |
204 if ((flags & _intrinsic_worked) != 0) { | |
205 juint count = (_intrinsic_hist_count[id] += 1); | |
206 if (count == 1) { | |
207 changed = true; // first time | |
208 } | |
209 // increment the overall count also: | |
210 _intrinsic_hist_count[vmIntrinsics::_none] += 1; | |
211 } | |
212 if (changed) { | |
213 if (((oflags ^ flags) & _intrinsic_virtual) != 0) { | |
214 // Something changed about the intrinsic's virtuality. | |
215 if ((flags & _intrinsic_virtual) != 0) { | |
216 // This is the first use of this intrinsic as a virtual call. | |
217 if (oflags != 0) { | |
218 // We already saw it as a non-virtual, so note both cases. | |
219 flags |= _intrinsic_both; | |
220 } | |
221 } else if ((oflags & _intrinsic_both) == 0) { | |
222 // This is the first use of this intrinsic as a non-virtual | |
223 flags |= _intrinsic_both; | |
224 } | |
225 } | |
226 _intrinsic_hist_flags[id] = (jubyte) (oflags | flags); | |
227 } | |
228 // update the overall flags also: | |
229 _intrinsic_hist_flags[vmIntrinsics::_none] |= (jubyte) flags; | |
230 return changed; | |
231 } | |
232 | |
233 static char* format_flags(int flags, char* buf) { | |
234 buf[0] = 0; | |
235 if ((flags & Compile::_intrinsic_worked) != 0) strcat(buf, ",worked"); | |
236 if ((flags & Compile::_intrinsic_failed) != 0) strcat(buf, ",failed"); | |
237 if ((flags & Compile::_intrinsic_disabled) != 0) strcat(buf, ",disabled"); | |
238 if ((flags & Compile::_intrinsic_virtual) != 0) strcat(buf, ",virtual"); | |
239 if ((flags & Compile::_intrinsic_both) != 0) strcat(buf, ",nonvirtual"); | |
240 if (buf[0] == 0) strcat(buf, ","); | |
241 assert(buf[0] == ',', "must be"); | |
242 return &buf[1]; | |
243 } | |
244 | |
245 void Compile::print_intrinsic_statistics() { | |
246 char flagsbuf[100]; | |
247 ttyLocker ttyl; | |
248 if (xtty != NULL) xtty->head("statistics type='intrinsic'"); | |
249 tty->print_cr("Compiler intrinsic usage:"); | |
250 juint total = _intrinsic_hist_count[vmIntrinsics::_none]; | |
251 if (total == 0) total = 1; // avoid div0 in case of no successes | |
252 #define PRINT_STAT_LINE(name, c, f) \ | |
253 tty->print_cr(" %4d (%4.1f%%) %s (%s)", (int)(c), ((c) * 100.0) / total, name, f); | |
254 for (int index = 1 + (int)vmIntrinsics::_none; index < (int)vmIntrinsics::ID_LIMIT; index++) { | |
255 vmIntrinsics::ID id = (vmIntrinsics::ID) index; | |
256 int flags = _intrinsic_hist_flags[id]; | |
257 juint count = _intrinsic_hist_count[id]; | |
258 if ((flags | count) != 0) { | |
259 PRINT_STAT_LINE(vmIntrinsics::name_at(id), count, format_flags(flags, flagsbuf)); | |
260 } | |
261 } | |
262 PRINT_STAT_LINE("total", total, format_flags(_intrinsic_hist_flags[vmIntrinsics::_none], flagsbuf)); | |
263 if (xtty != NULL) xtty->tail("statistics"); | |
264 } | |
265 | |
266 void Compile::print_statistics() { | |
267 { ttyLocker ttyl; | |
268 if (xtty != NULL) xtty->head("statistics type='opto'"); | |
269 Parse::print_statistics(); | |
270 PhaseCCP::print_statistics(); | |
271 PhaseRegAlloc::print_statistics(); | |
272 Scheduling::print_statistics(); | |
273 PhasePeephole::print_statistics(); | |
274 PhaseIdealLoop::print_statistics(); | |
275 if (xtty != NULL) xtty->tail("statistics"); | |
276 } | |
277 if (_intrinsic_hist_flags[vmIntrinsics::_none] != 0) { | |
278 // put this under its own <statistics> element. | |
279 print_intrinsic_statistics(); | |
280 } | |
281 } | |
282 #endif //PRODUCT | |
283 | |
284 // Support for bundling info | |
285 Bundle* Compile::node_bundling(const Node *n) { | |
286 assert(valid_bundle_info(n), "oob"); | |
287 return &_node_bundling_base[n->_idx]; | |
288 } | |
289 | |
290 bool Compile::valid_bundle_info(const Node *n) { | |
291 return (_node_bundling_limit > n->_idx); | |
292 } | |
293 | |
294 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
295 void Compile::gvn_replace_by(Node* n, Node* nn) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
296 for (DUIterator_Last imin, i = n->last_outs(imin); i >= imin; ) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
297 Node* use = n->last_out(i); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
298 bool is_in_table = initial_gvn()->hash_delete(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
299 uint uses_found = 0; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
300 for (uint j = 0; j < use->len(); j++) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
301 if (use->in(j) == n) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
302 if (j < use->req()) |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
303 use->set_req(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
304 else |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
305 use->set_prec(j, nn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
306 uses_found++; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
307 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
308 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
309 if (is_in_table) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
310 // reinsert into table |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
311 initial_gvn()->hash_find_insert(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
312 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
313 record_for_igvn(use); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
314 i -= uses_found; // we deleted 1 or more copies of this edge |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
315 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
316 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
317 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
318 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
319 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
320 |
0 | 321 // Identify all nodes that are reachable from below, useful. |
322 // Use breadth-first pass that records state in a Unique_Node_List, | |
323 // recursive traversal is slower. | |
324 void Compile::identify_useful_nodes(Unique_Node_List &useful) { | |
325 int estimated_worklist_size = unique(); | |
326 useful.map( estimated_worklist_size, NULL ); // preallocate space | |
327 | |
328 // Initialize worklist | |
329 if (root() != NULL) { useful.push(root()); } | |
330 // If 'top' is cached, declare it useful to preserve cached node | |
331 if( cached_top_node() ) { useful.push(cached_top_node()); } | |
332 | |
333 // Push all useful nodes onto the list, breadthfirst | |
334 for( uint next = 0; next < useful.size(); ++next ) { | |
335 assert( next < unique(), "Unique useful nodes < total nodes"); | |
336 Node *n = useful.at(next); | |
337 uint max = n->len(); | |
338 for( uint i = 0; i < max; ++i ) { | |
339 Node *m = n->in(i); | |
340 if( m == NULL ) continue; | |
341 useful.push(m); | |
342 } | |
343 } | |
344 } | |
345 | |
346 // Disconnect all useless nodes by disconnecting those at the boundary. | |
347 void Compile::remove_useless_nodes(Unique_Node_List &useful) { | |
348 uint next = 0; | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
349 while (next < useful.size()) { |
0 | 350 Node *n = useful.at(next++); |
351 // Use raw traversal of out edges since this code removes out edges | |
352 int max = n->outcnt(); | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
353 for (int j = 0; j < max; ++j) { |
0 | 354 Node* child = n->raw_out(j); |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
355 if (! useful.member(child)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
356 assert(!child->is_top() || child != top(), |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
357 "If top is cached in Compile object it is in useful list"); |
0 | 358 // Only need to remove this out-edge to the useless node |
359 n->raw_del_out(j); | |
360 --j; | |
361 --max; | |
362 } | |
363 } | |
364 if (n->outcnt() == 1 && n->has_special_unique_user()) { | |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
365 record_for_igvn(n->unique_out()); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
366 } |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
367 } |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
368 // Remove useless macro and predicate opaq nodes |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
369 for (int i = C->macro_count()-1; i >= 0; i--) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
370 Node* n = C->macro_node(i); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
371 if (!useful.member(n)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
372 remove_macro_node(n); |
0 | 373 } |
374 } | |
375 debug_only(verify_graph_edges(true/*check for no_dead_code*/);) | |
376 } | |
377 | |
378 //------------------------------frame_size_in_words----------------------------- | |
379 // frame_slots in units of words | |
380 int Compile::frame_size_in_words() const { | |
381 // shift is 0 in LP32 and 1 in LP64 | |
382 const int shift = (LogBytesPerWord - LogBytesPerInt); | |
383 int words = _frame_slots >> shift; | |
384 assert( words << shift == _frame_slots, "frame size must be properly aligned in LP64" ); | |
385 return words; | |
386 } | |
387 | |
388 // ============================================================================ | |
389 //------------------------------CompileWrapper--------------------------------- | |
390 class CompileWrapper : public StackObj { | |
391 Compile *const _compile; | |
392 public: | |
393 CompileWrapper(Compile* compile); | |
394 | |
395 ~CompileWrapper(); | |
396 }; | |
397 | |
398 CompileWrapper::CompileWrapper(Compile* compile) : _compile(compile) { | |
399 // the Compile* pointer is stored in the current ciEnv: | |
400 ciEnv* env = compile->env(); | |
401 assert(env == ciEnv::current(), "must already be a ciEnv active"); | |
402 assert(env->compiler_data() == NULL, "compile already active?"); | |
403 env->set_compiler_data(compile); | |
404 assert(compile == Compile::current(), "sanity"); | |
405 | |
406 compile->set_type_dict(NULL); | |
407 compile->set_type_hwm(NULL); | |
408 compile->set_type_last_size(0); | |
409 compile->set_last_tf(NULL, NULL); | |
410 compile->set_indexSet_arena(NULL); | |
411 compile->set_indexSet_free_block_list(NULL); | |
412 compile->init_type_arena(); | |
413 Type::Initialize(compile); | |
414 _compile->set_scratch_buffer_blob(NULL); | |
415 _compile->begin_method(); | |
416 } | |
417 CompileWrapper::~CompileWrapper() { | |
418 _compile->end_method(); | |
419 if (_compile->scratch_buffer_blob() != NULL) | |
420 BufferBlob::free(_compile->scratch_buffer_blob()); | |
421 _compile->env()->set_compiler_data(NULL); | |
422 } | |
423 | |
424 | |
425 //----------------------------print_compile_messages--------------------------- | |
426 void Compile::print_compile_messages() { | |
427 #ifndef PRODUCT | |
428 // Check if recompiling | |
429 if (_subsume_loads == false && PrintOpto) { | |
430 // Recompiling without allowing machine instructions to subsume loads | |
431 tty->print_cr("*********************************************************"); | |
432 tty->print_cr("** Bailout: Recompile without subsuming loads **"); | |
433 tty->print_cr("*********************************************************"); | |
434 } | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
435 if (_do_escape_analysis != DoEscapeAnalysis && PrintOpto) { |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
436 // Recompiling without escape analysis |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
437 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
438 tty->print_cr("** Bailout: Recompile without escape analysis **"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
439 tty->print_cr("*********************************************************"); |
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
440 } |
0 | 441 if (env()->break_at_compile()) { |
605 | 442 // Open the debugger when compiling this method. |
0 | 443 tty->print("### Breaking when compiling: "); |
444 method()->print_short_name(); | |
445 tty->cr(); | |
446 BREAKPOINT; | |
447 } | |
448 | |
449 if( PrintOpto ) { | |
450 if (is_osr_compilation()) { | |
451 tty->print("[OSR]%3d", _compile_id); | |
452 } else { | |
453 tty->print("%3d", _compile_id); | |
454 } | |
455 } | |
456 #endif | |
457 } | |
458 | |
459 | |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
460 //-----------------------init_scratch_buffer_blob------------------------------ |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
461 // Construct a temporary BufferBlob and cache it for this compile. |
2008 | 462 void Compile::init_scratch_buffer_blob(int const_size) { |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
463 // If there is already a scratch buffer blob allocated and the |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
464 // constant section is big enough, use it. Otherwise free the |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
465 // current and allocate a new one. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
466 BufferBlob* blob = scratch_buffer_blob(); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
467 if ((blob != NULL) && (const_size <= _scratch_const_size)) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
468 // Use the current blob. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
469 } else { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
470 if (blob != NULL) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
471 BufferBlob::free(blob); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
472 } |
0 | 473 |
2091
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
474 ResourceMark rm; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
475 _scratch_const_size = const_size; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
476 int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
477 blob = BufferBlob::create("Compile::scratch_buffer", size); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
478 // Record the buffer blob for next time. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
479 set_scratch_buffer_blob(blob); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
480 // Have we run out of code space? |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
481 if (scratch_buffer_blob() == NULL) { |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
482 // Let CompilerBroker disable further compilations. |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
483 record_failure("Not enough space for scratch buffer in CodeCache"); |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
484 return; |
51bd2d261853
7008325: CodeCache exhausted on sparc starting from hs20b04
kvn
parents:
2008
diff
changeset
|
485 } |
163 | 486 } |
0 | 487 |
488 // Initialize the relocation buffers | |
1748 | 489 relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size; |
0 | 490 set_scratch_locs_memory(locs_buf); |
491 } | |
492 | |
493 | |
494 //-----------------------scratch_emit_size------------------------------------- | |
495 // Helper function that computes size by emitting code | |
496 uint Compile::scratch_emit_size(const Node* n) { | |
2008 | 497 // Start scratch_emit_size section. |
498 set_in_scratch_emit_size(true); | |
499 | |
0 | 500 // Emit into a trash buffer and count bytes emitted. |
501 // This is a pretty expensive way to compute a size, | |
502 // but it works well enough if seldom used. | |
503 // All common fixed-size instructions are given a size | |
504 // method by the AD file. | |
505 // Note that the scratch buffer blob and locs memory are | |
506 // allocated at the beginning of the compile task, and | |
507 // may be shared by several calls to scratch_emit_size. | |
508 // The allocation of the scratch buffer blob is particularly | |
509 // expensive, since it has to grab the code cache lock. | |
510 BufferBlob* blob = this->scratch_buffer_blob(); | |
511 assert(blob != NULL, "Initialize BufferBlob at start"); | |
512 assert(blob->size() > MAX_inst_size, "sanity"); | |
513 relocInfo* locs_buf = scratch_locs_memory(); | |
1748 | 514 address blob_begin = blob->content_begin(); |
0 | 515 address blob_end = (address)locs_buf; |
1748 | 516 assert(blob->content_contains(blob_end), "sanity"); |
0 | 517 CodeBuffer buf(blob_begin, blob_end - blob_begin); |
2008 | 518 buf.initialize_consts_size(_scratch_const_size); |
0 | 519 buf.initialize_stubs_size(MAX_stubs_size); |
520 assert(locs_buf != NULL, "sanity"); | |
2008 | 521 int lsize = MAX_locs_size / 3; |
522 buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize); | |
523 buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize); | |
524 buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize); | |
525 | |
526 // Do the emission. | |
3839 | 527 |
528 Label fakeL; // Fake label for branch instructions. | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
529 Label* saveL = NULL; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
530 uint save_bnum = 0; |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
531 bool is_branch = n->is_MachBranch(); |
3839 | 532 if (is_branch) { |
533 MacroAssembler masm(&buf); | |
534 masm.bind(fakeL); | |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
535 n->as_MachBranch()->save_label(&saveL, &save_bnum); |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
536 n->as_MachBranch()->label_set(&fakeL, 0); |
3839 | 537 } |
0 | 538 n->emit(buf, this->regalloc()); |
3853
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
539 if (is_branch) // Restore label. |
11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents:
3839
diff
changeset
|
540 n->as_MachBranch()->label_set(saveL, save_bnum); |
2008 | 541 |
542 // End scratch_emit_size section. | |
543 set_in_scratch_emit_size(false); | |
544 | |
1748 | 545 return buf.insts_size(); |
0 | 546 } |
547 | |
548 | |
549 // ============================================================================ | |
550 //------------------------------Compile standard------------------------------- | |
551 debug_only( int Compile::_debug_idx = 100000; ) | |
552 | |
553 // Compile a method. entry_bci is -1 for normal compilations and indicates | |
554 // the continuation bci for on stack replacement. | |
555 | |
556 | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
557 Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr_bci, bool subsume_loads, bool do_escape_analysis ) |
0 | 558 : Phase(Compiler), |
559 _env(ci_env), | |
560 _log(ci_env->log()), | |
561 _compile_id(ci_env->compile_id()), | |
562 _save_argument_registers(false), | |
563 _stub_name(NULL), | |
564 _stub_function(NULL), | |
565 _stub_entry_point(NULL), | |
566 _method(target), | |
567 _entry_bci(osr_bci), | |
568 _initial_gvn(NULL), | |
569 _for_igvn(NULL), | |
570 _warm_calls(NULL), | |
571 _subsume_loads(subsume_loads), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
572 _do_escape_analysis(do_escape_analysis), |
0 | 573 _failure_reason(NULL), |
574 _code_buffer("Compile::Fill_buffer"), | |
575 _orig_pc_slot(0), | |
576 _orig_pc_slot_offset_in_bytes(0), | |
1265 | 577 _has_method_handle_invokes(false), |
2008 | 578 _mach_constant_base_node(NULL), |
0 | 579 _node_bundling_limit(0), |
580 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
581 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
582 _inner_loops(0), |
2008 | 583 _scratch_const_size(-1), |
584 _in_scratch_emit_size(false), | |
0 | 585 #ifndef PRODUCT |
586 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), | |
587 _printer(IdealGraphPrinter::printer()), | |
588 #endif | |
589 _congraph(NULL) { | |
590 C = this; | |
591 | |
592 CompileWrapper cw(this); | |
593 #ifndef PRODUCT | |
594 if (TimeCompiler2) { | |
595 tty->print(" "); | |
596 target->holder()->name()->print(); | |
597 tty->print("."); | |
598 target->print_short_name(); | |
599 tty->print(" "); | |
600 } | |
601 TraceTime t1("Total compilation time", &_t_totalCompilation, TimeCompiler, TimeCompiler2); | |
602 TraceTime t2(NULL, &_t_methodCompilation, TimeCompiler, false); | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
603 bool print_opto_assembly = PrintOptoAssembly || _method->has_option("PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
604 if (!print_opto_assembly) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
605 bool print_assembly = (PrintAssembly || _method->should_print_assembly()); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
606 if (print_assembly && !Disassembler::can_decode()) { |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
607 tty->print_cr("PrintAssembly request changed to PrintOptoAssembly"); |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
608 print_opto_assembly = true; |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
609 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
610 } |
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
65
diff
changeset
|
611 set_print_assembly(print_opto_assembly); |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
612 set_parsed_irreducible_loop(false); |
0 | 613 #endif |
614 | |
615 if (ProfileTraps) { | |
616 // Make sure the method being compiled gets its own MDO, | |
617 // so we can at least track the decompile_count(). | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
1972
diff
changeset
|
618 method()->ensure_method_data(); |
0 | 619 } |
620 | |
621 Init(::AliasLevel); | |
622 | |
623 | |
624 print_compile_messages(); | |
625 | |
626 if (UseOldInlining || PrintCompilation NOT_PRODUCT( || PrintOpto) ) | |
627 _ilt = InlineTree::build_inline_tree_root(); | |
628 else | |
629 _ilt = NULL; | |
630 | |
631 // Even if NO memory addresses are used, MergeMem nodes must have at least 1 slice | |
632 assert(num_alias_types() >= AliasIdxRaw, ""); | |
633 | |
634 #define MINIMUM_NODE_HASH 1023 | |
635 // Node list that Iterative GVN will start with | |
636 Unique_Node_List for_igvn(comp_arena()); | |
637 set_for_igvn(&for_igvn); | |
638 | |
639 // GVN that will be run immediately on new nodes | |
640 uint estimated_size = method()->code_size()*4+64; | |
641 estimated_size = (estimated_size < MINIMUM_NODE_HASH ? MINIMUM_NODE_HASH : estimated_size); | |
642 PhaseGVN gvn(node_arena(), estimated_size); | |
643 set_initial_gvn(&gvn); | |
644 | |
645 { // Scope for timing the parser | |
646 TracePhase t3("parse", &_t_parser, true); | |
647 | |
648 // Put top into the hash table ASAP. | |
649 initial_gvn()->transform_no_reclaim(top()); | |
650 | |
651 // Set up tf(), start(), and find a CallGenerator. | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
652 CallGenerator* cg = NULL; |
0 | 653 if (is_osr_compilation()) { |
654 const TypeTuple *domain = StartOSRNode::osr_domain(); | |
655 const TypeTuple *range = TypeTuple::make_range(method()->signature()); | |
656 init_tf(TypeFunc::make(domain, range)); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
657 StartNode* s = new (this) StartOSRNode(root(), domain); |
0 | 658 initial_gvn()->set_type_bottom(s); |
659 init_start(s); | |
660 cg = CallGenerator::for_osr(method(), entry_bci()); | |
661 } else { | |
662 // Normal case. | |
663 init_tf(TypeFunc::make(method())); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
664 StartNode* s = new (this) StartNode(root(), tf()->domain()); |
0 | 665 initial_gvn()->set_type_bottom(s); |
666 init_start(s); | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
667 if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
668 // With java.lang.ref.reference.get() we must go through the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
669 // intrinsic when G1 is enabled - even when get() is the root |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
670 // method of the compile - so that, if necessary, the value in |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
671 // the referent field of the reference object gets recorded by |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
672 // the pre-barrier code. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
673 // Specifically, if G1 is enabled, the value in the referent |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
674 // field is recorded by the G1 SATB pre barrier. This will |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
675 // result in the referent being marked live and the reference |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
676 // object removed from the list of discovered references during |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
677 // reference processing. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
678 cg = find_intrinsic(method(), false); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
679 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
680 if (cg == NULL) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
681 float past_uses = method()->interpreter_invocation_count(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
682 float expected_uses = past_uses; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
683 cg = CallGenerator::for_inline(method(), expected_uses); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
3248
diff
changeset
|
684 } |
0 | 685 } |
686 if (failing()) return; | |
687 if (cg == NULL) { | |
688 record_method_not_compilable_all_tiers("cannot parse method"); | |
689 return; | |
690 } | |
691 JVMState* jvms = build_start_state(start(), tf()); | |
692 if ((jvms = cg->generate(jvms)) == NULL) { | |
693 record_method_not_compilable("method parse failed"); | |
694 return; | |
695 } | |
696 GraphKit kit(jvms); | |
697 | |
698 if (!kit.stopped()) { | |
699 // Accept return values, and transfer control we know not where. | |
700 // This is done by a special, unique ReturnNode bound to root. | |
701 return_values(kit.jvms()); | |
702 } | |
703 | |
704 if (kit.has_exceptions()) { | |
705 // Any exceptions that escape from this call must be rethrown | |
706 // to whatever caller is dynamically above us on the stack. | |
707 // This is done by a special, unique RethrowNode bound to root. | |
708 rethrow_exceptions(kit.transfer_exceptions_into_jvms()); | |
709 } | |
710 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
711 if (!failing() && has_stringbuilder()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
712 { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
713 // remove useless nodes to make the usage analysis simpler |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
714 ResourceMark rm; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
715 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
716 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
717 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
718 { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
719 ResourceMark rm; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
720 print_method("Before StringOpts", 3); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
721 PhaseStringOpts pso(initial_gvn(), &for_igvn); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
722 print_method("After StringOpts", 3); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
723 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
724 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
725 // now inline anything that we skipped the first time around |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
726 while (_late_inlines.length() > 0) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
727 CallGenerator* cg = _late_inlines.pop(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
728 cg->do_late_inline(); |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
729 if (failing()) return; |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
730 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
731 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
732 assert(_late_inlines.length() == 0, "should have been processed"); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
733 |
417 | 734 print_method("Before RemoveUseless", 3); |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
735 |
0 | 736 // Remove clutter produced by parsing. |
737 if (!failing()) { | |
738 ResourceMark rm; | |
739 PhaseRemoveUseless pru(initial_gvn(), &for_igvn); | |
740 } | |
741 } | |
742 | |
743 // Note: Large methods are capped off in do_one_bytecode(). | |
744 if (failing()) return; | |
745 | |
746 // After parsing, node notes are no longer automagic. | |
747 // They must be propagated by register_new_node_with_optimizer(), | |
748 // clone(), or the like. | |
749 set_default_node_notes(NULL); | |
750 | |
751 for (;;) { | |
752 int successes = Inline_Warm(); | |
753 if (failing()) return; | |
754 if (successes == 0) break; | |
755 } | |
756 | |
757 // Drain the list. | |
758 Finish_Warm(); | |
759 #ifndef PRODUCT | |
760 if (_printer) { | |
761 _printer->print_inlining(this); | |
762 } | |
763 #endif | |
764 | |
765 if (failing()) return; | |
766 NOT_PRODUCT( verify_graph_edges(); ) | |
767 | |
768 // Now optimize | |
769 Optimize(); | |
770 if (failing()) return; | |
771 NOT_PRODUCT( verify_graph_edges(); ) | |
772 | |
773 #ifndef PRODUCT | |
774 if (PrintIdeal) { | |
775 ttyLocker ttyl; // keep the following output all in one block | |
776 // This output goes directly to the tty, not the compiler log. | |
777 // To enable tools to match it up with the compilation activity, | |
778 // be sure to tag this tty output with the compile ID. | |
779 if (xtty != NULL) { | |
780 xtty->head("ideal compile_id='%d'%s", compile_id(), | |
781 is_osr_compilation() ? " compile_kind='osr'" : | |
782 ""); | |
783 } | |
784 root()->dump(9999); | |
785 if (xtty != NULL) { | |
786 xtty->tail("ideal"); | |
787 } | |
788 } | |
789 #endif | |
790 | |
791 // Now that we know the size of all the monitors we can add a fixed slot | |
792 // for the original deopt pc. | |
793 | |
794 _orig_pc_slot = fixed_slots(); | |
795 int next_slot = _orig_pc_slot + (sizeof(address) / VMRegImpl::stack_slot_size); | |
796 set_fixed_slots(next_slot); | |
797 | |
798 // Now generate code | |
799 Code_Gen(); | |
800 if (failing()) return; | |
801 | |
802 // Check if we want to skip execution of all compiled code. | |
803 { | |
804 #ifndef PRODUCT | |
805 if (OptoNoExecute) { | |
806 record_method_not_compilable("+OptoNoExecute"); // Flag as failed | |
807 return; | |
808 } | |
809 TracePhase t2("install_code", &_t_registerMethod, TimeCompiler); | |
810 #endif | |
811 | |
812 if (is_osr_compilation()) { | |
813 _code_offsets.set_value(CodeOffsets::Verified_Entry, 0); | |
814 _code_offsets.set_value(CodeOffsets::OSR_Entry, _first_block_size); | |
815 } else { | |
816 _code_offsets.set_value(CodeOffsets::Verified_Entry, _first_block_size); | |
817 _code_offsets.set_value(CodeOffsets::OSR_Entry, 0); | |
818 } | |
819 | |
820 env()->register_method(_method, _entry_bci, | |
821 &_code_offsets, | |
822 _orig_pc_slot_offset_in_bytes, | |
823 code_buffer(), | |
824 frame_size_in_words(), _oop_map_set, | |
825 &_handler_table, &_inc_table, | |
826 compiler, | |
827 env()->comp_level(), | |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
828 has_unsafe_access(), |
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
829 SharedRuntime::is_wide_vector(max_vector_size()) |
0 | 830 ); |
6843 | 831 |
832 if (log() != NULL) // Print code cache state into compiler log | |
833 log()->code_cache_state(); | |
0 | 834 } |
835 } | |
836 | |
837 //------------------------------Compile---------------------------------------- | |
838 // Compile a runtime stub | |
839 Compile::Compile( ciEnv* ci_env, | |
840 TypeFunc_generator generator, | |
841 address stub_function, | |
842 const char *stub_name, | |
843 int is_fancy_jump, | |
844 bool pass_tls, | |
845 bool save_arg_registers, | |
846 bool return_pc ) | |
847 : Phase(Compiler), | |
848 _env(ci_env), | |
849 _log(ci_env->log()), | |
850 _compile_id(-1), | |
851 _save_argument_registers(save_arg_registers), | |
852 _method(NULL), | |
853 _stub_name(stub_name), | |
854 _stub_function(stub_function), | |
855 _stub_entry_point(NULL), | |
856 _entry_bci(InvocationEntryBci), | |
857 _initial_gvn(NULL), | |
858 _for_igvn(NULL), | |
859 _warm_calls(NULL), | |
860 _orig_pc_slot(0), | |
861 _orig_pc_slot_offset_in_bytes(0), | |
862 _subsume_loads(true), | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
863 _do_escape_analysis(false), |
0 | 864 _failure_reason(NULL), |
865 _code_buffer("Compile::Fill_buffer"), | |
1265 | 866 _has_method_handle_invokes(false), |
2008 | 867 _mach_constant_base_node(NULL), |
0 | 868 _node_bundling_limit(0), |
869 _node_bundling_base(NULL), | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
870 _java_calls(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
871 _inner_loops(0), |
0 | 872 #ifndef PRODUCT |
873 _trace_opto_output(TraceOptoOutput), | |
874 _printer(NULL), | |
875 #endif | |
876 _congraph(NULL) { | |
877 C = this; | |
878 | |
879 #ifndef PRODUCT | |
880 TraceTime t1(NULL, &_t_totalCompilation, TimeCompiler, false); | |
881 TraceTime t2(NULL, &_t_stubCompilation, TimeCompiler, false); | |
882 set_print_assembly(PrintFrameConverterAssembly); | |
367
194b8e3a2fc4
6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents:
333
diff
changeset
|
883 set_parsed_irreducible_loop(false); |
0 | 884 #endif |
885 CompileWrapper cw(this); | |
886 Init(/*AliasLevel=*/ 0); | |
887 init_tf((*generator)()); | |
888 | |
889 { | |
890 // The following is a dummy for the sake of GraphKit::gen_stub | |
891 Unique_Node_List for_igvn(comp_arena()); | |
892 set_for_igvn(&for_igvn); // not used, but some GraphKit guys push on this | |
893 PhaseGVN gvn(Thread::current()->resource_area(),255); | |
894 set_initial_gvn(&gvn); // not significant, but GraphKit guys use it pervasively | |
895 gvn.transform_no_reclaim(top()); | |
896 | |
897 GraphKit kit; | |
898 kit.gen_stub(stub_function, stub_name, is_fancy_jump, pass_tls, return_pc); | |
899 } | |
900 | |
901 NOT_PRODUCT( verify_graph_edges(); ) | |
902 Code_Gen(); | |
903 if (failing()) return; | |
904 | |
905 | |
906 // Entry point will be accessed using compile->stub_entry_point(); | |
907 if (code_buffer() == NULL) { | |
908 Matcher::soft_match_failure(); | |
909 } else { | |
910 if (PrintAssembly && (WizardMode || Verbose)) | |
911 tty->print_cr("### Stub::%s", stub_name); | |
912 | |
913 if (!failing()) { | |
914 assert(_fixed_slots == 0, "no fixed slots used for runtime stubs"); | |
915 | |
916 // Make the NMethod | |
917 // For now we mark the frame as never safe for profile stackwalking | |
918 RuntimeStub *rs = RuntimeStub::new_runtime_stub(stub_name, | |
919 code_buffer(), | |
920 CodeOffsets::frame_never_safe, | |
921 // _code_offsets.value(CodeOffsets::Frame_Complete), | |
922 frame_size_in_words(), | |
923 _oop_map_set, | |
924 save_arg_registers); | |
925 assert(rs != NULL && rs->is_runtime_stub(), "sanity check"); | |
926 | |
927 _stub_entry_point = rs->entry_point(); | |
928 } | |
929 } | |
930 } | |
931 | |
932 //------------------------------Init------------------------------------------- | |
933 // Prepare for a single compilation | |
934 void Compile::Init(int aliaslevel) { | |
935 _unique = 0; | |
936 _regalloc = NULL; | |
937 | |
938 _tf = NULL; // filled in later | |
939 _top = NULL; // cached later | |
940 _matcher = NULL; // filled in later | |
941 _cfg = NULL; // filled in later | |
942 | |
943 set_24_bit_selection_and_mode(Use24BitFP, false); | |
944 | |
945 _node_note_array = NULL; | |
946 _default_node_notes = NULL; | |
947 | |
948 _immutable_memory = NULL; // filled in at first inquiry | |
949 | |
950 // Globally visible Nodes | |
951 // First set TOP to NULL to give safe behavior during creation of RootNode | |
952 set_cached_top_node(NULL); | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
953 set_root(new (this) RootNode()); |
0 | 954 // Now that you have a Root to point to, create the real TOP |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
955 set_cached_top_node( new (this) ConNode(Type::TOP) ); |
0 | 956 set_recent_alloc(NULL, NULL); |
957 | |
958 // Create Debug Information Recorder to record scopes, oopmaps, etc. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
959 env()->set_oop_recorder(new OopRecorder(env()->arena())); |
0 | 960 env()->set_debug_info(new DebugInformationRecorder(env()->oop_recorder())); |
961 env()->set_dependencies(new Dependencies(env())); | |
962 | |
963 _fixed_slots = 0; | |
964 set_has_split_ifs(false); | |
965 set_has_loops(has_method() && method()->has_loops()); // first approximation | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
966 set_has_stringbuilder(false); |
0 | 967 _trap_can_recompile = false; // no traps emitted yet |
968 _major_progress = true; // start out assuming good things will happen | |
969 set_has_unsafe_access(false); | |
6792
137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
kvn
parents:
6725
diff
changeset
|
970 set_max_vector_size(0); |
0 | 971 Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); |
972 set_decompile_count(0); | |
973 | |
418 | 974 set_do_freq_based_layout(BlockLayoutByFrequency || method_has_option("BlockLayoutByFrequency")); |
1783 | 975 set_num_loop_opts(LoopOptsCount); |
976 set_do_inlining(Inline); | |
977 set_max_inline_size(MaxInlineSize); | |
978 set_freq_inline_size(FreqInlineSize); | |
979 set_do_scheduling(OptoScheduling); | |
980 set_do_count_invocations(false); | |
981 set_do_method_data_update(false); | |
0 | 982 |
983 if (debug_info()->recording_non_safepoints()) { | |
984 set_node_note_array(new(comp_arena()) GrowableArray<Node_Notes*> | |
985 (comp_arena(), 8, 0, NULL)); | |
986 set_default_node_notes(Node_Notes::make(this)); | |
987 } | |
988 | |
989 // // -- Initialize types before each compile -- | |
990 // // Update cached type information | |
991 // if( _method && _method->constants() ) | |
992 // Type::update_loaded_types(_method, _method->constants()); | |
993 | |
994 // Init alias_type map. | |
38
b789bcaf2dd9
6667610: (Escape Analysis) retry compilation without EA if it fails
kvn
parents:
0
diff
changeset
|
995 if (!_do_escape_analysis && aliaslevel == 3) |
0 | 996 aliaslevel = 2; // No unique types without escape analysis |
997 _AliasLevel = aliaslevel; | |
998 const int grow_ats = 16; | |
999 _max_alias_types = grow_ats; | |
1000 _alias_types = NEW_ARENA_ARRAY(comp_arena(), AliasType*, grow_ats); | |
1001 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, grow_ats); | |
1002 Copy::zero_to_bytes(ats, sizeof(AliasType)*grow_ats); | |
1003 { | |
1004 for (int i = 0; i < grow_ats; i++) _alias_types[i] = &ats[i]; | |
1005 } | |
1006 // Initialize the first few types. | |
1007 _alias_types[AliasIdxTop]->Init(AliasIdxTop, NULL); | |
1008 _alias_types[AliasIdxBot]->Init(AliasIdxBot, TypePtr::BOTTOM); | |
1009 _alias_types[AliasIdxRaw]->Init(AliasIdxRaw, TypeRawPtr::BOTTOM); | |
1010 _num_alias_types = AliasIdxRaw+1; | |
1011 // Zero out the alias type cache. | |
1012 Copy::zero_to_bytes(_alias_cache, sizeof(_alias_cache)); | |
1013 // A NULL adr_type hits in the cache right away. Preload the right answer. | |
1014 probe_alias_cache(NULL)->_index = AliasIdxTop; | |
1015 | |
1016 _intrinsics = NULL; | |
1685 | 1017 _macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); |
1018 _predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); | |
0 | 1019 register_library_intrinsics(); |
1020 } | |
1021 | |
1022 //---------------------------init_start---------------------------------------- | |
1023 // Install the StartNode on this compile object. | |
1024 void Compile::init_start(StartNode* s) { | |
1025 if (failing()) | |
1026 return; // already failing | |
1027 assert(s == start(), ""); | |
1028 } | |
1029 | |
1030 StartNode* Compile::start() const { | |
1031 assert(!failing(), ""); | |
1032 for (DUIterator_Fast imax, i = root()->fast_outs(imax); i < imax; i++) { | |
1033 Node* start = root()->fast_out(i); | |
1034 if( start->is_Start() ) | |
1035 return start->as_Start(); | |
1036 } | |
1037 ShouldNotReachHere(); | |
1038 return NULL; | |
1039 } | |
1040 | |
1041 //-------------------------------immutable_memory------------------------------------- | |
1042 // Access immutable memory | |
1043 Node* Compile::immutable_memory() { | |
1044 if (_immutable_memory != NULL) { | |
1045 return _immutable_memory; | |
1046 } | |
1047 StartNode* s = start(); | |
1048 for (DUIterator_Fast imax, i = s->fast_outs(imax); true; i++) { | |
1049 Node *p = s->fast_out(i); | |
1050 if (p != s && p->as_Proj()->_con == TypeFunc::Memory) { | |
1051 _immutable_memory = p; | |
1052 return _immutable_memory; | |
1053 } | |
1054 } | |
1055 ShouldNotReachHere(); | |
1056 return NULL; | |
1057 } | |
1058 | |
1059 //----------------------set_cached_top_node------------------------------------ | |
1060 // Install the cached top node, and make sure Node::is_top works correctly. | |
1061 void Compile::set_cached_top_node(Node* tn) { | |
1062 if (tn != NULL) verify_top(tn); | |
1063 Node* old_top = _top; | |
1064 _top = tn; | |
1065 // Calling Node::setup_is_top allows the nodes the chance to adjust | |
1066 // their _out arrays. | |
1067 if (_top != NULL) _top->setup_is_top(); | |
1068 if (old_top != NULL) old_top->setup_is_top(); | |
1069 assert(_top == NULL || top()->is_top(), ""); | |
1070 } | |
1071 | |
1072 #ifndef PRODUCT | |
1073 void Compile::verify_top(Node* tn) const { | |
1074 if (tn != NULL) { | |
1075 assert(tn->is_Con(), "top node must be a constant"); | |
1076 assert(((ConNode*)tn)->type() == Type::TOP, "top node must have correct type"); | |
1077 assert(tn->in(0) != NULL, "must have live top node"); | |
1078 } | |
1079 } | |
1080 #endif | |
1081 | |
1082 | |
1083 ///-------------------Managing Per-Node Debug & Profile Info------------------- | |
1084 | |
1085 void Compile::grow_node_notes(GrowableArray<Node_Notes*>* arr, int grow_by) { | |
1086 guarantee(arr != NULL, ""); | |
1087 int num_blocks = arr->length(); | |
1088 if (grow_by < num_blocks) grow_by = num_blocks; | |
1089 int num_notes = grow_by * _node_notes_block_size; | |
1090 Node_Notes* notes = NEW_ARENA_ARRAY(node_arena(), Node_Notes, num_notes); | |
1091 Copy::zero_to_bytes(notes, num_notes * sizeof(Node_Notes)); | |
1092 while (num_notes > 0) { | |
1093 arr->append(notes); | |
1094 notes += _node_notes_block_size; | |
1095 num_notes -= _node_notes_block_size; | |
1096 } | |
1097 assert(num_notes == 0, "exact multiple, please"); | |
1098 } | |
1099 | |
1100 bool Compile::copy_node_notes_to(Node* dest, Node* source) { | |
1101 if (source == NULL || dest == NULL) return false; | |
1102 | |
1103 if (dest->is_Con()) | |
1104 return false; // Do not push debug info onto constants. | |
1105 | |
1106 #ifdef ASSERT | |
1107 // Leave a bread crumb trail pointing to the original node: | |
1108 if (dest != NULL && dest != source && dest->debug_orig() == NULL) { | |
1109 dest->set_debug_orig(source); | |
1110 } | |
1111 #endif | |
1112 | |
1113 if (node_note_array() == NULL) | |
1114 return false; // Not collecting any notes now. | |
1115 | |
1116 // This is a copy onto a pre-existing node, which may already have notes. | |
1117 // If both nodes have notes, do not overwrite any pre-existing notes. | |
1118 Node_Notes* source_notes = node_notes_at(source->_idx); | |
1119 if (source_notes == NULL || source_notes->is_clear()) return false; | |
1120 Node_Notes* dest_notes = node_notes_at(dest->_idx); | |
1121 if (dest_notes == NULL || dest_notes->is_clear()) { | |
1122 return set_node_notes_at(dest->_idx, source_notes); | |
1123 } | |
1124 | |
1125 Node_Notes merged_notes = (*source_notes); | |
1126 // The order of operations here ensures that dest notes will win... | |
1127 merged_notes.update_from(dest_notes); | |
1128 return set_node_notes_at(dest->_idx, &merged_notes); | |
1129 } | |
1130 | |
1131 | |
1132 //--------------------------allow_range_check_smearing------------------------- | |
1133 // Gating condition for coalescing similar range checks. | |
1134 // Sometimes we try 'speculatively' replacing a series of a range checks by a | |
1135 // single covering check that is at least as strong as any of them. | |
1136 // If the optimization succeeds, the simplified (strengthened) range check | |
1137 // will always succeed. If it fails, we will deopt, and then give up | |
1138 // on the optimization. | |
1139 bool Compile::allow_range_check_smearing() const { | |
1140 // If this method has already thrown a range-check, | |
1141 // assume it was because we already tried range smearing | |
1142 // and it failed. | |
1143 uint already_trapped = trap_count(Deoptimization::Reason_range_check); | |
1144 return !already_trapped; | |
1145 } | |
1146 | |
1147 | |
1148 //------------------------------flatten_alias_type----------------------------- | |
1149 const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { | |
1150 int offset = tj->offset(); | |
1151 TypePtr::PTR ptr = tj->ptr(); | |
1152 | |
247 | 1153 // Known instance (scalarizable allocation) alias only with itself. |
1154 bool is_known_inst = tj->isa_oopptr() != NULL && | |
1155 tj->is_oopptr()->is_known_instance(); | |
1156 | |
0 | 1157 // Process weird unsafe references. |
1158 if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) { | |
1159 assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops"); | |
247 | 1160 assert(!is_known_inst, "scalarizable allocation should not have unsafe references"); |
0 | 1161 tj = TypeOopPtr::BOTTOM; |
1162 ptr = tj->ptr(); | |
1163 offset = tj->offset(); | |
1164 } | |
1165 | |
1166 // Array pointers need some flattening | |
1167 const TypeAryPtr *ta = tj->isa_aryptr(); | |
247 | 1168 if( ta && is_known_inst ) { |
1169 if ( offset != Type::OffsetBot && | |
1170 offset > arrayOopDesc::length_offset_in_bytes() ) { | |
1171 offset = Type::OffsetBot; // Flatten constant access into array body only | |
1172 tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id()); | |
1173 } | |
1174 } else if( ta && _AliasLevel >= 2 ) { | |
0 | 1175 // For arrays indexed by constant indices, we flatten the alias |
1176 // space to include all of the array body. Only the header, klass | |
1177 // and array length can be accessed un-aliased. | |
1178 if( offset != Type::OffsetBot ) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
1179 if( ta->const_oop() ) { // MethodData* or Method* |
0 | 1180 offset = Type::OffsetBot; // Flatten constant access into array body |
247 | 1181 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset); |
0 | 1182 } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { |
1183 // range is OK as-is. | |
1184 tj = ta = TypeAryPtr::RANGE; | |
1185 } else if( offset == oopDesc::klass_offset_in_bytes() ) { | |
1186 tj = TypeInstPtr::KLASS; // all klass loads look alike | |
1187 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1188 ptr = TypePtr::BotPTR; | |
1189 } else if( offset == oopDesc::mark_offset_in_bytes() ) { | |
1190 tj = TypeInstPtr::MARK; | |
1191 ta = TypeAryPtr::RANGE; // generic ignored junk | |
1192 ptr = TypePtr::BotPTR; | |
1193 } else { // Random constant offset into array body | |
1194 offset = Type::OffsetBot; // Flatten constant access into array body | |
247 | 1195 tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset); |
0 | 1196 } |
1197 } | |
1198 // Arrays of fixed size alias with arrays of unknown size. | |
1199 if (ta->size() != TypeInt::POS) { | |
1200 const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); | |
247 | 1201 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset); |
0 | 1202 } |
1203 // Arrays of known objects become arrays of unknown objects. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1204 if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1205 const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); |
247 | 1206 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1207 } |
0 | 1208 if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { |
1209 const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); | |
247 | 1210 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset); |
0 | 1211 } |
1212 // Arrays of bytes and of booleans both use 'bastore' and 'baload' so | |
1213 // cannot be distinguished by bytecode alone. | |
1214 if (ta->elem() == TypeInt::BOOL) { | |
1215 const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); | |
1216 ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); | |
247 | 1217 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); |
0 | 1218 } |
1219 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1220 // Make sure the Bottom and NotNull variants alias the same. | |
1221 // Also, make sure exact and non-exact variants alias the same. | |
1222 if( ptr == TypePtr::NotNull || ta->klass_is_exact() ) { | |
3789 | 1223 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset); |
0 | 1224 } |
1225 } | |
1226 | |
1227 // Oop pointers need some flattening | |
1228 const TypeInstPtr *to = tj->isa_instptr(); | |
1229 if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1230 ciInstanceKlass *k = to->klass()->as_instance_klass(); |
0 | 1231 if( ptr == TypePtr::Constant ) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1232 if (to->klass() != ciEnv::current()->Class_klass() || |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1233 offset < k->size_helper() * wordSize) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1234 // No constant oop pointers (such as Strings); they alias with |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1235 // unknown strings. |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1236 assert(!is_known_inst, "not scalarizable allocation"); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1237 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1238 } |
247 | 1239 } else if( is_known_inst ) { |
163 | 1240 tj = to; // Keep NotNull and klass_is_exact for instance type |
0 | 1241 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { |
1242 // During the 2nd round of IterGVN, NotNull castings are removed. | |
1243 // Make sure the Bottom and NotNull variants alias the same. | |
1244 // Also, make sure exact and non-exact variants alias the same. | |
247 | 1245 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); |
0 | 1246 } |
1247 // Canonicalize the holder of this field | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1248 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { |
0 | 1249 // First handle header references such as a LoadKlassNode, even if the |
1250 // object's klass is unloaded at compile time (4965979). | |
247 | 1251 if (!is_known_inst) { // Do it only for non-instance types |
1252 tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset); | |
1253 } | |
0 | 1254 } else if (offset < 0 || offset >= k->size_helper() * wordSize) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1255 // Static fields are in the space above the normal instance |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1256 // fields in the java.lang.Class instance. |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1257 if (to->klass() != ciEnv::current()->Class_klass()) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1258 to = NULL; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1259 tj = TypeOopPtr::BOTTOM; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1260 offset = tj->offset(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1261 } |
0 | 1262 } else { |
1263 ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset); | |
1264 if (!k->equals(canonical_holder) || tj->offset() != offset) { | |
247 | 1265 if( is_known_inst ) { |
1266 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id()); | |
1267 } else { | |
1268 tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset); | |
1269 } | |
0 | 1270 } |
1271 } | |
1272 } | |
1273 | |
1274 // Klass pointers to object array klasses need some flattening | |
1275 const TypeKlassPtr *tk = tj->isa_klassptr(); | |
1276 if( tk ) { | |
1277 // If we are referencing a field within a Klass, we need | |
1278 // to assume the worst case of an Object. Both exact and | |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1279 // inexact types must flatten to the same alias class so |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1280 // use NotNull as the PTR. |
0 | 1281 if ( offset == Type::OffsetBot || (offset >= 0 && (size_t)offset < sizeof(Klass)) ) { |
1282 | |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1283 tj = tk = TypeKlassPtr::make(TypePtr::NotNull, |
0 | 1284 TypeKlassPtr::OBJECT->klass(), |
1285 offset); | |
1286 } | |
1287 | |
1288 ciKlass* klass = tk->klass(); | |
1289 if( klass->is_obj_array_klass() ) { | |
1290 ciKlass* k = TypeAryPtr::OOPS->klass(); | |
1291 if( !k || !k->is_loaded() ) // Only fails for some -Xcomp runs | |
1292 k = TypeInstPtr::BOTTOM->klass(); | |
1293 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, k, offset ); | |
1294 } | |
1295 | |
1296 // Check for precise loads from the primary supertype array and force them | |
1297 // to the supertype cache alias index. Check for generic array loads from | |
1298 // the primary supertype array and also force them to the supertype cache | |
1299 // alias index. Since the same load can reach both, we need to merge | |
1300 // these 2 disparate memories into the same alias class. Since the | |
1301 // primary supertype array is read-only, there's no chance of confusion | |
1302 // where we bypass an array load and an array store. | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1303 int primary_supers_offset = in_bytes(Klass::primary_supers_offset()); |
4760
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1304 if (offset == Type::OffsetBot || |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1305 (offset >= primary_supers_offset && |
669f6a7d5b70
7121073: secondary_super_cache memory slice has incorrect bounds in flatten_alias_type
never
parents:
4115
diff
changeset
|
1306 offset < (int)(primary_supers_offset + Klass::primary_super_limit() * wordSize)) || |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1307 offset == (int)in_bytes(Klass::secondary_super_cache_offset())) { |
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1308 offset = in_bytes(Klass::secondary_super_cache_offset()); |
0 | 1309 tj = tk = TypeKlassPtr::make( TypePtr::NotNull, tk->klass(), offset ); |
1310 } | |
1311 } | |
1312 | |
1313 // Flatten all Raw pointers together. | |
1314 if (tj->base() == Type::RawPtr) | |
1315 tj = TypeRawPtr::BOTTOM; | |
1316 | |
1317 if (tj->base() == Type::AnyPtr) | |
1318 tj = TypePtr::BOTTOM; // An error, which the caller must check for. | |
1319 | |
1320 // Flatten all to bottom for now | |
1321 switch( _AliasLevel ) { | |
1322 case 0: | |
1323 tj = TypePtr::BOTTOM; | |
1324 break; | |
1325 case 1: // Flatten to: oop, static, field or array | |
1326 switch (tj->base()) { | |
1327 //case Type::AryPtr: tj = TypeAryPtr::RANGE; break; | |
1328 case Type::RawPtr: tj = TypeRawPtr::BOTTOM; break; | |
1329 case Type::AryPtr: // do not distinguish arrays at all | |
1330 case Type::InstPtr: tj = TypeInstPtr::BOTTOM; break; | |
1331 case Type::KlassPtr: tj = TypeKlassPtr::OBJECT; break; | |
1332 case Type::AnyPtr: tj = TypePtr::BOTTOM; break; // caller checks it | |
1333 default: ShouldNotReachHere(); | |
1334 } | |
1335 break; | |
605 | 1336 case 2: // No collapsing at level 2; keep all splits |
1337 case 3: // No collapsing at level 3; keep all splits | |
0 | 1338 break; |
1339 default: | |
1340 Unimplemented(); | |
1341 } | |
1342 | |
1343 offset = tj->offset(); | |
1344 assert( offset != Type::OffsetTop, "Offset has fallen from constant" ); | |
1345 | |
1346 assert( (offset != Type::OffsetBot && tj->base() != Type::AryPtr) || | |
1347 (offset == Type::OffsetBot && tj->base() == Type::AryPtr) || | |
1348 (offset == Type::OffsetBot && tj == TypeOopPtr::BOTTOM) || | |
1349 (offset == Type::OffsetBot && tj == TypePtr::BOTTOM) || | |
1350 (offset == oopDesc::mark_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1351 (offset == oopDesc::klass_offset_in_bytes() && tj->base() == Type::AryPtr) || | |
1352 (offset == arrayOopDesc::length_offset_in_bytes() && tj->base() == Type::AryPtr) , | |
1353 "For oops, klasses, raw offset must be constant; for arrays the offset is never known" ); | |
1354 assert( tj->ptr() != TypePtr::TopPTR && | |
1355 tj->ptr() != TypePtr::AnyNull && | |
1356 tj->ptr() != TypePtr::Null, "No imprecise addresses" ); | |
1357 // assert( tj->ptr() != TypePtr::Constant || | |
1358 // tj->base() == Type::RawPtr || | |
1359 // tj->base() == Type::KlassPtr, "No constant oop addresses" ); | |
1360 | |
1361 return tj; | |
1362 } | |
1363 | |
1364 void Compile::AliasType::Init(int i, const TypePtr* at) { | |
1365 _index = i; | |
1366 _adr_type = at; | |
1367 _field = NULL; | |
1368 _is_rewritable = true; // default | |
1369 const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; | |
223 | 1370 if (atoop != NULL && atoop->is_known_instance()) { |
1371 const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot); | |
0 | 1372 _general_index = Compile::current()->get_alias_index(gt); |
1373 } else { | |
1374 _general_index = 0; | |
1375 } | |
1376 } | |
1377 | |
1378 //---------------------------------print_on------------------------------------ | |
1379 #ifndef PRODUCT | |
1380 void Compile::AliasType::print_on(outputStream* st) { | |
1381 if (index() < 10) | |
1382 st->print("@ <%d> ", index()); | |
1383 else st->print("@ <%d>", index()); | |
1384 st->print(is_rewritable() ? " " : " RO"); | |
1385 int offset = adr_type()->offset(); | |
1386 if (offset == Type::OffsetBot) | |
1387 st->print(" +any"); | |
1388 else st->print(" +%-3d", offset); | |
1389 st->print(" in "); | |
1390 adr_type()->dump_on(st); | |
1391 const TypeOopPtr* tjp = adr_type()->isa_oopptr(); | |
1392 if (field() != NULL && tjp) { | |
1393 if (tjp->klass() != field()->holder() || | |
1394 tjp->offset() != field()->offset_in_bytes()) { | |
1395 st->print(" != "); | |
1396 field()->print(); | |
1397 st->print(" ***"); | |
1398 } | |
1399 } | |
1400 } | |
1401 | |
1402 void print_alias_types() { | |
1403 Compile* C = Compile::current(); | |
1404 tty->print_cr("--- Alias types, AliasIdxBot .. %d", C->num_alias_types()-1); | |
1405 for (int idx = Compile::AliasIdxBot; idx < C->num_alias_types(); idx++) { | |
1406 C->alias_type(idx)->print_on(tty); | |
1407 tty->cr(); | |
1408 } | |
1409 } | |
1410 #endif | |
1411 | |
1412 | |
1413 //----------------------------probe_alias_cache-------------------------------- | |
1414 Compile::AliasCacheEntry* Compile::probe_alias_cache(const TypePtr* adr_type) { | |
1415 intptr_t key = (intptr_t) adr_type; | |
1416 key ^= key >> logAliasCacheSize; | |
1417 return &_alias_cache[key & right_n_bits(logAliasCacheSize)]; | |
1418 } | |
1419 | |
1420 | |
1421 //-----------------------------grow_alias_types-------------------------------- | |
1422 void Compile::grow_alias_types() { | |
1423 const int old_ats = _max_alias_types; // how many before? | |
1424 const int new_ats = old_ats; // how many more? | |
1425 const int grow_ats = old_ats+new_ats; // how many now? | |
1426 _max_alias_types = grow_ats; | |
1427 _alias_types = REALLOC_ARENA_ARRAY(comp_arena(), AliasType*, _alias_types, old_ats, grow_ats); | |
1428 AliasType* ats = NEW_ARENA_ARRAY(comp_arena(), AliasType, new_ats); | |
1429 Copy::zero_to_bytes(ats, sizeof(AliasType)*new_ats); | |
1430 for (int i = 0; i < new_ats; i++) _alias_types[old_ats+i] = &ats[i]; | |
1431 } | |
1432 | |
1433 | |
1434 //--------------------------------find_alias_type------------------------------ | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1435 Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create, ciField* original_field) { |
0 | 1436 if (_AliasLevel == 0) |
1437 return alias_type(AliasIdxBot); | |
1438 | |
1439 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1440 if (ace->_adr_type == adr_type) { | |
1441 return alias_type(ace->_index); | |
1442 } | |
1443 | |
1444 // Handle special cases. | |
1445 if (adr_type == NULL) return alias_type(AliasIdxTop); | |
1446 if (adr_type == TypePtr::BOTTOM) return alias_type(AliasIdxBot); | |
1447 | |
1448 // Do it the slow way. | |
1449 const TypePtr* flat = flatten_alias_type(adr_type); | |
1450 | |
1451 #ifdef ASSERT | |
1452 assert(flat == flatten_alias_type(flat), "idempotent"); | |
1453 assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr"); | |
1454 if (flat->isa_oopptr() && !flat->isa_klassptr()) { | |
1455 const TypeOopPtr* foop = flat->is_oopptr(); | |
247 | 1456 // Scalarizable allocations have exact klass always. |
1457 bool exact = !foop->klass_is_exact() || foop->is_known_instance(); | |
1458 const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr(); | |
0 | 1459 assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type"); |
1460 } | |
1461 assert(flat == flatten_alias_type(flat), "exact bit doesn't matter"); | |
1462 #endif | |
1463 | |
1464 int idx = AliasIdxTop; | |
1465 for (int i = 0; i < num_alias_types(); i++) { | |
1466 if (alias_type(i)->adr_type() == flat) { | |
1467 idx = i; | |
1468 break; | |
1469 } | |
1470 } | |
1471 | |
1472 if (idx == AliasIdxTop) { | |
1473 if (no_create) return NULL; | |
1474 // Grow the array if necessary. | |
1475 if (_num_alias_types == _max_alias_types) grow_alias_types(); | |
1476 // Add a new alias type. | |
1477 idx = _num_alias_types++; | |
1478 _alias_types[idx]->Init(idx, flat); | |
1479 if (flat == TypeInstPtr::KLASS) alias_type(idx)->set_rewritable(false); | |
1480 if (flat == TypeAryPtr::RANGE) alias_type(idx)->set_rewritable(false); | |
1481 if (flat->isa_instptr()) { | |
1482 if (flat->offset() == java_lang_Class::klass_offset_in_bytes() | |
1483 && flat->is_instptr()->klass() == env()->Class_klass()) | |
1484 alias_type(idx)->set_rewritable(false); | |
1485 } | |
1486 if (flat->isa_klassptr()) { | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1487 if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) |
0 | 1488 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1489 if (flat->offset() == in_bytes(Klass::modifier_flags_offset())) |
0 | 1490 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1491 if (flat->offset() == in_bytes(Klass::access_flags_offset())) |
0 | 1492 alias_type(idx)->set_rewritable(false); |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4760
diff
changeset
|
1493 if (flat->offset() == in_bytes(Klass::java_mirror_offset())) |
0 | 1494 alias_type(idx)->set_rewritable(false); |
1495 } | |
1496 // %%% (We would like to finalize JavaThread::threadObj_offset(), | |
1497 // but the base pointer type is not distinctive enough to identify | |
1498 // references into JavaThread.) | |
1499 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1500 // Check for final fields. |
0 | 1501 const TypeInstPtr* tinst = flat->isa_instptr(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1502 if (tinst && tinst->offset() >= instanceOopDesc::base_offset_in_bytes()) { |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1503 ciField* field; |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1504 if (tinst->const_oop() != NULL && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1505 tinst->klass() == ciEnv::current()->Class_klass() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1506 tinst->offset() >= (tinst->klass()->as_instance_klass()->size_helper() * wordSize)) { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1507 // static field |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1508 ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1509 field = k->get_field_by_offset(tinst->offset(), true); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1510 } else { |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1511 ciInstanceKlass *k = tinst->klass()->as_instance_klass(); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1512 field = k->get_field_by_offset(tinst->offset(), false); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1513 } |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1514 assert(field == NULL || |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1515 original_field == NULL || |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1516 (field->holder() == original_field->holder() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1517 field->offset() == original_field->offset() && |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1518 field->is_static() == original_field->is_static()), "wrong field?"); |
0 | 1519 // Set field() and is_rewritable() attributes. |
1520 if (field != NULL) alias_type(idx)->set_field(field); | |
1521 } | |
1522 } | |
1523 | |
1524 // Fill the cache for next time. | |
1525 ace->_adr_type = adr_type; | |
1526 ace->_index = idx; | |
1527 assert(alias_type(adr_type) == alias_type(idx), "type must be installed"); | |
1528 | |
1529 // Might as well try to fill the cache for the flattened version, too. | |
1530 AliasCacheEntry* face = probe_alias_cache(flat); | |
1531 if (face->_adr_type == NULL) { | |
1532 face->_adr_type = flat; | |
1533 face->_index = idx; | |
1534 assert(alias_type(flat) == alias_type(idx), "flat type must work too"); | |
1535 } | |
1536 | |
1537 return alias_type(idx); | |
1538 } | |
1539 | |
1540 | |
1541 Compile::AliasType* Compile::alias_type(ciField* field) { | |
1542 const TypeOopPtr* t; | |
1543 if (field->is_static()) | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1544 t = TypeInstPtr::make(field->holder()->java_mirror()); |
0 | 1545 else |
1546 t = TypeOopPtr::make_from_klass_raw(field->holder()); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1547 AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field); |
0 | 1548 assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); |
1549 return atp; | |
1550 } | |
1551 | |
1552 | |
1553 //------------------------------have_alias_type-------------------------------- | |
1554 bool Compile::have_alias_type(const TypePtr* adr_type) { | |
1555 AliasCacheEntry* ace = probe_alias_cache(adr_type); | |
1556 if (ace->_adr_type == adr_type) { | |
1557 return true; | |
1558 } | |
1559 | |
1560 // Handle special cases. | |
1561 if (adr_type == NULL) return true; | |
1562 if (adr_type == TypePtr::BOTTOM) return true; | |
1563 | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2192
diff
changeset
|
1564 return find_alias_type(adr_type, true, NULL) != NULL; |
0 | 1565 } |
1566 | |
1567 //-----------------------------must_alias-------------------------------------- | |
1568 // True if all values of the given address type are in the given alias category. | |
1569 bool Compile::must_alias(const TypePtr* adr_type, int alias_idx) { | |
1570 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1571 if (adr_type == NULL) return true; // NULL serves as TypePtr::TOP | |
1572 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1573 if (adr_type->base() == Type::AnyPtr) return false; // TypePtr::BOTTOM or its twins | |
1574 | |
1575 // the only remaining possible overlap is identity | |
1576 int adr_idx = get_alias_index(adr_type); | |
1577 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1578 assert(adr_idx == alias_idx || | |
1579 (alias_type(alias_idx)->adr_type() != TypeOopPtr::BOTTOM | |
1580 && adr_type != TypeOopPtr::BOTTOM), | |
1581 "should not be testing for overlap with an unsafe pointer"); | |
1582 return adr_idx == alias_idx; | |
1583 } | |
1584 | |
1585 //------------------------------can_alias-------------------------------------- | |
1586 // True if any values of the given address type are in the given alias category. | |
1587 bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) { | |
1588 if (alias_idx == AliasIdxTop) return false; // the empty category | |
1589 if (adr_type == NULL) return false; // NULL serves as TypePtr::TOP | |
1590 if (alias_idx == AliasIdxBot) return true; // the universal category | |
1591 if (adr_type->base() == Type::AnyPtr) return true; // TypePtr::BOTTOM or its twins | |
1592 | |
1593 // the only remaining possible overlap is identity | |
1594 int adr_idx = get_alias_index(adr_type); | |
1595 assert(adr_idx != AliasIdxBot && adr_idx != AliasIdxTop, ""); | |
1596 return adr_idx == alias_idx; | |
1597 } | |
1598 | |
1599 | |
1600 | |
1601 //---------------------------pop_warm_call------------------------------------- | |
1602 WarmCallInfo* Compile::pop_warm_call() { | |
1603 WarmCallInfo* wci = _warm_calls; | |
1604 if (wci != NULL) _warm_calls = wci->remove_from(wci); | |
1605 return wci; | |
1606 } | |
1607 | |
1608 //----------------------------Inline_Warm-------------------------------------- | |
1609 int Compile::Inline_Warm() { | |
1610 // If there is room, try to inline some more warm call sites. | |
1611 // %%% Do a graph index compaction pass when we think we're out of space? | |
1612 if (!InlineWarmCalls) return 0; | |
1613 | |
1614 int calls_made_hot = 0; | |
1615 int room_to_grow = NodeCountInliningCutoff - unique(); | |
1616 int amount_to_grow = MIN2(room_to_grow, (int)NodeCountInliningStep); | |
1617 int amount_grown = 0; | |
1618 WarmCallInfo* call; | |
1619 while (amount_to_grow > 0 && (call = pop_warm_call()) != NULL) { | |
1620 int est_size = (int)call->size(); | |
1621 if (est_size > (room_to_grow - amount_grown)) { | |
1622 // This one won't fit anyway. Get rid of it. | |
1623 call->make_cold(); | |
1624 continue; | |
1625 } | |
1626 call->make_hot(); | |
1627 calls_made_hot++; | |
1628 amount_grown += est_size; | |
1629 amount_to_grow -= est_size; | |
1630 } | |
1631 | |
1632 if (calls_made_hot > 0) set_major_progress(); | |
1633 return calls_made_hot; | |
1634 } | |
1635 | |
1636 | |
1637 //----------------------------Finish_Warm-------------------------------------- | |
1638 void Compile::Finish_Warm() { | |
1639 if (!InlineWarmCalls) return; | |
1640 if (failing()) return; | |
1641 if (warm_calls() == NULL) return; | |
1642 | |
1643 // Clean up loose ends, if we are out of space for inlining. | |
1644 WarmCallInfo* call; | |
1645 while ((call = pop_warm_call()) != NULL) { | |
1646 call->make_cold(); | |
1647 } | |
1648 } | |
1649 | |
1172 | 1650 //---------------------cleanup_loop_predicates----------------------- |
1651 // Remove the opaque nodes that protect the predicates so that all unused | |
1652 // checks and uncommon_traps will be eliminated from the ideal graph | |
1653 void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) { | |
1654 if (predicate_count()==0) return; | |
1655 for (int i = predicate_count(); i > 0; i--) { | |
1656 Node * n = predicate_opaque1_node(i-1); | |
1657 assert(n->Opcode() == Op_Opaque1, "must be"); | |
1658 igvn.replace_node(n, n->in(1)); | |
1659 } | |
1660 assert(predicate_count()==0, "should be clean!"); | |
1661 } | |
0 | 1662 |
1663 //------------------------------Optimize--------------------------------------- | |
1664 // Given a graph, optimize it. | |
1665 void Compile::Optimize() { | |
1666 TracePhase t1("optimizer", &_t_optimizer, true); | |
1667 | |
1668 #ifndef PRODUCT | |
1669 if (env()->break_at_compile()) { | |
1670 BREAKPOINT; | |
1671 } | |
1672 | |
1673 #endif | |
1674 | |
1675 ResourceMark rm; | |
1676 int loop_opts_cnt; | |
1677 | |
1678 NOT_PRODUCT( verify_graph_edges(); ) | |
1679 | |
222 | 1680 print_method("After Parsing"); |
0 | 1681 |
1682 { | |
1683 // Iterative Global Value Numbering, including ideal transforms | |
1684 // Initialize IterGVN with types and values from parse-time GVN | |
1685 PhaseIterGVN igvn(initial_gvn()); | |
1686 { | |
1687 NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) | |
1688 igvn.optimize(); | |
1689 } | |
1690 | |
1691 print_method("Iter GVN 1", 2); | |
1692 | |
1693 if (failing()) return; | |
1694 | |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1695 // Perform escape analysis |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1696 if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) { |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1697 if (has_loops()) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1698 // Cleanup graph (remove dead nodes). |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1699 TracePhase t2("idealLoop", &_t_idealLoop, true); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1700 PhaseIdealLoop ideal_loop( igvn, false, true ); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1701 if (major_progress()) print_method("PhaseIdealLoop before EA", 2); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1702 if (failing()) return; |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1703 } |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1704 ConnectionGraph::do_analysis(this, &igvn); |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1705 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1706 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1707 |
4115 | 1708 // Optimize out fields loads from scalar replaceable allocations. |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1709 igvn.optimize(); |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3899
diff
changeset
|
1710 print_method("Iter GVN after EA", 2); |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1711 |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1712 if (failing()) return; |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1713 |
4115 | 1714 if (congraph() != NULL && macro_count() > 0) { |
5948
ee138854b3a6
7147744: CTW: assert(false) failed: infinite EA connection graph build
kvn
parents:
4767
diff
changeset
|
1715 NOT_PRODUCT( TracePhase t2("macroEliminate", &_t_macroEliminate, TimeCompiler); ) |
4115 | 1716 PhaseMacroExpand mexp(igvn); |
1717 mexp.eliminate_macro_nodes(); | |
1718 igvn.set_delay_transform(false); | |
1719 | |
1720 igvn.optimize(); | |
1721 print_method("Iter GVN after eliminating allocations and locks", 2); | |
1722 | |
1723 if (failing()) return; | |
1724 } | |
1634
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1725 } |
60a14ad85270
6966411: escape.cpp:450 assert(base->Opcode() == Op_ConP
kvn
parents:
1609
diff
changeset
|
1726 |
0 | 1727 // Loop transforms on the ideal graph. Range Check Elimination, |
1728 // peeling, unrolling, etc. | |
1729 | |
1730 // Set loop opts counter | |
1731 loop_opts_cnt = num_loop_opts(); | |
1732 if((loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { | |
1733 { | |
1734 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
2445 | 1735 PhaseIdealLoop ideal_loop( igvn, true ); |
0 | 1736 loop_opts_cnt--; |
1737 if (major_progress()) print_method("PhaseIdealLoop 1", 2); | |
1738 if (failing()) return; | |
1739 } | |
1740 // Loop opts pass if partial peeling occurred in previous pass | |
1741 if(PartialPeelLoop && major_progress() && (loop_opts_cnt > 0)) { | |
1742 TracePhase t3("idealLoop", &_t_idealLoop, true); | |
2445 | 1743 PhaseIdealLoop ideal_loop( igvn, false ); |
0 | 1744 loop_opts_cnt--; |
1745 if (major_progress()) print_method("PhaseIdealLoop 2", 2); | |
1746 if (failing()) return; | |
1747 } | |
1748 // Loop opts pass for loop-unrolling before CCP | |
1749 if(major_progress() && (loop_opts_cnt > 0)) { | |
1750 TracePhase t4("idealLoop", &_t_idealLoop, true); | |
2445 | 1751 PhaseIdealLoop ideal_loop( igvn, false ); |
0 | 1752 loop_opts_cnt--; |
1753 if (major_progress()) print_method("PhaseIdealLoop 3", 2); | |
1754 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1755 if (!failing()) { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1756 // Verify that last round of loop opts produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1757 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1758 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1759 } |
0 | 1760 } |
1761 if (failing()) return; | |
1762 | |
1763 // Conditional Constant Propagation; | |
1764 PhaseCCP ccp( &igvn ); | |
1765 assert( true, "Break here to ccp.dump_nodes_and_types(_root,999,1)"); | |
1766 { | |
1767 TracePhase t2("ccp", &_t_ccp, true); | |
1768 ccp.do_transform(); | |
1769 } | |
1770 print_method("PhaseCPP 1", 2); | |
1771 | |
1772 assert( true, "Break here to ccp.dump_old2new_map()"); | |
1773 | |
1774 // Iterative Global Value Numbering, including ideal transforms | |
1775 { | |
1776 NOT_PRODUCT( TracePhase t2("iterGVN2", &_t_iterGVN2, TimeCompiler); ) | |
1777 igvn = ccp; | |
1778 igvn.optimize(); | |
1779 } | |
1780 | |
1781 print_method("Iter GVN 2", 2); | |
1782 | |
1783 if (failing()) return; | |
1784 | |
1785 // Loop transforms on the ideal graph. Range Check Elimination, | |
1786 // peeling, unrolling, etc. | |
1787 if(loop_opts_cnt > 0) { | |
1788 debug_only( int cnt = 0; ); | |
1789 while(major_progress() && (loop_opts_cnt > 0)) { | |
1790 TracePhase t2("idealLoop", &_t_idealLoop, true); | |
1791 assert( cnt++ < 40, "infinite cycle in loop optimization" ); | |
2445 | 1792 PhaseIdealLoop ideal_loop( igvn, true); |
0 | 1793 loop_opts_cnt--; |
1794 if (major_progress()) print_method("PhaseIdealLoop iterations", 2); | |
1795 if (failing()) return; | |
1796 } | |
1797 } | |
921
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1798 |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1799 { |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1800 // Verify that all previous optimizations produced a valid graph |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1801 // at least to this point, even if no loop optimizations were done. |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1802 NOT_PRODUCT( TracePhase t2("idealLoopVerify", &_t_idealLoopVerify, TimeCompiler); ) |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1803 PhaseIdealLoop::verify(igvn); |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1804 } |
046932b72aa2
6862956: PhaseIdealLoop should have a CFG verification mode
never
parents:
859
diff
changeset
|
1805 |
0 | 1806 { |
1807 NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); ) | |
1808 PhaseMacroExpand mex(igvn); | |
1809 if (mex.expand_macro_nodes()) { | |
1810 assert(failing(), "must bail out w/ explicit message"); | |
1811 return; | |
1812 } | |
1813 } | |
1814 | |
1815 } // (End scope of igvn; run destructor if necessary for asserts.) | |
1816 | |
1817 // A method with only infinite loops has no edges entering loops from root | |
1818 { | |
1819 NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); ) | |
1820 if (final_graph_reshaping()) { | |
1821 assert(failing(), "must bail out w/ explicit message"); | |
1822 return; | |
1823 } | |
1824 } | |
1825 | |
1826 print_method("Optimize finished", 2); | |
1827 } | |
1828 | |
1829 | |
1830 //------------------------------Code_Gen--------------------------------------- | |
1831 // Given a graph, generate code for it | |
1832 void Compile::Code_Gen() { | |
1833 if (failing()) return; | |
1834 | |
1835 // Perform instruction selection. You might think we could reclaim Matcher | |
1836 // memory PDQ, but actually the Matcher is used in generating spill code. | |
1837 // Internals of the Matcher (including some VectorSets) must remain live | |
1838 // for awhile - thus I cannot reclaim Matcher memory lest a VectorSet usage | |
1839 // set a bit in reclaimed memory. | |
1840 | |
1841 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1842 // nodes. Mapping is only valid at the root of each matched subtree. | |
1843 NOT_PRODUCT( verify_graph_edges(); ) | |
1844 | |
1845 Node_List proj_list; | |
1846 Matcher m(proj_list); | |
1847 _matcher = &m; | |
1848 { | |
1849 TracePhase t2("matcher", &_t_matcher, true); | |
1850 m.match(); | |
1851 } | |
1852 // In debug mode can dump m._nodes.dump() for mapping of ideal to machine | |
1853 // nodes. Mapping is only valid at the root of each matched subtree. | |
1854 NOT_PRODUCT( verify_graph_edges(); ) | |
1855 | |
1856 // If you have too many nodes, or if matching has failed, bail out | |
1857 check_node_count(0, "out of nodes matching instructions"); | |
1858 if (failing()) return; | |
1859 | |
1860 // Build a proper-looking CFG | |
1861 PhaseCFG cfg(node_arena(), root(), m); | |
1862 _cfg = &cfg; | |
1863 { | |
1864 NOT_PRODUCT( TracePhase t2("scheduler", &_t_scheduler, TimeCompiler); ) | |
1865 cfg.Dominators(); | |
1866 if (failing()) return; | |
1867 | |
1868 NOT_PRODUCT( verify_graph_edges(); ) | |
1869 | |
1870 cfg.Estimate_Block_Frequency(); | |
1871 cfg.GlobalCodeMotion(m,unique(),proj_list); | |
5951 | 1872 if (failing()) return; |
0 | 1873 |
1874 print_method("Global code motion", 2); | |
1875 | |
1876 NOT_PRODUCT( verify_graph_edges(); ) | |
1877 | |
1878 debug_only( cfg.verify(); ) | |
1879 } | |
1880 NOT_PRODUCT( verify_graph_edges(); ) | |
1881 | |
1882 PhaseChaitin regalloc(unique(),cfg,m); | |
1883 _regalloc = ®alloc; | |
1884 { | |
1885 TracePhase t2("regalloc", &_t_registerAllocation, true); | |
1886 // Perform any platform dependent preallocation actions. This is used, | |
1887 // for example, to avoid taking an implicit null pointer exception | |
1888 // using the frame pointer on win95. | |
1889 _regalloc->pd_preallocate_hook(); | |
1890 | |
1891 // Perform register allocation. After Chaitin, use-def chains are | |
1892 // no longer accurate (at spill code) and so must be ignored. | |
1893 // Node->LRG->reg mappings are still accurate. | |
1894 _regalloc->Register_Allocate(); | |
1895 | |
1896 // Bail out if the allocator builds too many nodes | |
1897 if (failing()) return; | |
1898 } | |
1899 | |
1900 // Prior to register allocation we kept empty basic blocks in case the | |
1901 // the allocator needed a place to spill. After register allocation we | |
1902 // are not adding any new instructions. If any basic block is empty, we | |
1903 // can now safely remove it. | |
1904 { | |
418 | 1905 NOT_PRODUCT( TracePhase t2("blockOrdering", &_t_blockOrdering, TimeCompiler); ) |
1906 cfg.remove_empty(); | |
1907 if (do_freq_based_layout()) { | |
1908 PhaseBlockLayout layout(cfg); | |
1909 } else { | |
1910 cfg.set_loop_alignment(); | |
1911 } | |
1912 cfg.fixup_flow(); | |
0 | 1913 } |
1914 | |
1915 // Perform any platform dependent postallocation verifications. | |
1916 debug_only( _regalloc->pd_postallocate_verify_hook(); ) | |
1917 | |
1918 // Apply peephole optimizations | |
1919 if( OptoPeephole ) { | |
1920 NOT_PRODUCT( TracePhase t2("peephole", &_t_peephole, TimeCompiler); ) | |
1921 PhasePeephole peep( _regalloc, cfg); | |
1922 peep.do_transform(); | |
1923 } | |
1924 | |
1925 // Convert Nodes to instruction bits in a buffer | |
1926 { | |
1927 // %%%% workspace merge brought two timers together for one job | |
1928 TracePhase t2a("output", &_t_output, true); | |
1929 NOT_PRODUCT( TraceTime t2b(NULL, &_t_codeGeneration, TimeCompiler, false); ) | |
1930 Output(); | |
1931 } | |
1932 | |
222 | 1933 print_method("Final Code"); |
0 | 1934 |
1935 // He's dead, Jim. | |
1936 _cfg = (PhaseCFG*)0xdeadbeef; | |
1937 _regalloc = (PhaseChaitin*)0xdeadbeef; | |
1938 } | |
1939 | |
1940 | |
1941 //------------------------------dump_asm--------------------------------------- | |
1942 // Dump formatted assembly | |
1943 #ifndef PRODUCT | |
1944 void Compile::dump_asm(int *pcs, uint pc_limit) { | |
1945 bool cut_short = false; | |
1946 tty->print_cr("#"); | |
1947 tty->print("# "); _tf->dump(); tty->cr(); | |
1948 tty->print_cr("#"); | |
1949 | |
1950 // For all blocks | |
1951 int pc = 0x0; // Program counter | |
1952 char starts_bundle = ' '; | |
1953 _regalloc->dump_frame(); | |
1954 | |
1955 Node *n = NULL; | |
1956 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | |
1957 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1958 Block *b = _cfg->_blocks[i]; | |
1959 if (b->is_connector() && !Verbose) continue; | |
1960 n = b->_nodes[0]; | |
1961 if (pcs && n->_idx < pc_limit) | |
1962 tty->print("%3.3x ", pcs[n->_idx]); | |
1963 else | |
1964 tty->print(" "); | |
1965 b->dump_head( &_cfg->_bbs ); | |
1966 if (b->is_connector()) { | |
1967 tty->print_cr(" # Empty connector block"); | |
1968 } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) { | |
1969 tty->print_cr(" # Block is sole successor of call"); | |
1970 } | |
1971 | |
1972 // For all instructions | |
1973 Node *delay = NULL; | |
1974 for( uint j = 0; j<b->_nodes.size(); j++ ) { | |
1975 if (VMThread::should_terminate()) { cut_short = true; break; } | |
1976 n = b->_nodes[j]; | |
1977 if (valid_bundle_info(n)) { | |
1978 Bundle *bundle = node_bundling(n); | |
1979 if (bundle->used_in_unconditional_delay()) { | |
1980 delay = n; | |
1981 continue; | |
1982 } | |
1983 if (bundle->starts_bundle()) | |
1984 starts_bundle = '+'; | |
1985 } | |
1986 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1987 if (WizardMode) n->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
1988 |
0 | 1989 if( !n->is_Region() && // Dont print in the Assembly |
1990 !n->is_Phi() && // a few noisely useless nodes | |
1991 !n->is_Proj() && | |
1992 !n->is_MachTemp() && | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
1993 !n->is_SafePointScalarObject() && |
0 | 1994 !n->is_Catch() && // Would be nice to print exception table targets |
1995 !n->is_MergeMem() && // Not very interesting | |
1996 !n->is_top() && // Debug info table constants | |
1997 !(n->is_Con() && !n->is_Mach())// Debug info table constants | |
1998 ) { | |
1999 if (pcs && n->_idx < pc_limit) | |
2000 tty->print("%3.3x", pcs[n->_idx]); | |
2001 else | |
2002 tty->print(" "); | |
2003 tty->print(" %c ", starts_bundle); | |
2004 starts_bundle = ' '; | |
2005 tty->print("\t"); | |
2006 n->format(_regalloc, tty); | |
2007 tty->cr(); | |
2008 } | |
2009 | |
2010 // If we have an instruction with a delay slot, and have seen a delay, | |
2011 // then back up and print it | |
2012 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { | |
2013 assert(delay != NULL, "no unconditional delay instruction"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2014 if (WizardMode) delay->dump(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2015 |
0 | 2016 if (node_bundling(delay)->starts_bundle()) |
2017 starts_bundle = '+'; | |
2018 if (pcs && n->_idx < pc_limit) | |
2019 tty->print("%3.3x", pcs[n->_idx]); | |
2020 else | |
2021 tty->print(" "); | |
2022 tty->print(" %c ", starts_bundle); | |
2023 starts_bundle = ' '; | |
2024 tty->print("\t"); | |
2025 delay->format(_regalloc, tty); | |
2026 tty->print_cr(""); | |
2027 delay = NULL; | |
2028 } | |
2029 | |
2030 // Dump the exception table as well | |
2031 if( n->is_Catch() && (Verbose || WizardMode) ) { | |
2032 // Print the exception table for this offset | |
2033 _handler_table.print_subtable_for(pc); | |
2034 } | |
2035 } | |
2036 | |
2037 if (pcs && n->_idx < pc_limit) | |
2038 tty->print_cr("%3.3x", pcs[n->_idx]); | |
2039 else | |
2040 tty->print_cr(""); | |
2041 | |
2042 assert(cut_short || delay == NULL, "no unconditional delay branch"); | |
2043 | |
2044 } // End of per-block dump | |
2045 tty->print_cr(""); | |
2046 | |
2047 if (cut_short) tty->print_cr("*** disassembly is cut short ***"); | |
2048 } | |
2049 #endif | |
2050 | |
2051 //------------------------------Final_Reshape_Counts--------------------------- | |
2052 // This class defines counters to help identify when a method | |
2053 // may/must be executed using hardware with only 24-bit precision. | |
2054 struct Final_Reshape_Counts : public StackObj { | |
2055 int _call_count; // count non-inlined 'common' calls | |
2056 int _float_count; // count float ops requiring 24-bit precision | |
2057 int _double_count; // count double ops requiring more precision | |
2058 int _java_call_count; // count non-inlined 'java' calls | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2059 int _inner_loop_count; // count loops which need alignment |
0 | 2060 VectorSet _visited; // Visitation flags |
2061 Node_List _tests; // Set of IfNodes & PCTableNodes | |
2062 | |
2063 Final_Reshape_Counts() : | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2064 _call_count(0), _float_count(0), _double_count(0), |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2065 _java_call_count(0), _inner_loop_count(0), |
0 | 2066 _visited( Thread::current()->resource_area() ) { } |
2067 | |
2068 void inc_call_count () { _call_count ++; } | |
2069 void inc_float_count () { _float_count ++; } | |
2070 void inc_double_count() { _double_count++; } | |
2071 void inc_java_call_count() { _java_call_count++; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2072 void inc_inner_loop_count() { _inner_loop_count++; } |
0 | 2073 |
2074 int get_call_count () const { return _call_count ; } | |
2075 int get_float_count () const { return _float_count ; } | |
2076 int get_double_count() const { return _double_count; } | |
2077 int get_java_call_count() const { return _java_call_count; } | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2078 int get_inner_loop_count() const { return _inner_loop_count; } |
0 | 2079 }; |
2080 | |
2081 static bool oop_offset_is_sane(const TypeInstPtr* tp) { | |
2082 ciInstanceKlass *k = tp->klass()->as_instance_klass(); | |
2083 // Make sure the offset goes inside the instance layout. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2084 return k->contains_field_offset(tp->offset()); |
0 | 2085 // Note that OffsetBot and OffsetTop are very negative. |
2086 } | |
2087 | |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2088 // Eliminate trivially redundant StoreCMs and accumulate their |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2089 // precedence edges. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2090 static void eliminate_redundant_card_marks(Node* n) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2091 assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2092 if (n->in(MemNode::Address)->outcnt() > 1) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2093 // There are multiple users of the same address so it might be |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2094 // possible to eliminate some of the StoreCMs |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2095 Node* mem = n->in(MemNode::Memory); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2096 Node* adr = n->in(MemNode::Address); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2097 Node* val = n->in(MemNode::ValueIn); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2098 Node* prev = n; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2099 bool done = false; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2100 // Walk the chain of StoreCMs eliminating ones that match. As |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2101 // long as it's a chain of single users then the optimization is |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2102 // safe. Eliminating partially redundant StoreCMs would require |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2103 // cloning copies down the other paths. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2104 while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2105 if (adr == mem->in(MemNode::Address) && |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2106 val == mem->in(MemNode::ValueIn)) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2107 // redundant StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2108 if (mem->req() > MemNode::OopStore) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2109 // Hasn't been processed by this code yet. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2110 n->add_prec(mem->in(MemNode::OopStore)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2111 } else { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2112 // Already converted to precedence edge |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2113 for (uint i = mem->req(); i < mem->len(); i++) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2114 // Accumulate any precedence edges |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2115 if (mem->in(i) != NULL) { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2116 n->add_prec(mem->in(i)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2117 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2118 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2119 // Everything above this point has been processed. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2120 done = true; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2121 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2122 // Eliminate the previous StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2123 prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2124 assert(mem->outcnt() == 0, "should be dead"); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2125 mem->disconnect_inputs(NULL); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2126 } else { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2127 prev = mem; |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2128 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2129 mem = prev->in(MemNode::Memory); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2130 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2131 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2132 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2133 |
0 | 2134 //------------------------------final_graph_reshaping_impl---------------------- |
2135 // Implement items 1-5 from final_graph_reshaping below. | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2136 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { |
0 | 2137 |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2138 if ( n->outcnt() == 0 ) return; // dead node |
0 | 2139 uint nop = n->Opcode(); |
2140 | |
2141 // Check for 2-input instruction with "last use" on right input. | |
2142 // Swap to left input. Implements item (2). | |
2143 if( n->req() == 3 && // two-input instruction | |
2144 n->in(1)->outcnt() > 1 && // left use is NOT a last use | |
2145 (!n->in(1)->is_Phi() || n->in(1)->in(2) != n) && // it is not data loop | |
2146 n->in(2)->outcnt() == 1 &&// right use IS a last use | |
2147 !n->in(2)->is_Con() ) { // right use is not a constant | |
2148 // Check for commutative opcode | |
2149 switch( nop ) { | |
2150 case Op_AddI: case Op_AddF: case Op_AddD: case Op_AddL: | |
2151 case Op_MaxI: case Op_MinI: | |
2152 case Op_MulI: case Op_MulF: case Op_MulD: case Op_MulL: | |
2153 case Op_AndL: case Op_XorL: case Op_OrL: | |
2154 case Op_AndI: case Op_XorI: case Op_OrI: { | |
2155 // Move "last use" input to left by swapping inputs | |
2156 n->swap_edges(1, 2); | |
2157 break; | |
2158 } | |
2159 default: | |
2160 break; | |
2161 } | |
2162 } | |
2163 | |
1609 | 2164 #ifdef ASSERT |
2165 if( n->is_Mem() ) { | |
2166 Compile* C = Compile::current(); | |
2167 int alias_idx = C->get_alias_index(n->as_Mem()->adr_type()); | |
2168 assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || | |
2169 // oop will be recorded in oop map if load crosses safepoint | |
2170 n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || | |
2171 LoadNode::is_immutable_value(n->in(MemNode::Address))), | |
2172 "raw memory operations should have control edge"); | |
2173 } | |
2174 #endif | |
0 | 2175 // Count FPU ops and common calls, implements item (3) |
2176 switch( nop ) { | |
2177 // Count all float operations that may use FPU | |
2178 case Op_AddF: | |
2179 case Op_SubF: | |
2180 case Op_MulF: | |
2181 case Op_DivF: | |
2182 case Op_NegF: | |
2183 case Op_ModF: | |
2184 case Op_ConvI2F: | |
2185 case Op_ConF: | |
2186 case Op_CmpF: | |
2187 case Op_CmpF3: | |
2188 // case Op_ConvL2F: // longs are split into 32-bit halves | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2189 frc.inc_float_count(); |
0 | 2190 break; |
2191 | |
2192 case Op_ConvF2D: | |
2193 case Op_ConvD2F: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2194 frc.inc_float_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2195 frc.inc_double_count(); |
0 | 2196 break; |
2197 | |
2198 // Count all double operations that may use FPU | |
2199 case Op_AddD: | |
2200 case Op_SubD: | |
2201 case Op_MulD: | |
2202 case Op_DivD: | |
2203 case Op_NegD: | |
2204 case Op_ModD: | |
2205 case Op_ConvI2D: | |
2206 case Op_ConvD2I: | |
2207 // case Op_ConvL2D: // handled by leaf call | |
2208 // case Op_ConvD2L: // handled by leaf call | |
2209 case Op_ConD: | |
2210 case Op_CmpD: | |
2211 case Op_CmpD3: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2212 frc.inc_double_count(); |
0 | 2213 break; |
2214 case Op_Opaque1: // Remove Opaque Nodes before matching | |
2215 case Op_Opaque2: // Remove Opaque Nodes before matching | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2216 n->subsume_by(n->in(1)); |
0 | 2217 break; |
2218 case Op_CallStaticJava: | |
2219 case Op_CallJava: | |
2220 case Op_CallDynamicJava: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2221 frc.inc_java_call_count(); // Count java call site; |
0 | 2222 case Op_CallRuntime: |
2223 case Op_CallLeaf: | |
2224 case Op_CallLeafNoFP: { | |
2225 assert( n->is_Call(), "" ); | |
2226 CallNode *call = n->as_Call(); | |
2227 // Count call sites where the FP mode bit would have to be flipped. | |
2228 // Do not count uncommon runtime calls: | |
2229 // uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking, | |
2230 // _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ... | |
2231 if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) { | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2232 frc.inc_call_count(); // Count the call site |
0 | 2233 } else { // See if uncommon argument is shared |
2234 Node *n = call->in(TypeFunc::Parms); | |
2235 int nop = n->Opcode(); | |
2236 // Clone shared simple arguments to uncommon calls, item (1). | |
2237 if( n->outcnt() > 1 && | |
2238 !n->is_Proj() && | |
2239 nop != Op_CreateEx && | |
2240 nop != Op_CheckCastPP && | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2241 nop != Op_DecodeN && |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2242 nop != Op_DecodeNKlass && |
0 | 2243 !n->is_Mem() ) { |
2244 Node *x = n->clone(); | |
2245 call->set_req( TypeFunc::Parms, x ); | |
2246 } | |
2247 } | |
2248 break; | |
2249 } | |
2250 | |
2251 case Op_StoreD: | |
2252 case Op_LoadD: | |
2253 case Op_LoadD_unaligned: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2254 frc.inc_double_count(); |
0 | 2255 goto handle_mem; |
2256 case Op_StoreF: | |
2257 case Op_LoadF: | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2258 frc.inc_float_count(); |
0 | 2259 goto handle_mem; |
2260 | |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2261 case Op_StoreCM: |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2262 { |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2263 // Convert OopStore dependence into precedence edge |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2264 Node* prec = n->in(MemNode::OopStore); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2265 n->del_req(MemNode::OopStore); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2266 n->add_prec(prec); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2267 eliminate_redundant_card_marks(n); |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2268 } |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2269 |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2270 // fall through |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2376
diff
changeset
|
2271 |
0 | 2272 case Op_StoreB: |
2273 case Op_StoreC: | |
2274 case Op_StorePConditional: | |
2275 case Op_StoreI: | |
2276 case Op_StoreL: | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
418
diff
changeset
|
2277 case Op_StoreIConditional: |
0 | 2278 case Op_StoreLConditional: |
2279 case Op_CompareAndSwapI: | |
2280 case Op_CompareAndSwapL: | |
2281 case Op_CompareAndSwapP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2282 case Op_CompareAndSwapN: |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2283 case Op_GetAndAddI: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2284 case Op_GetAndAddL: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2285 case Op_GetAndSetI: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2286 case Op_GetAndSetL: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2287 case Op_GetAndSetP: |
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6792
diff
changeset
|
2288 case Op_GetAndSetN: |
0 | 2289 case Op_StoreP: |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2290 case Op_StoreN: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2291 case Op_StoreNKlass: |
0 | 2292 case Op_LoadB: |
624 | 2293 case Op_LoadUB: |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
492
diff
changeset
|
2294 case Op_LoadUS: |
0 | 2295 case Op_LoadI: |
2296 case Op_LoadKlass: | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2297 case Op_LoadNKlass: |
0 | 2298 case Op_LoadL: |
2299 case Op_LoadL_unaligned: | |
2300 case Op_LoadPLocked: | |
2301 case Op_LoadP: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
2302 case Op_LoadN: |
0 | 2303 case Op_LoadRange: |
2304 case Op_LoadS: { | |
2305 handle_mem: | |
2306 #ifdef ASSERT | |
2307 if( VerifyOptoOopOffsets ) { | |
2308 assert( n->is_Mem(), "" ); | |
2309 MemNode *mem = (MemNode*)n; | |
2310 // Check to see if address types have grounded out somehow. | |
2311 const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr(); | |
2312 assert( !tp || oop_offset_is_sane(tp), "" ); | |
2313 } | |
2314 #endif | |
2315 break; | |
2316 } | |
2317 | |
2318 case Op_AddP: { // Assert sane base pointers | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2319 Node *addp = n->in(AddPNode::Address); |
0 | 2320 assert( !addp->is_AddP() || |
2321 addp->in(AddPNode::Base)->is_top() || // Top OK for allocation | |
2322 addp->in(AddPNode::Base) == n->in(AddPNode::Base), | |
2323 "Base pointers must match" ); | |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2324 #ifdef _LP64 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2325 if ((UseCompressedOops || UseCompressedKlassPointers) && |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2326 addp->Opcode() == Op_ConP && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2327 addp == n->in(AddPNode::Base) && |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2328 n->in(AddPNode::Offset)->is_Con()) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2329 // Use addressing with narrow klass to load with offset on x86. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2330 // On sparc loading 32-bits constant and decoding it have less |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2331 // instructions (4) then load 64-bits constant (7). |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2332 // Do this transformation here since IGVN will convert ConN back to ConP. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2333 const Type* t = addp->bottom_type(); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2334 if (t->isa_oopptr() || t->isa_klassptr()) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2335 Node* nn = NULL; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2336 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2337 int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass; |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2338 |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2339 // Look for existing ConN node of the same exact type. |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2340 Compile* C = Compile::current(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2341 Node* r = C->root(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2342 uint cnt = r->outcnt(); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2343 for (uint i = 0; i < cnt; i++) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2344 Node* m = r->raw_out(i); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2345 if (m!= NULL && m->Opcode() == op && |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
182
diff
changeset
|
2346 m->bottom_type()->make_ptr() == t) { |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2347 nn = m; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2348 break; |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2349 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2350 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2351 if (nn != NULL) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2352 // Decode a narrow oop to match address |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2353 // [R12 + narrow_oop_reg<<3 + offset] |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2354 if (t->isa_oopptr()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2355 nn = new (C) DecodeNNode(nn, t); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2356 } else { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2357 nn = new (C) DecodeNKlassNode(nn, t); |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2358 } |
182
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2359 n->set_req(AddPNode::Base, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2360 n->set_req(AddPNode::Address, nn); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2361 if (addp->outcnt() == 0) { |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2362 addp->disconnect_inputs(NULL); |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2363 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2364 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2365 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2366 } |
44abbb0d4c18
6709093: Compressed Oops: reduce size of compiled methods
kvn
parents:
168
diff
changeset
|
2367 #endif |
0 | 2368 break; |
2369 } | |
2370 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2371 #ifdef _LP64 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2372 case Op_CastPP: |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2373 if (n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2374 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2375 Node* in1 = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2376 const Type* t = n->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2377 Node* new_in1 = in1->clone(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2378 new_in1->as_DecodeN()->set_type(t); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2379 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2380 if (!Matcher::narrow_oop_use_complex_address()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2381 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2382 // x86, ARM and friends can handle 2 adds in addressing mode |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2383 // and Matcher can fold a DecodeN node into address by using |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2384 // a narrow oop directly and do implicit NULL check in address: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2385 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2386 // [R12 + narrow_oop_reg<<3 + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2387 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2388 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2389 // On other platforms (Sparc) we have to keep new DecodeN node and |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2390 // use it to do implicit NULL check in address: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2391 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2392 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2393 // [base_reg + offset] |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2394 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2395 // |
605 | 2396 // Pin the new DecodeN node to non-null path on these platform (Sparc) |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2397 // to keep the information to which NULL check the new DecodeN node |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2398 // corresponds to use it as value in implicit_null_check(). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2399 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2400 new_in1->set_req(0, n->in(0)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2401 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2402 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2403 n->subsume_by(new_in1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2404 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2405 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2406 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2407 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2408 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2409 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2410 case Op_CmpP: |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2411 // Do this transformation here to preserve CmpPNode::sub() and |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2412 // other TypePtr related Ideal optimizations (for example, ptr nullness). |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2413 if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2414 Node* in1 = n->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2415 Node* in2 = n->in(2); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2416 if (!in1->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2417 in2 = in1; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2418 in1 = n->in(2); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2419 } |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2420 assert(in1->is_DecodeNarrowPtr(), "sanity"); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2421 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2422 Compile* C = Compile::current(); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2423 Node* new_in2 = NULL; |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2424 if (in2->is_DecodeNarrowPtr()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2425 assert(in2->Opcode() == in1->Opcode(), "must be same node type"); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2426 new_in2 = in2->in(1); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2427 } else if (in2->Opcode() == Op_ConP) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2428 const Type* t = in2->bottom_type(); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2429 if (t == TypePtr::NULL_PTR) { |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2430 assert(in1->is_DecodeN(), "compare klass to null?"); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2431 // Don't convert CmpP null check into CmpN if compressed |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2432 // oops implicit null check is not generated. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2433 // This will allow to generate normal oop implicit null check. |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2434 if (Matcher::gen_narrow_oop_implicit_null_checks()) |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2435 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2436 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2437 // This transformation together with CastPP transformation above |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2438 // will generated code for implicit NULL checks for compressed oops. |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2439 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2440 // The original code after Optimize() |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2441 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2442 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2443 // decode narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2444 // CmpP base_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2445 // CastPP base_reg // NotNull |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2446 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2447 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2448 // after these transformations will be |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2449 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2450 // LoadN memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2451 // CmpN narrow_oop_reg, NULL |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2452 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2453 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2454 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2455 // and the uncommon path (== NULL) will use narrow_oop_reg directly |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2456 // since narrow oops can be used in debug info now (see the code in |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2457 // final_graph_reshaping_walk()). |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2458 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2459 // At the end the code will be matched to |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2460 // on x86: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2461 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2462 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2463 // Load [R12 + narrow_oop_reg<<3 + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2464 // NullCheck narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2465 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2466 // and on sparc: |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2467 // |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2468 // Load_narrow_oop memory, narrow_oop_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2469 // decode_not_null narrow_oop_reg, base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2470 // Load [base_reg + offset], val_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2471 // NullCheck base_reg |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2472 // |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2473 } else if (t->isa_oopptr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2474 new_in2 = ConNode::make(C, t->make_narrowoop()); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2475 } else if (t->isa_klassptr()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2476 new_in2 = ConNode::make(C, t->make_narrowklass()); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2477 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2478 } |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2479 if (new_in2 != NULL) { |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2480 Node* cmpN = new (C) CmpNNode(in1->in(1), new_in2); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2481 n->subsume_by( cmpN ); |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2482 if (in1->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2483 in1->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2484 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2485 if (in2->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2486 in2->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2487 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2488 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2489 } |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
2490 break; |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2491 |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2492 case Op_DecodeN: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2493 case Op_DecodeNKlass: |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2494 assert(!n->in(1)->is_EncodeNarrowPtr(), "should be optimized out"); |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2495 // DecodeN could be pinned when it can't be fold into |
492
5496e074077f
6787050: assert(n->in(0) == 0L,"no control") with UseCompressedOops on sparcv9
kvn
parents:
490
diff
changeset
|
2496 // an address expression, see the code for Op_CastPP above. |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2497 assert(n->in(0) == NULL || (UseCompressedOops && !Matcher::narrow_oop_use_complex_address()), "no control"); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2498 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2499 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2500 case Op_EncodeP: |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2501 case Op_EncodePKlass: { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2502 Node* in1 = n->in(1); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2503 if (in1->is_DecodeNarrowPtr()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2504 n->subsume_by(in1->in(1)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2505 } else if (in1->Opcode() == Op_ConP) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2506 Compile* C = Compile::current(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2507 const Type* t = in1->bottom_type(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2508 if (t == TypePtr::NULL_PTR) { |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2509 assert(t->isa_oopptr(), "null klass?"); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2510 n->subsume_by(ConNode::make(C, TypeNarrowOop::NULL_PTR)); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2511 } else if (t->isa_oopptr()) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2512 n->subsume_by(ConNode::make(C, t->make_narrowoop())); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2513 } else if (t->isa_klassptr()) { |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2514 n->subsume_by(ConNode::make(C, t->make_narrowklass())); |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2515 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2516 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2517 if (in1->outcnt() == 0) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2518 in1->disconnect_inputs(NULL); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2519 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2520 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2521 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2522 |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2523 case Op_Proj: { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2524 if (OptimizeStringConcat) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2525 ProjNode* p = n->as_Proj(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2526 if (p->_is_io_use) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2527 // Separate projections were used for the exception path which |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2528 // are normally removed by a late inline. If it wasn't inlined |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2529 // then they will hang around and should just be replaced with |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2530 // the original one. |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2531 Node* proj = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2532 // Replace with just one |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2533 for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2534 Node *use = i.get(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2535 if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2536 proj = use; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2537 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2538 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2539 } |
4767 | 2540 assert(proj != NULL, "must be found"); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2541 p->subsume_by(proj); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2542 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2543 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2544 break; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2545 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
929
diff
changeset
|
2546 |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2547 case Op_Phi: |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2548 if (n->as_Phi()->bottom_type()->isa_narrowoop() || n->as_Phi()->bottom_type()->isa_narrowklass()) { |
368
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2549 // The EncodeP optimization may create Phi with the same edges |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2550 // for all paths. It is not handled well by Register Allocator. |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2551 Node* unique_in = n->in(1); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2552 assert(unique_in != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2553 uint cnt = n->req(); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2554 for (uint i = 2; i < cnt; i++) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2555 Node* m = n->in(i); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2556 assert(m != NULL, ""); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2557 if (unique_in != m) |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2558 unique_in = NULL; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2559 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2560 if (unique_in != NULL) { |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2561 n->subsume_by(unique_in); |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2562 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2563 } |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2564 break; |
36ccc817fca4
6747051: Improve code and implicit null check generation for compressed oops
kvn
parents:
367
diff
changeset
|
2565 |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2566 #endif |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2567 |
0 | 2568 case Op_ModI: |
2569 if (UseDivMod) { | |
2570 // Check if a%b and a/b both exist | |
2571 Node* d = n->find_similar(Op_DivI); | |
2572 if (d) { | |
2573 // Replace them with a fused divmod if supported | |
2574 Compile* C = Compile::current(); | |
2575 if (Matcher::has_match_rule(Op_DivModI)) { | |
2576 DivModINode* divmod = DivModINode::make(C, n); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2577 d->subsume_by(divmod->div_proj()); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2578 n->subsume_by(divmod->mod_proj()); |
0 | 2579 } else { |
2580 // replace a%b with a-((a/b)*b) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2581 Node* mult = new (C) MulINode(d, d->in(2)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2582 Node* sub = new (C) SubINode(d->in(1), mult); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2583 n->subsume_by( sub ); |
0 | 2584 } |
2585 } | |
2586 } | |
2587 break; | |
2588 | |
2589 case Op_ModL: | |
2590 if (UseDivMod) { | |
2591 // Check if a%b and a/b both exist | |
2592 Node* d = n->find_similar(Op_DivL); | |
2593 if (d) { | |
2594 // Replace them with a fused divmod if supported | |
2595 Compile* C = Compile::current(); | |
2596 if (Matcher::has_match_rule(Op_DivModL)) { | |
2597 DivModLNode* divmod = DivModLNode::make(C, n); | |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2598 d->subsume_by(divmod->div_proj()); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2599 n->subsume_by(divmod->mod_proj()); |
0 | 2600 } else { |
2601 // replace a%b with a-((a/b)*b) | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2602 Node* mult = new (C) MulLNode(d, d->in(2)); |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2603 Node* sub = new (C) SubLNode(d->in(1), mult); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2604 n->subsume_by( sub ); |
0 | 2605 } |
2606 } | |
2607 } | |
2608 break; | |
2609 | |
6179
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
2610 case Op_LoadVector: |
8c92982cbbc4
7119644: Increase superword's vector size up to 256 bits
kvn
parents:
6143
diff
changeset
|
2611 case Op_StoreVector: |
0 | 2612 break; |
2613 | |
2614 case Op_PackB: | |
2615 case Op_PackS: | |
2616 case Op_PackI: | |
2617 case Op_PackF: | |
2618 case Op_PackL: | |
2619 case Op_PackD: | |
2620 if (n->req()-1 > 2) { | |
2621 // Replace many operand PackNodes with a binary tree for matching | |
2622 PackNode* p = (PackNode*) n; | |
6619
5af51c882207
7192963: assert(_in[req-1] == this) failed: Must pass arg count to 'new'
kvn
parents:
6268
diff
changeset
|
2623 Node* btp = p->binary_tree_pack(Compile::current(), 1, n->req()); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
2624 n->subsume_by(btp); |
0 | 2625 } |
2626 break; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2627 case Op_Loop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2628 case Op_CountedLoop: |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2629 if (n->as_Loop()->is_inner_loop()) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2630 frc.inc_inner_loop_count(); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2631 } |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2632 break; |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2633 case Op_LShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2634 case Op_RShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2635 case Op_URShiftI: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2636 case Op_LShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2637 case Op_RShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2638 case Op_URShiftL: |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2639 if (Matcher::need_masked_shift_count) { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2640 // The cpu's shift instructions don't restrict the count to the |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2641 // lower 5/6 bits. We need to do the masking ourselves. |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2642 Node* in2 = n->in(2); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2643 juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2644 const TypeInt* t = in2->find_int_type(); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2645 if (t != NULL && t->is_con()) { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2646 juint shift = t->get_con(); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2647 if (shift > mask) { // Unsigned cmp |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2648 Compile* C = Compile::current(); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2649 n->set_req(2, ConNode::make(C, TypeInt::make(shift & mask))); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2650 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2651 } else { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2652 if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2653 Compile* C = Compile::current(); |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
6795
diff
changeset
|
2654 Node* shift = new (C) AndINode(in2, ConNode::make(C, TypeInt::make(mask))); |
2401
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2655 n->set_req(2, shift); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2656 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2657 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2658 if (in2->outcnt() == 0) { // Remove dead node |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2659 in2->disconnect_inputs(NULL); |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2660 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2661 } |
7e88bdae86ec
7029017: Additional architecture support for c2 compiler
roland
parents:
2376
diff
changeset
|
2662 break; |
0 | 2663 default: |
2664 assert( !n->is_Call(), "" ); | |
2665 assert( !n->is_Mem(), "" ); | |
2666 break; | |
2667 } | |
127 | 2668 |
2669 // Collect CFG split points | |
2670 if (n->is_MultiBranch()) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2671 frc._tests.push(n); |
0 | 2672 } |
2673 | |
2674 //------------------------------final_graph_reshaping_walk--------------------- | |
2675 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | |
2676 // requires that the walk visits a node's inputs before visiting the node. | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2677 static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2678 ResourceArea *area = Thread::current()->resource_area(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2679 Unique_Node_List sfpt(area); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2680 |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2681 frc._visited.set(root->_idx); // first, mark node as visited |
0 | 2682 uint cnt = root->req(); |
2683 Node *n = root; | |
2684 uint i = 0; | |
2685 while (true) { | |
2686 if (i < cnt) { | |
2687 // Place all non-visited non-null inputs onto stack | |
2688 Node* m = n->in(i); | |
2689 ++i; | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2690 if (m != NULL && !frc._visited.test_set(m->_idx)) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2691 if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2692 sfpt.push(m); |
0 | 2693 cnt = m->req(); |
2694 nstack.push(n, i); // put on stack parent and next input's index | |
2695 n = m; | |
2696 i = 0; | |
2697 } | |
2698 } else { | |
2699 // Now do post-visit work | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2700 final_graph_reshaping_impl( n, frc ); |
0 | 2701 if (nstack.is_empty()) |
2702 break; // finished | |
2703 n = nstack.node(); // Get node from stack | |
2704 cnt = n->req(); | |
2705 i = nstack.index(); | |
2706 nstack.pop(); // Shift to the next node on stack | |
2707 } | |
2708 } | |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2709 |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2710 // Skip next transformation if compressed oops are not used. |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2711 if ((UseCompressedOops && !Matcher::gen_narrow_oop_implicit_null_checks()) || |
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2712 (!UseCompressedOops && !UseCompressedKlassPointers)) |
1575
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2713 return; |
3657cb01ffc5
6954029: Improve implicit null check generation with compressed oops
kvn
parents:
1397
diff
changeset
|
2714 |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2715 // Go over safepoints nodes to skip DecodeN/DecodeNKlass nodes for debug edges. |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2716 // It could be done for an uncommon traps or any safepoints/calls |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2717 // if the DecodeN/DecodeNKlass node is referenced only in a debug info. |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2718 while (sfpt.size() > 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2719 n = sfpt.pop(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2720 JVMState *jvms = n->as_SafePoint()->jvms(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2721 assert(jvms != NULL, "sanity"); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2722 int start = jvms->debug_start(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2723 int end = n->req(); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2724 bool is_uncommon = (n->is_CallStaticJava() && |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2725 n->as_CallStaticJava()->uncommon_trap_request() != 0); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2726 for (int j = start; j < end; j++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2727 Node* in = n->in(j); |
6848
8e47bac5643a
7054512: Compress class pointers after perm gen removal
roland
parents:
6843
diff
changeset
|
2728 if (in->is_DecodeNarrowPtr()) { |
331
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2729 bool safe_to_skip = true; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2730 if (!is_uncommon ) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2731 // Is it safe to skip? |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2732 for (uint i = 0; i < in->outcnt(); i++) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2733 Node* u = in->raw_out(i); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2734 if (!u->is_SafePoint() || |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2735 u->is_Call() && u->as_Call()->has_non_debug_use(n)) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2736 safe_to_skip = false; |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2737 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2738 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2739 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2740 if (safe_to_skip) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2741 n->set_req(j, in->in(1)); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2742 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2743 if (in->outcnt() == 0) { |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2744 in->disconnect_inputs(NULL); |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2745 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2746 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2747 } |
cecd8eb4e0ca
6706829: Compressed Oops: add debug info for narrow oops
kvn
parents:
293
diff
changeset
|
2748 } |
0 | 2749 } |
2750 | |
2751 //------------------------------final_graph_reshaping-------------------------- | |
2752 // Final Graph Reshaping. | |
2753 // | |
2754 // (1) Clone simple inputs to uncommon calls, so they can be scheduled late | |
2755 // and not commoned up and forced early. Must come after regular | |
2756 // optimizations to avoid GVN undoing the cloning. Clone constant | |
2757 // inputs to Loop Phis; these will be split by the allocator anyways. | |
2758 // Remove Opaque nodes. | |
2759 // (2) Move last-uses by commutative operations to the left input to encourage | |
2760 // Intel update-in-place two-address operations and better register usage | |
2761 // on RISCs. Must come after regular optimizations to avoid GVN Ideal | |
2762 // calls canonicalizing them back. | |
2763 // (3) Count the number of double-precision FP ops, single-precision FP ops | |
2764 // and call sites. On Intel, we can get correct rounding either by | |
2765 // forcing singles to memory (requires extra stores and loads after each | |
2766 // FP bytecode) or we can set a rounding mode bit (requires setting and | |
2767 // clearing the mode bit around call sites). The mode bit is only used | |
2768 // if the relative frequency of single FP ops to calls is low enough. | |
2769 // This is a key transform for SPEC mpeg_audio. | |
2770 // (4) Detect infinite loops; blobs of code reachable from above but not | |
2771 // below. Several of the Code_Gen algorithms fail on such code shapes, | |
2772 // so we simply bail out. Happens a lot in ZKM.jar, but also happens | |
2773 // from time to time in other codes (such as -Xcomp finalizer loops, etc). | |
2774 // Detection is by looking for IfNodes where only 1 projection is | |
2775 // reachable from below or CatchNodes missing some targets. | |
2776 // (5) Assert for insane oop offsets in debug mode. | |
2777 | |
2778 bool Compile::final_graph_reshaping() { | |
2779 // an infinite loop may have been eliminated by the optimizer, | |
2780 // in which case the graph will be empty. | |
2781 if (root()->req() == 1) { | |
2782 record_method_not_compilable("trivial infinite loop"); | |
2783 return true; | |
2784 } | |
2785 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2786 Final_Reshape_Counts frc; |
0 | 2787 |
2788 // Visit everybody reachable! | |
2789 // Allocate stack of size C->unique()/2 to avoid frequent realloc | |
2790 Node_Stack nstack(unique() >> 1); | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2791 final_graph_reshaping_walk(nstack, root(), frc); |
0 | 2792 |
2793 // Check for unreachable (from below) code (i.e., infinite loops). | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2794 for( uint i = 0; i < frc._tests.size(); i++ ) { |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2795 MultiBranchNode *n = frc._tests[i]->as_MultiBranch(); |
127 | 2796 // Get number of CFG targets. |
0 | 2797 // Note that PCTables include exception targets after calls. |
127 | 2798 uint required_outcnt = n->required_outcnt(); |
2799 if (n->outcnt() != required_outcnt) { | |
0 | 2800 // Check for a few special cases. Rethrow Nodes never take the |
2801 // 'fall-thru' path, so expected kids is 1 less. | |
2802 if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { | |
2803 if (n->in(0)->in(0)->is_Call()) { | |
2804 CallNode *call = n->in(0)->in(0)->as_Call(); | |
2805 if (call->entry_point() == OptoRuntime::rethrow_stub()) { | |
127 | 2806 required_outcnt--; // Rethrow always has 1 less kid |
0 | 2807 } else if (call->req() > TypeFunc::Parms && |
2808 call->is_CallDynamicJava()) { | |
2809 // Check for null receiver. In such case, the optimizer has | |
2810 // detected that the virtual call will always result in a null | |
2811 // pointer exception. The fall-through projection of this CatchNode | |
2812 // will not be populated. | |
2813 Node *arg0 = call->in(TypeFunc::Parms); | |
2814 if (arg0->is_Type() && | |
2815 arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { | |
127 | 2816 required_outcnt--; |
0 | 2817 } |
2818 } else if (call->entry_point() == OptoRuntime::new_array_Java() && | |
2819 call->req() > TypeFunc::Parms+1 && | |
2820 call->is_CallStaticJava()) { | |
2821 // Check for negative array length. In such case, the optimizer has | |
2822 // detected that the allocation attempt will always result in an | |
2823 // exception. There is no fall-through projection of this CatchNode . | |
2824 Node *arg1 = call->in(TypeFunc::Parms+1); | |
2825 if (arg1->is_Type() && | |
2826 arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { | |
127 | 2827 required_outcnt--; |
0 | 2828 } |
2829 } | |
2830 } | |
2831 } | |
127 | 2832 // Recheck with a better notion of 'required_outcnt' |
2833 if (n->outcnt() != required_outcnt) { | |
0 | 2834 record_method_not_compilable("malformed control flow"); |
2835 return true; // Not all targets reachable! | |
2836 } | |
2837 } | |
2838 // Check that I actually visited all kids. Unreached kids | |
2839 // must be infinite loops. | |
2840 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2841 if (!frc._visited.test(n->fast_out(j)->_idx)) { |
0 | 2842 record_method_not_compilable("infinite loop"); |
2843 return true; // Found unvisited kid; must be unreach | |
2844 } | |
2845 } | |
2846 | |
2847 // If original bytecodes contained a mixture of floats and doubles | |
2848 // check if the optimizer has made it homogenous, item (3). | |
929
cd18bd5e667c
6873777: FPU control word optimization still performed with SSE
never
parents:
921
diff
changeset
|
2849 if( Use24BitFPMode && Use24BitFP && UseSSE == 0 && |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2850 frc.get_float_count() > 32 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2851 frc.get_double_count() == 0 && |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2852 (10 * frc.get_call_count() < frc.get_float_count()) ) { |
0 | 2853 set_24_bit_selection_and_mode( false, true ); |
2854 } | |
2855 | |
859
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2856 set_java_calls(frc.get_java_call_count()); |
ea3f9723b5cf
6860599: nodes limit could be reached during Output phase
kvn
parents:
856
diff
changeset
|
2857 set_inner_loops(frc.get_inner_loop_count()); |
0 | 2858 |
2859 // No infinite loops, no reason to bail out. | |
2860 return false; | |
2861 } | |
2862 | |
2863 //-----------------------------too_many_traps---------------------------------- | |
2864 // Report if there are too many traps at the current method and bci. | |
2865 // Return true if there was a trap, and/or PerMethodTrapLimit is exceeded. | |
2866 bool Compile::too_many_traps(ciMethod* method, | |
2867 int bci, | |
2868 Deoptimization::DeoptReason reason) { | |
2869 ciMethodData* md = method->method_data(); | |
2870 if (md->is_empty()) { | |
2871 // Assume the trap has not occurred, or that it occurred only | |
2872 // because of a transient condition during start-up in the interpreter. | |
2873 return false; | |
2874 } | |
2875 if (md->has_trap_at(bci, reason) != 0) { | |
2876 // Assume PerBytecodeTrapLimit==0, for a more conservative heuristic. | |
2877 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2878 // assume the worst. | |
2879 if (log()) | |
2880 log()->elem("observe trap='%s' count='%d'", | |
2881 Deoptimization::trap_reason_name(reason), | |
2882 md->trap_count(reason)); | |
2883 return true; | |
2884 } else { | |
2885 // Ignore method/bci and see if there have been too many globally. | |
2886 return too_many_traps(reason, md); | |
2887 } | |
2888 } | |
2889 | |
2890 // Less-accurate variant which does not require a method and bci. | |
2891 bool Compile::too_many_traps(Deoptimization::DeoptReason reason, | |
2892 ciMethodData* logmd) { | |
2893 if (trap_count(reason) >= (uint)PerMethodTrapLimit) { | |
2894 // Too many traps globally. | |
2895 // Note that we use cumulative trap_count, not just md->trap_count. | |
2896 if (log()) { | |
2897 int mcount = (logmd == NULL)? -1: (int)logmd->trap_count(reason); | |
2898 log()->elem("observe trap='%s' count='0' mcount='%d' ccount='%d'", | |
2899 Deoptimization::trap_reason_name(reason), | |
2900 mcount, trap_count(reason)); | |
2901 } | |
2902 return true; | |
2903 } else { | |
2904 // The coast is clear. | |
2905 return false; | |
2906 } | |
2907 } | |
2908 | |
2909 //--------------------------too_many_recompiles-------------------------------- | |
2910 // Report if there are too many recompiles at the current method and bci. | |
2911 // Consults PerBytecodeRecompilationCutoff and PerMethodRecompilationCutoff. | |
2912 // Is not eager to return true, since this will cause the compiler to use | |
2913 // Action_none for a trap point, to avoid too many recompilations. | |
2914 bool Compile::too_many_recompiles(ciMethod* method, | |
2915 int bci, | |
2916 Deoptimization::DeoptReason reason) { | |
2917 ciMethodData* md = method->method_data(); | |
2918 if (md->is_empty()) { | |
2919 // Assume the trap has not occurred, or that it occurred only | |
2920 // because of a transient condition during start-up in the interpreter. | |
2921 return false; | |
2922 } | |
2923 // Pick a cutoff point well within PerBytecodeRecompilationCutoff. | |
2924 uint bc_cutoff = (uint) PerBytecodeRecompilationCutoff / 8; | |
2925 uint m_cutoff = (uint) PerMethodRecompilationCutoff / 2 + 1; // not zero | |
2926 Deoptimization::DeoptReason per_bc_reason | |
2927 = Deoptimization::reason_recorded_per_bytecode_if_any(reason); | |
2928 if ((per_bc_reason == Deoptimization::Reason_none | |
2929 || md->has_trap_at(bci, reason) != 0) | |
2930 // The trap frequency measure we care about is the recompile count: | |
2931 && md->trap_recompiled_at(bci) | |
2932 && md->overflow_recompile_count() >= bc_cutoff) { | |
2933 // Do not emit a trap here if it has already caused recompilations. | |
2934 // Also, if there are multiple reasons, or if there is no per-BCI record, | |
2935 // assume the worst. | |
2936 if (log()) | |
2937 log()->elem("observe trap='%s recompiled' count='%d' recompiles2='%d'", | |
2938 Deoptimization::trap_reason_name(reason), | |
2939 md->trap_count(reason), | |
2940 md->overflow_recompile_count()); | |
2941 return true; | |
2942 } else if (trap_count(reason) != 0 | |
2943 && decompile_count() >= m_cutoff) { | |
2944 // Too many recompiles globally, and we have seen this sort of trap. | |
2945 // Use cumulative decompile_count, not just md->decompile_count. | |
2946 if (log()) | |
2947 log()->elem("observe trap='%s' count='%d' mcount='%d' decompiles='%d' mdecompiles='%d'", | |
2948 Deoptimization::trap_reason_name(reason), | |
2949 md->trap_count(reason), trap_count(reason), | |
2950 md->decompile_count(), decompile_count()); | |
2951 return true; | |
2952 } else { | |
2953 // The coast is clear. | |
2954 return false; | |
2955 } | |
2956 } | |
2957 | |
2958 | |
2959 #ifndef PRODUCT | |
2960 //------------------------------verify_graph_edges--------------------------- | |
2961 // Walk the Graph and verify that there is a one-to-one correspondence | |
2962 // between Use-Def edges and Def-Use edges in the graph. | |
2963 void Compile::verify_graph_edges(bool no_dead_code) { | |
2964 if (VerifyGraphEdges) { | |
2965 ResourceArea *area = Thread::current()->resource_area(); | |
2966 Unique_Node_List visited(area); | |
2967 // Call recursive graph walk to check edges | |
2968 _root->verify_edges(visited); | |
2969 if (no_dead_code) { | |
2970 // Now make sure that no visited node is used by an unvisited node. | |
2971 bool dead_nodes = 0; | |
2972 Unique_Node_List checked(area); | |
2973 while (visited.size() > 0) { | |
2974 Node* n = visited.pop(); | |
2975 checked.push(n); | |
2976 for (uint i = 0; i < n->outcnt(); i++) { | |
2977 Node* use = n->raw_out(i); | |
2978 if (checked.member(use)) continue; // already checked | |
2979 if (visited.member(use)) continue; // already in the graph | |
2980 if (use->is_Con()) continue; // a dead ConNode is OK | |
2981 // At this point, we have found a dead node which is DU-reachable. | |
2982 if (dead_nodes++ == 0) | |
2983 tty->print_cr("*** Dead nodes reachable via DU edges:"); | |
2984 use->dump(2); | |
2985 tty->print_cr("---"); | |
2986 checked.push(use); // No repeats; pretend it is now checked. | |
2987 } | |
2988 } | |
2989 assert(dead_nodes == 0, "using nodes must be reachable from root"); | |
2990 } | |
2991 } | |
2992 } | |
2993 #endif | |
2994 | |
2995 // The Compile object keeps track of failure reasons separately from the ciEnv. | |
2996 // This is required because there is not quite a 1-1 relation between the | |
2997 // ciEnv and its compilation task and the Compile object. Note that one | |
2998 // ciEnv might use two Compile objects, if C2Compiler::compile_method decides | |
2999 // to backtrack and retry without subsuming loads. Other than this backtracking | |
3000 // behavior, the Compile's failure reason is quietly copied up to the ciEnv | |
3001 // by the logic in C2Compiler. | |
3002 void Compile::record_failure(const char* reason) { | |
3003 if (log() != NULL) { | |
3004 log()->elem("failure reason='%s' phase='compile'", reason); | |
3005 } | |
3006 if (_failure_reason == NULL) { | |
3007 // Record the first failure reason. | |
3008 _failure_reason = reason; | |
3009 } | |
222 | 3010 if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) { |
3011 C->print_method(_failure_reason); | |
3012 } | |
0 | 3013 _root = NULL; // flush the graph, too |
3014 } | |
3015 | |
3016 Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) | |
3017 : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false) | |
3018 { | |
3019 if (dolog) { | |
3020 C = Compile::current(); | |
3021 _log = C->log(); | |
3022 } else { | |
3023 C = NULL; | |
3024 _log = NULL; | |
3025 } | |
3026 if (_log != NULL) { | |
3027 _log->begin_head("phase name='%s' nodes='%d'", name, C->unique()); | |
3028 _log->stamp(); | |
3029 _log->end_head(); | |
3030 } | |
3031 } | |
3032 | |
3033 Compile::TracePhase::~TracePhase() { | |
3034 if (_log != NULL) { | |
3035 _log->done("phase nodes='%d'", C->unique()); | |
3036 } | |
3037 } | |
2008 | 3038 |
3039 //============================================================================= | |
3040 // Two Constant's are equal when the type and the value are equal. | |
3041 bool Compile::Constant::operator==(const Constant& other) { | |
3042 if (type() != other.type() ) return false; | |
3043 if (can_be_reused() != other.can_be_reused()) return false; | |
3044 // For floating point values we compare the bit pattern. | |
3045 switch (type()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3046 case T_FLOAT: return (_v._value.i == other._v._value.i); |
2008 | 3047 case T_LONG: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3048 case T_DOUBLE: return (_v._value.j == other._v._value.j); |
2008 | 3049 case T_OBJECT: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3050 case T_ADDRESS: return (_v._value.l == other._v._value.l); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3051 case T_VOID: return (_v._value.l == other._v._value.l); // jump-table entries |
6888
cfe522e6461c
8000623: tools/javac/Diagnostics/6769027/T6769027.java crashes in PSPromotionManager::copy_to_survivor_space
kvn
parents:
6849
diff
changeset
|
3052 case T_METADATA: return (_v._metadata == other._v._metadata); |
2008 | 3053 default: ShouldNotReachHere(); |
3054 } | |
3055 return false; | |
3056 } | |
3057 | |
3058 static int type_to_size_in_bytes(BasicType t) { | |
3059 switch (t) { | |
3060 case T_LONG: return sizeof(jlong ); | |
3061 case T_FLOAT: return sizeof(jfloat ); | |
3062 case T_DOUBLE: return sizeof(jdouble); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3063 case T_METADATA: return sizeof(Metadata*); |
2008 | 3064 // We use T_VOID as marker for jump-table entries (labels) which |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3065 // need an internal word relocation. |
2008 | 3066 case T_VOID: |
3067 case T_ADDRESS: | |
3068 case T_OBJECT: return sizeof(jobject); | |
3069 } | |
3070 | |
3071 ShouldNotReachHere(); | |
3072 return -1; | |
3073 } | |
3074 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3075 int Compile::ConstantTable::qsort_comparator(Constant* a, Constant* b) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3076 // sort descending |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3077 if (a->freq() > b->freq()) return -1; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3078 if (a->freq() < b->freq()) return 1; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3079 return 0; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3080 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3081 |
2008 | 3082 void Compile::ConstantTable::calculate_offsets_and_size() { |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3083 // First, sort the array by frequencies. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3084 _constants.sort(qsort_comparator); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3085 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3086 #ifdef ASSERT |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3087 // Make sure all jump-table entries were sorted to the end of the |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3088 // array (they have a negative frequency). |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3089 bool found_void = false; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3090 for (int i = 0; i < _constants.length(); i++) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3091 Constant con = _constants.at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3092 if (con.type() == T_VOID) |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3093 found_void = true; // jump-tables |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3094 else |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3095 assert(!found_void, "wrong sorting"); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3096 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3097 #endif |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3098 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3099 int offset = 0; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3100 for (int i = 0; i < _constants.length(); i++) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3101 Constant* con = _constants.adr_at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3102 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3103 // Align offset for type. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3104 int typesize = type_to_size_in_bytes(con->type()); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3105 offset = align_size_up(offset, typesize); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3106 con->set_offset(offset); // set constant's offset |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3107 |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3108 if (con->type() == T_VOID) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3109 MachConstantNode* n = (MachConstantNode*) con->get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3110 offset = offset + typesize * n->outcnt(); // expand jump-table |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3111 } else { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3112 offset = offset + typesize; |
2008 | 3113 } |
3114 } | |
3115 | |
3116 // Align size up to the next section start (which is insts; see | |
3117 // CodeBuffer::align_at_start). | |
3118 assert(_size == -1, "already set?"); | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3119 _size = align_size_up(offset, CodeEntryAlignment); |
2008 | 3120 } |
3121 | |
3122 void Compile::ConstantTable::emit(CodeBuffer& cb) { | |
3123 MacroAssembler _masm(&cb); | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3124 for (int i = 0; i < _constants.length(); i++) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3125 Constant con = _constants.at(i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3126 address constant_addr; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3127 switch (con.type()) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3128 case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3129 case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3130 case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3131 case T_OBJECT: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3132 jobject obj = con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3133 int oop_index = _masm.oop_recorder()->find_index(obj); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3134 constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3135 break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3136 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3137 case T_ADDRESS: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3138 address addr = (address) con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3139 constant_addr = _masm.address_constant(addr); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3140 break; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3141 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3142 // We use T_VOID as marker for jump-table entries (labels) which |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3143 // need an internal word relocation. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3144 case T_VOID: { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3145 MachConstantNode* n = (MachConstantNode*) con.get_jobject(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3146 // Fill the jump-table with a dummy word. The real value is |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3147 // filled in later in fill_jump_table. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3148 address dummy = (address) n; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3149 constant_addr = _masm.address_constant(dummy); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3150 // Expand jump-table |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3151 for (uint i = 1; i < n->outcnt(); i++) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3152 address temp_addr = _masm.address_constant(dummy + i); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3153 assert(temp_addr, "consts section too small"); |
2008 | 3154 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3155 break; |
2008 | 3156 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3157 case T_METADATA: { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3158 Metadata* obj = con.get_metadata(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3159 int metadata_index = _masm.oop_recorder()->find_index(obj); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3160 constant_addr = _masm.address_constant((address) obj, metadata_Relocation::spec(metadata_index)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3161 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3162 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3163 default: ShouldNotReachHere(); |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3164 } |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3165 assert(constant_addr, "consts section too small"); |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3166 assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); |
2008 | 3167 } |
3168 } | |
3169 | |
3170 int Compile::ConstantTable::find_offset(Constant& con) const { | |
3171 int idx = _constants.find(con); | |
3172 assert(idx != -1, "constant must be in constant table"); | |
3173 int offset = _constants.at(idx).offset(); | |
3174 assert(offset != -1, "constant table not emitted yet?"); | |
3175 return offset; | |
3176 } | |
3177 | |
3178 void Compile::ConstantTable::add(Constant& con) { | |
3179 if (con.can_be_reused()) { | |
3180 int idx = _constants.find(con); | |
3181 if (idx != -1 && _constants.at(idx).can_be_reused()) { | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3182 _constants.adr_at(idx)->inc_freq(con.freq()); // increase the frequency by the current value |
2008 | 3183 return; |
3184 } | |
3185 } | |
3186 (void) _constants.append(con); | |
3187 } | |
3188 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3189 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) { |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3190 Block* b = Compile::current()->cfg()->_bbs[n->_idx]; |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3191 Constant con(type, value, b->_freq); |
2008 | 3192 add(con); |
3193 return con; | |
3194 } | |
3195 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3196 Compile::Constant Compile::ConstantTable::add(Metadata* metadata) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3197 Constant con(metadata); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3198 add(con); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3199 return con; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3200 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3201 |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3202 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, MachOper* oper) { |
2008 | 3203 jvalue value; |
3204 BasicType type = oper->type()->basic_type(); | |
3205 switch (type) { | |
3206 case T_LONG: value.j = oper->constantL(); break; | |
3207 case T_FLOAT: value.f = oper->constantF(); break; | |
3208 case T_DOUBLE: value.d = oper->constantD(); break; | |
3209 case T_OBJECT: | |
3210 case T_ADDRESS: value.l = (jobject) oper->constant(); break; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3211 case T_METADATA: return add((Metadata*)oper->constant()); break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6619
diff
changeset
|
3212 default: guarantee(false, err_msg_res("unhandled type: %s", type2name(type))); |
2008 | 3213 } |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3214 return add(n, type, value); |
2008 | 3215 } |
3216 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3217 Compile::Constant Compile::ConstantTable::add_jump_table(MachConstantNode* n) { |
2008 | 3218 jvalue value; |
3219 // We can use the node pointer here to identify the right jump-table | |
3220 // as this method is called from Compile::Fill_buffer right before | |
3221 // the MachNodes are emitted and the jump-table is filled (means the | |
3222 // MachNode pointers do not change anymore). | |
3223 value.l = (jobject) n; | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3224 Constant con(T_VOID, value, next_jump_table_freq(), false); // Labels of a jump-table cannot be reused. |
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3225 add(con); |
2008 | 3226 return con; |
3227 } | |
3228 | |
3229 void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { | |
3230 // If called from Compile::scratch_emit_size do nothing. | |
3231 if (Compile::current()->in_scratch_emit_size()) return; | |
3232 | |
3233 assert(labels.is_nonempty(), "must be"); | |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3234 assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt())); |
2008 | 3235 |
3236 // Since MachConstantNode::constant_offset() also contains | |
3237 // table_base_offset() we need to subtract the table_base_offset() | |
3238 // to get the plain offset into the constant table. | |
3239 int offset = n->constant_offset() - table_base_offset(); | |
3240 | |
3241 MacroAssembler _masm(&cb); | |
3242 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); | |
3243 | |
4114
6729bbc1fcd6
7003454: order constants in constant table by number of references in code
twisti
parents:
4064
diff
changeset
|
3244 for (uint i = 0; i < n->outcnt(); i++) { |
2008 | 3245 address* constant_addr = &jump_table_base[i]; |
6268
6c5b7a6becc8
7187454: stack overflow in C2 compiler thread on Solaris x86
kvn
parents:
6179
diff
changeset
|
3246 assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i))); |
2008 | 3247 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); |
3248 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); | |
3249 } | |
3250 } |