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