Mercurial > hg > truffle
annotate src/share/vm/c1/c1_ValueMap.hpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 7eca5de9e0b6 |
children | b9a9ed0f8eeb |
rev | line source |
---|---|
0 | 1 /* |
2166
403dc4c1d7f5
6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents:
1972
diff
changeset
|
2 * Copyright (c) 1999, 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:
470
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
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:
470
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_C1_C1_VALUEMAP_HPP |
26 #define SHARE_VM_C1_C1_VALUEMAP_HPP | |
27 | |
28 #include "c1/c1_Instruction.hpp" | |
29 #include "c1/c1_ValueSet.hpp" | |
30 #include "memory/allocation.hpp" | |
31 | |
0 | 32 class ValueMapEntry: public CompilationResourceObj { |
33 private: | |
34 intx _hash; | |
35 Value _value; | |
36 int _nesting; | |
37 ValueMapEntry* _next; | |
38 | |
39 public: | |
40 ValueMapEntry(intx hash, Value value, int nesting, ValueMapEntry* next) | |
41 : _hash(hash) | |
42 , _value(value) | |
43 , _nesting(nesting) | |
44 , _next(next) | |
45 { | |
46 } | |
47 | |
48 intx hash() { return _hash; } | |
49 Value value() { return _value; } | |
50 int nesting() { return _nesting; } | |
51 ValueMapEntry* next() { return _next; } | |
52 | |
53 void set_next(ValueMapEntry* next) { _next = next; } | |
54 }; | |
55 | |
56 define_array(ValueMapEntryArray, ValueMapEntry*) | |
57 define_stack(ValueMapEntryList, ValueMapEntryArray) | |
58 | |
59 // ValueMap implements nested hash tables for value numbering. It | |
60 // maintains a set _killed_values which represents the instructions | |
61 // which have been killed so far and an array of linked lists of | |
62 // ValueMapEntries names _entries. Each ValueMapEntry has a nesting | |
63 // which indicates what ValueMap nesting it belongs to. Higher | |
64 // nesting values are always before lower values in the linked list. | |
65 // This allows cloning of parent ValueMaps by simply copying the heads | |
66 // of the list. _entry_count represents the number of reachable | |
67 // entries in the ValueMap. A ValueMap is only allowed to mutate | |
68 // ValueMapEntries with the same nesting level. Adding or removing | |
69 // entries at the current nesting level requires updating | |
70 // _entry_count. Elements in the parent's list that get killed can be | |
71 // skipped if they are at the head of the list by simply moving to the | |
72 // next element in the list and decrementing _entry_count. | |
73 | |
74 class ValueMap: public CompilationResourceObj { | |
75 private: | |
76 int _nesting; | |
77 ValueMapEntryArray _entries; | |
78 ValueSet _killed_values; | |
79 int _entry_count; | |
80 | |
81 int nesting() { return _nesting; } | |
82 bool is_local_value_numbering() { return _nesting == 0; } | |
83 bool is_global_value_numbering() { return _nesting > 0; } | |
84 | |
85 int entry_count() { return _entry_count; } | |
86 int size() { return _entries.length(); } | |
87 ValueMapEntry* entry_at(int i) { return _entries.at(i); } | |
88 | |
89 // calculates the index of a hash value in a hash table of size n | |
90 int entry_index(intx hash, int n) { return (unsigned int)hash % n; } | |
91 | |
92 // if entry_count > size_threshold, the size of the hash table is increased | |
93 int size_threshold() { return size(); } | |
94 | |
95 // management of the killed-bitset for global value numbering | |
96 void kill_value(Value v) { if (is_global_value_numbering()) _killed_values.put(v); } | |
97 bool is_killed(Value v) { if (is_global_value_numbering()) return _killed_values.contains(v); else return false; } | |
98 | |
99 // helper functions | |
100 void increase_table_size(); | |
101 | |
102 #ifndef PRODUCT | |
103 static int _number_of_finds; | |
104 static int _number_of_hits; | |
105 static int _number_of_kills; | |
106 #endif // PRODUCT | |
107 | |
108 public: | |
109 // creation | |
110 ValueMap(); // empty value map | |
111 ValueMap(ValueMap* old); // value map with increased nesting | |
112 | |
113 // manipulation | |
114 Value find_insert(Value x); | |
115 | |
116 void kill_memory(); | |
6618
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
117 void kill_field(ciField* field, bool all_offsets); |
0 | 118 void kill_array(ValueType* type); |
119 void kill_exception(); | |
120 void kill_map(ValueMap* map); | |
121 void kill_all(); | |
122 | |
123 #ifndef PRODUCT | |
124 // debugging/printing | |
125 void print(); | |
126 | |
127 static void reset_statistics(); | |
128 static void print_statistics(); | |
129 #endif | |
130 }; | |
131 | |
132 define_array(ValueMapArray, ValueMap*) | |
133 | |
134 | |
135 class ValueNumberingVisitor: public InstructionVisitor { | |
136 protected: | |
137 // called by visitor functions for instructions that kill values | |
138 virtual void kill_memory() = 0; | |
6618
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
139 virtual void kill_field(ciField* field, bool all_offsets) = 0; |
0 | 140 virtual void kill_array(ValueType* type) = 0; |
141 | |
142 // visitor functions | |
459 | 143 void do_StoreField (StoreField* x) { |
6132
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
144 if (x->is_init_point() || // putstatic is an initialization point so treat it as a wide kill |
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
145 // This is actually too strict and the JMM doesn't require |
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
146 // this in all cases (e.g. load a; volatile store b; load a) |
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
147 // but possible future optimizations might require this. |
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
148 x->field()->is_volatile()) { |
459 | 149 kill_memory(); |
150 } else { | |
6618
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
151 kill_field(x->field(), x->needs_patching()); |
459 | 152 } |
153 } | |
154 void do_StoreIndexed (StoreIndexed* x) { kill_array(x->type()); } | |
155 void do_MonitorEnter (MonitorEnter* x) { kill_memory(); } | |
156 void do_MonitorExit (MonitorExit* x) { kill_memory(); } | |
157 void do_Invoke (Invoke* x) { kill_memory(); } | |
158 void do_UnsafePutRaw (UnsafePutRaw* x) { kill_memory(); } | |
159 void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); } | |
6795
7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
roland
parents:
6618
diff
changeset
|
160 void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { kill_memory(); } |
459 | 161 void do_Intrinsic (Intrinsic* x) { if (!x->preserves_state()) kill_memory(); } |
0 | 162 |
459 | 163 void do_Phi (Phi* x) { /* nothing to do */ } |
164 void do_Local (Local* x) { /* nothing to do */ } | |
165 void do_Constant (Constant* x) { /* nothing to do */ } | |
166 void do_LoadField (LoadField* x) { | |
6132
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
167 if (x->is_init_point() || // getstatic is an initialization point so treat it as a wide kill |
4d8787136e08
7170145: C1 doesn't respect the JMM with volatile field loads
twisti
parents:
4966
diff
changeset
|
168 x->field()->is_volatile()) { // the JMM requires this |
459 | 169 kill_memory(); |
170 } | |
171 } | |
172 void do_ArrayLength (ArrayLength* x) { /* nothing to do */ } | |
173 void do_LoadIndexed (LoadIndexed* x) { /* nothing to do */ } | |
174 void do_NegateOp (NegateOp* x) { /* nothing to do */ } | |
175 void do_ArithmeticOp (ArithmeticOp* x) { /* nothing to do */ } | |
176 void do_ShiftOp (ShiftOp* x) { /* nothing to do */ } | |
177 void do_LogicOp (LogicOp* x) { /* nothing to do */ } | |
178 void do_CompareOp (CompareOp* x) { /* nothing to do */ } | |
179 void do_IfOp (IfOp* x) { /* nothing to do */ } | |
180 void do_Convert (Convert* x) { /* nothing to do */ } | |
181 void do_NullCheck (NullCheck* x) { /* nothing to do */ } | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6132
diff
changeset
|
182 void do_TypeCast (TypeCast* x) { /* nothing to do */ } |
459 | 183 void do_NewInstance (NewInstance* x) { /* nothing to do */ } |
184 void do_NewTypeArray (NewTypeArray* x) { /* nothing to do */ } | |
185 void do_NewObjectArray (NewObjectArray* x) { /* nothing to do */ } | |
186 void do_NewMultiArray (NewMultiArray* x) { /* nothing to do */ } | |
187 void do_CheckCast (CheckCast* x) { /* nothing to do */ } | |
188 void do_InstanceOf (InstanceOf* x) { /* nothing to do */ } | |
189 void do_BlockBegin (BlockBegin* x) { /* nothing to do */ } | |
190 void do_Goto (Goto* x) { /* nothing to do */ } | |
191 void do_If (If* x) { /* nothing to do */ } | |
192 void do_IfInstanceOf (IfInstanceOf* x) { /* nothing to do */ } | |
193 void do_TableSwitch (TableSwitch* x) { /* nothing to do */ } | |
194 void do_LookupSwitch (LookupSwitch* x) { /* nothing to do */ } | |
195 void do_Return (Return* x) { /* nothing to do */ } | |
196 void do_Throw (Throw* x) { /* nothing to do */ } | |
197 void do_Base (Base* x) { /* nothing to do */ } | |
198 void do_OsrEntry (OsrEntry* x) { /* nothing to do */ } | |
199 void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ } | |
200 void do_RoundFP (RoundFP* x) { /* nothing to do */ } | |
201 void do_UnsafeGetRaw (UnsafeGetRaw* x) { /* nothing to do */ } | |
202 void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ } | |
203 void do_UnsafePrefetchRead (UnsafePrefetchRead* x) { /* nothing to do */ } | |
204 void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ } | |
205 void do_ProfileCall (ProfileCall* x) { /* nothing to do */ } | |
2166
403dc4c1d7f5
6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents:
1972
diff
changeset
|
206 void do_ProfileInvoke (ProfileInvoke* x) { /* nothing to do */ }; |
403dc4c1d7f5
6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents:
1972
diff
changeset
|
207 void do_RuntimeCall (RuntimeCall* x) { /* nothing to do */ }; |
4966
701a83c86f28
7120481: storeStore barrier in constructor with final field
jiangli
parents:
2352
diff
changeset
|
208 void do_MemBar (MemBar* x) { /* nothing to do */ }; |
459 | 209 }; |
210 | |
211 | |
212 class ValueNumberingEffects: public ValueNumberingVisitor { | |
213 private: | |
214 ValueMap* _map; | |
215 | |
216 public: | |
217 // implementation for abstract methods of ValueNumberingVisitor | |
6618
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
218 void kill_memory() { _map->kill_memory(); } |
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
219 void kill_field(ciField* field, bool all_offsets) { _map->kill_field(field, all_offsets); } |
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
220 void kill_array(ValueType* type) { _map->kill_array(type); } |
459 | 221 |
222 ValueNumberingEffects(ValueMap* map): _map(map) {} | |
0 | 223 }; |
224 | |
225 | |
226 class GlobalValueNumbering: public ValueNumberingVisitor { | |
227 private: | |
228 ValueMap* _current_map; // value map of current block | |
229 ValueMapArray _value_maps; // list of value maps for all blocks | |
230 | |
231 public: | |
232 // accessors | |
233 ValueMap* current_map() { return _current_map; } | |
234 ValueMap* value_map_of(BlockBegin* block) { return _value_maps.at(block->linear_scan_number()); } | |
235 void set_value_map_of(BlockBegin* block, ValueMap* map) { assert(value_map_of(block) == NULL, ""); _value_maps.at_put(block->linear_scan_number(), map); } | |
236 | |
237 // implementation for abstract methods of ValueNumberingVisitor | |
6618
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
238 void kill_memory() { current_map()->kill_memory(); } |
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
239 void kill_field(ciField* field, bool all_offsets) { current_map()->kill_field(field, all_offsets); } |
0bfcb7a3e12d
7171824: assert(_offset >= 1) failed: illegal call to offset()
roland
parents:
6266
diff
changeset
|
240 void kill_array(ValueType* type) { current_map()->kill_array(type); } |
0 | 241 |
242 // main entry point that performs global value numbering | |
243 GlobalValueNumbering(IR* ir); | |
244 }; | |
1972 | 245 |
246 #endif // SHARE_VM_C1_C1_VALUEMAP_HPP |