Mercurial > hg > truffle
annotate src/share/vm/opto/live.cpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 55fb97c4c58d |
children | 4ca6dc0799b6 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12269
diff
changeset
|
2 * Copyright (c) 1997, 2013, 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:
628
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
628
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:
628
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "memory/allocation.inline.hpp" | |
27 #include "opto/callnode.hpp" | |
28 #include "opto/chaitin.hpp" | |
29 #include "opto/live.hpp" | |
30 #include "opto/machnode.hpp" | |
0 | 31 |
32 | |
33 // Compute live-in/live-out. We use a totally incremental algorithm. The LIVE | |
34 // problem is monotonic. The steady-state solution looks like this: pull a | |
35 // block from the worklist. It has a set of delta's - values which are newly | |
36 // live-in from the block. Push these to the live-out sets of all predecessor | |
37 // blocks. At each predecessor, the new live-out values are ANDed with what is | |
38 // already live-out (extra stuff is added to the live-out sets). Then the | |
39 // remaining new live-out values are ANDed with what is locally defined. | |
40 // Leftover bits become the new live-in for the predecessor block, and the pred | |
41 // block is put on the worklist. | |
42 // The locally live-in stuff is computed once and added to predecessor | |
605 | 43 // live-out sets. This separate compilation is done in the outer loop below. |
10111 | 44 PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) : Phase(LIVE), _cfg(cfg), _names(names), _arena(arena), _live(0) { |
0 | 45 } |
46 | |
47 void PhaseLive::compute(uint maxlrg) { | |
48 _maxlrg = maxlrg; | |
49 _worklist = new (_arena) Block_List(); | |
50 | |
51 // Init the sparse live arrays. This data is live on exit from here! | |
52 // The _live info is the live-out info. | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
53 _live = (IndexSet*)_arena->Amalloc(sizeof(IndexSet) * _cfg.number_of_blocks()); |
0 | 54 uint i; |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
55 for (i = 0; i < _cfg.number_of_blocks(); i++) { |
0 | 56 _live[i].initialize(_maxlrg); |
57 } | |
58 | |
59 // Init the sparse arrays for delta-sets. | |
60 ResourceMark rm; // Nuke temp storage on exit | |
61 | |
62 // Does the memory used by _defs and _deltas get reclaimed? Does it matter? TT | |
63 | |
64 // Array of values defined locally in blocks | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
65 _defs = NEW_RESOURCE_ARRAY(IndexSet,_cfg.number_of_blocks()); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
66 for (i = 0; i < _cfg.number_of_blocks(); i++) { |
0 | 67 _defs[i].initialize(_maxlrg); |
68 } | |
69 | |
70 // Array of delta-set pointers, indexed by block pre_order-1. | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
71 _deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks()); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
72 memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks()); |
0 | 73 |
74 _free_IndexSet = NULL; | |
75 | |
76 // Blocks having done pass-1 | |
77 VectorSet first_pass(Thread::current()->resource_area()); | |
78 | |
79 // Outer loop: must compute local live-in sets and push into predecessors. | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
80 for (uint j = _cfg.number_of_blocks(); j > 0; j--) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
81 Block* block = _cfg.get_block(j - 1); |
0 | 82 |
83 // Compute the local live-in set. Start with any new live-out bits. | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
84 IndexSet* use = getset(block); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
85 IndexSet* def = &_defs[block->_pre_order-1]; |
0 | 86 DEBUG_ONLY(IndexSet *def_outside = getfreeset();) |
87 uint i; | |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
88 for (i = block->number_of_nodes(); i > 1; i--) { |
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
89 Node* n = block->get_node(i-1); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
90 if (n->is_Phi()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
91 break; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
92 } |
0 | 93 |
12254
8c83625e3a53
8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents:
12167
diff
changeset
|
94 uint r = _names.at(n->_idx); |
0 | 95 assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block"); |
96 def->insert( r ); | |
97 use->remove( r ); | |
98 uint cnt = n->req(); | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
99 for (uint k = 1; k < cnt; k++) { |
0 | 100 Node *nk = n->in(k); |
101 uint nkidx = nk->_idx; | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
102 if (_cfg.get_block_for_node(nk) != block) { |
12254
8c83625e3a53
8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents:
12167
diff
changeset
|
103 uint u = _names.at(nkidx); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
104 use->insert(u); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
105 DEBUG_ONLY(def_outside->insert(u);) |
0 | 106 } |
107 } | |
108 } | |
109 #ifdef ASSERT | |
110 def_outside->set_next(_free_IndexSet); | |
111 _free_IndexSet = def_outside; // Drop onto free list | |
112 #endif | |
113 // Remove anything defined by Phis and the block start instruction | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
114 for (uint k = i; k > 0; k--) { |
12254
8c83625e3a53
8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents:
12167
diff
changeset
|
115 uint r = _names.at(block->get_node(k - 1)->_idx); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
116 def->insert(r); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
117 use->remove(r); |
0 | 118 } |
119 | |
120 // Push these live-in things to predecessors | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
121 for (uint l = 1; l < block->num_preds(); l++) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
122 Block* p = _cfg.get_block_for_node(block->pred(l)); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
123 add_liveout(p, use, first_pass); |
0 | 124 |
125 // PhiNode uses go in the live-out set of prior blocks. | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
126 for (uint k = i; k > 0; k--) { |
12254
8c83625e3a53
8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents:
12167
diff
changeset
|
127 add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
128 } |
0 | 129 } |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
130 freeset(block); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
131 first_pass.set(block->_pre_order); |
0 | 132 |
133 // Inner loop: blocks that picked up new live-out values to be propagated | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
134 while (_worklist->size()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
135 Block* block = _worklist->pop(); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
136 IndexSet *delta = getset(block); |
0 | 137 assert( delta->count(), "missing delta set" ); |
138 | |
139 // Add new-live-in to predecessors live-out sets | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
140 for (uint l = 1; l < block->num_preds(); l++) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
141 Block* predecessor = _cfg.get_block_for_node(block->pred(l)); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
142 add_liveout(predecessor, delta, first_pass); |
12023
d1034bd8cefc
8022284: Hide internal data structure in PhaseCFG
adlertz
parents:
10111
diff
changeset
|
143 } |
0 | 144 |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
145 freeset(block); |
0 | 146 } // End of while-worklist-not-empty |
147 | |
148 } // End of for-all-blocks-outer-loop | |
149 | |
150 // We explicitly clear all of the IndexSets which we are about to release. | |
151 // This allows us to recycle their internal memory into IndexSet's free list. | |
152 | |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
153 for (i = 0; i < _cfg.number_of_blocks(); i++) { |
0 | 154 _defs[i].clear(); |
155 if (_deltas[i]) { | |
156 // Is this always true? | |
157 _deltas[i]->clear(); | |
158 } | |
159 } | |
160 IndexSet *free = _free_IndexSet; | |
161 while (free != NULL) { | |
162 IndexSet *temp = free; | |
163 free = free->next(); | |
164 temp->clear(); | |
165 } | |
166 | |
167 } | |
168 | |
169 #ifndef PRODUCT | |
170 void PhaseLive::stats(uint iters) const { | |
171 } | |
172 #endif | |
173 | |
174 // Get an IndexSet for a block. Return existing one, if any. Make a new | |
175 // empty one if a prior one does not exist. | |
176 IndexSet *PhaseLive::getset( Block *p ) { | |
177 IndexSet *delta = _deltas[p->_pre_order-1]; | |
178 if( !delta ) // Not on worklist? | |
179 // Get a free set; flag as being on worklist | |
180 delta = _deltas[p->_pre_order-1] = getfreeset(); | |
181 return delta; // Return set of new live-out items | |
182 } | |
183 | |
184 // Pull from free list, or allocate. Internal allocation on the returned set | |
185 // is always from thread local storage. | |
186 IndexSet *PhaseLive::getfreeset( ) { | |
187 IndexSet *f = _free_IndexSet; | |
188 if( !f ) { | |
189 f = new IndexSet; | |
190 // f->set_arena(Thread::current()->resource_area()); | |
191 f->initialize(_maxlrg, Thread::current()->resource_area()); | |
192 } else { | |
193 // Pull from free list | |
194 _free_IndexSet = f->next(); | |
195 //f->_cnt = 0; // Reset to empty | |
196 // f->set_arena(Thread::current()->resource_area()); | |
197 f->initialize(_maxlrg, Thread::current()->resource_area()); | |
198 } | |
199 return f; | |
200 } | |
201 | |
202 // Free an IndexSet from a block. | |
203 void PhaseLive::freeset( const Block *p ) { | |
204 IndexSet *f = _deltas[p->_pre_order-1]; | |
205 f->set_next(_free_IndexSet); | |
206 _free_IndexSet = f; // Drop onto free list | |
207 _deltas[p->_pre_order-1] = NULL; | |
208 } | |
209 | |
210 // Add a live-out value to a given blocks live-out set. If it is new, then | |
211 // also add it to the delta set and stick the block on the worklist. | |
212 void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) { | |
213 IndexSet *live = &_live[p->_pre_order-1]; | |
214 if( live->insert(r) ) { // If actually inserted... | |
215 // We extended the live-out set. See if the value is generated locally. | |
216 // If it is not, then we must extend the live-in set. | |
217 if( !_defs[p->_pre_order-1].member( r ) ) { | |
218 if( !_deltas[p->_pre_order-1] && // Not on worklist? | |
219 first_pass.test(p->_pre_order) ) | |
220 _worklist->push(p); // Actually go on worklist if already 1st pass | |
221 getset(p)->insert(r); | |
222 } | |
223 } | |
224 } | |
225 | |
226 // Add a vector of live-out values to a given blocks live-out set. | |
227 void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) { | |
228 IndexSet *live = &_live[p->_pre_order-1]; | |
229 IndexSet *defs = &_defs[p->_pre_order-1]; | |
230 IndexSet *on_worklist = _deltas[p->_pre_order-1]; | |
231 IndexSet *delta = on_worklist ? on_worklist : getfreeset(); | |
232 | |
233 IndexSetIterator elements(lo); | |
234 uint r; | |
235 while ((r = elements.next()) != 0) { | |
236 if( live->insert(r) && // If actually inserted... | |
237 !defs->member( r ) ) // and not defined locally | |
238 delta->insert(r); // Then add to live-in set | |
239 } | |
240 | |
241 if( delta->count() ) { // If actually added things | |
242 _deltas[p->_pre_order-1] = delta; // Flag as on worklist now | |
243 if( !on_worklist && // Not on worklist? | |
244 first_pass.test(p->_pre_order) ) | |
245 _worklist->push(p); // Actually go on worklist if already 1st pass | |
246 } else { // Nothing there; just free it | |
247 delta->set_next(_free_IndexSet); | |
248 _free_IndexSet = delta; // Drop onto free list | |
249 } | |
250 } | |
251 | |
252 #ifndef PRODUCT | |
253 // Dump the live-out set for a block | |
254 void PhaseLive::dump( const Block *b ) const { | |
255 tty->print("Block %d: ",b->_pre_order); | |
256 tty->print("LiveOut: "); _live[b->_pre_order-1].dump(); | |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
257 uint cnt = b->number_of_nodes(); |
0 | 258 for( uint i=0; i<cnt; i++ ) { |
12254
8c83625e3a53
8024646: Remove LRG_List container, replace it with GrowableArray
adlertz
parents:
12167
diff
changeset
|
259 tty->print("L%d/", _names.at(b->get_node(i)->_idx)); |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
260 b->get_node(i)->dump(); |
0 | 261 } |
262 tty->print("\n"); | |
263 } | |
264 | |
265 // Verify that base pointers and derived pointers are still sane. | |
266 void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const { | |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
267 #ifdef ASSERT |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
268 Unique_Node_List worklist(a); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
269 for (uint i = 0; i < _cfg.number_of_blocks(); i++) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
270 Block* block = _cfg.get_block(i); |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
271 for (uint j = block->end_idx() + 1; j > 1; j--) { |
12167
650868c062a9
8023691: Create interface for nodes in class Block
adlertz
parents:
12071
diff
changeset
|
272 Node* n = block->get_node(j-1); |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
273 if (n->is_Phi()) { |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
274 break; |
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
275 } |
0 | 276 // Found a safepoint? |
12071
adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
adlertz
parents:
12023
diff
changeset
|
277 if (n->is_MachSafePoint()) { |
0 | 278 MachSafePointNode *sfpt = n->as_MachSafePoint(); |
279 JVMState* jvms = sfpt->jvms(); | |
280 if (jvms != NULL) { | |
281 // Now scan for a live derived pointer | |
282 if (jvms->oopoff() < sfpt->req()) { | |
283 // Check each derived/base pair | |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
284 for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) { |
0 | 285 Node *check = sfpt->in(idx); |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
286 bool is_derived = ((idx - jvms->oopoff()) & 1) == 0; |
0 | 287 // search upwards through spills and spill phis for AddP |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
288 worklist.clear(); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
289 worklist.push(check); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
290 uint k = 0; |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
291 while( k < worklist.size() ) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
292 check = worklist.at(k); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
293 assert(check,"Bad base or derived pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
294 // See PhaseChaitin::find_base_for_derived() for all cases. |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
295 int isc = check->is_Copy(); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
296 if( isc ) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
297 worklist.push(check->in(isc)); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
298 } else if( check->is_Phi() ) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
299 for (uint m = 1; m < check->req(); m++) |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
300 worklist.push(check->in(m)); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
301 } else if( check->is_Con() ) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
302 if (is_derived) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
303 // Derived is NULL+offset |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
304 assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
305 } else { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
306 assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
307 // Base either ConP(NULL) or loadConP |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
308 if (check->is_Mach()) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
309 assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
310 } else { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
311 assert(check->Opcode() == Op_ConP && |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
312 check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
313 } |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
314 } |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
315 } else if( check->bottom_type()->is_ptr()->_offset == 0 ) { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
316 if(check->is_Proj() || check->is_Mach() && |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
317 (check->as_Mach()->ideal_Opcode() == Op_CreateEx || |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
318 check->as_Mach()->ideal_Opcode() == Op_ThreadLocal || |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
319 check->as_Mach()->ideal_Opcode() == Op_CMoveP || |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
320 check->as_Mach()->ideal_Opcode() == Op_CheckCastPP || |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
321 #ifdef _LP64 |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
322 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP || |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
323 UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || |
12226
7944aba7ba41
8015107: NPG: Use consistent naming for metaspace concepts
ehelin
parents:
12167
diff
changeset
|
324 UseCompressedClassPointers && check->as_Mach()->ideal_Opcode() == Op_DecodeNKlass || |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
325 #endif |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
326 check->as_Mach()->ideal_Opcode() == Op_LoadP || |
566
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
327 check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) { |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
328 // Valid nodes |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
329 } else { |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
330 check->dump(); |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
331 assert(false,"Bad base or derived pointer"); |
566
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
332 } |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
333 } else { |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
334 assert(is_derived,"Bad base pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
335 assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer"); |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
336 } |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
337 k++; |
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
338 assert(k < 100000,"Derived pointer checking in infinite loop"); |
0 | 339 } // End while |
340 } | |
341 } // End of check for derived pointers | |
342 } // End of Kcheck for debug info | |
343 } // End of if found a safepoint | |
344 } // End of forall instructions in block | |
345 } // End of forall blocks | |
550
96964ebdb154
6782232: assert("CreateEx must be first instruction in block" )
kvn
parents:
0
diff
changeset
|
346 #endif |
0 | 347 } |
566
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
348 |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
349 // Verify that graphs and base pointers are still sane. |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
350 void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const { |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
351 #ifdef ASSERT |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
352 if( VerifyOpto || VerifyRegisterAllocator ) { |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
353 _cfg.verify(); |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
354 verify_base_ptrs(a); |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
355 if(verify_ifg) |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
356 _ifg->verify(this); |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
357 } |
0 | 358 #endif |
566
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
359 } |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
360 |
91263420e1c6
6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents:
550
diff
changeset
|
361 #endif |