Mercurial > hg > truffle
annotate src/share/vm/opto/idealKit.hpp @ 1145:e018e6884bd8
6631166: CMS: better heuristics when combatting fragmentation
Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Wed, 23 Dec 2009 09:23:54 -0800 |
parents | a1423fe86a18 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
948 | 2 * Copyright 2005-2009 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 //----------------------------------------------------------------------------- | |
26 //----------------------------IdealKit----------------------------------------- | |
27 // Set of utilities for creating control flow and scalar SSA data flow. | |
28 // Control: | |
29 // if_then(left, relop, right) | |
30 // else_ (optional) | |
31 // end_if | |
32 // loop(iv variable, initial, relop, limit) | |
33 // - sets iv to initial for first trip | |
34 // - exits when relation on limit is true | |
35 // - the values of initial and limit should be loop invariant | |
36 // - no increment, must be explicitly coded | |
37 // - final value of iv is available after end_loop (until dead()) | |
38 // end_loop | |
39 // make_label(number of gotos) | |
40 // goto_(label) | |
41 // bind(label) | |
42 // Data: | |
43 // ConI(integer constant) - create an integer constant | |
44 // set(variable, value) - assignment | |
45 // value(variable) - reference value | |
46 // dead(variable) - variable's value is no longer live | |
47 // increment(variable, value) - increment variable by value | |
48 // simple operations: AddI, SubI, AndI, LShiftI, etc. | |
49 // Example: | |
50 // Node* limit = ?? | |
51 // IdealVariable i(kit), j(kit); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
52 // declarations_done(); |
0 | 53 // Node* exit = make_label(1); // 1 goto |
54 // set(j, ConI(0)); | |
55 // loop(i, ConI(0), BoolTest::lt, limit); { | |
56 // if_then(value(i), BoolTest::gt, ConI(5)) { | |
57 // set(j, ConI(1)); | |
58 // goto_(exit); dead(i); | |
59 // } end_if(); | |
60 // increment(i, ConI(1)); | |
61 // } end_loop(); dead(i); | |
62 // bind(exit); | |
63 // | |
64 // See string_indexOf for a more complete example. | |
65 | |
66 class IdealKit; | |
67 | |
68 // Variable definition for IdealKit | |
69 class IdealVariable: public StackObj { | |
70 friend class IdealKit; | |
71 private: | |
72 int _id; | |
73 void set_id(int id) { _id = id; } | |
74 public: | |
75 IdealVariable(IdealKit &k); | |
76 int id() { assert(has_id(),"uninitialized id"); return _id; } | |
77 bool has_id() { return _id >= 0; } | |
78 }; | |
79 | |
80 class IdealKit: public StackObj { | |
81 friend class IdealVariable; | |
82 // The main state (called a cvstate for Control and Variables) | |
83 // contains both the current values of the variables and the | |
84 // current set of predecessor control edges. The variable values | |
85 // are managed via a Node [in(1)..in(_var_ct)], and the predecessor | |
86 // control edges managed via a RegionNode. The in(0) of the Node | |
87 // for variables points to the RegionNode for the control edges. | |
88 protected: | |
89 Compile * const C; | |
90 PhaseGVN &_gvn; | |
91 GrowableArray<Node*>* _pending_cvstates; // stack of cvstates | |
92 GrowableArray<Node*>* _delay_transform; // delay invoking gvn.transform until drain | |
93 Node* _cvstate; // current cvstate (control, memory and variables) | |
94 uint _var_ct; // number of variables | |
95 bool _delay_all_transforms; // flag forcing all transforms to be delayed | |
96 Node* _initial_ctrl; // saves initial control until variables declared | |
97 Node* _initial_memory; // saves initial memory until variables declared | |
98 | |
99 PhaseGVN& gvn() const { return _gvn; } | |
100 // Create a new cvstate filled with nulls | |
101 Node* new_cvstate(); // Create a new cvstate | |
102 Node* cvstate() { return _cvstate; } // current cvstate | |
103 Node* copy_cvstate(); // copy current cvstate | |
104 | |
105 void set_memory(Node* mem, uint alias_idx ); | |
106 void do_memory_merge(Node* merging, Node* join); | |
107 void clear(Node* m); // clear a cvstate | |
108 void stop() { clear(_cvstate); } // clear current cvstate | |
109 Node* delay_transform(Node* n); | |
110 Node* transform(Node* n); // gvn.transform or push node on delay list | |
111 Node* promote_to_phi(Node* n, Node* reg);// Promote "n" to a phi on region "reg" | |
112 bool was_promoted_to_phi(Node* n, Node* reg) { | |
113 return (n->is_Phi() && n->in(0) == reg); | |
114 } | |
115 void declare(IdealVariable* v) { v->set_id(_var_ct++); } | |
116 // This declares the position where vars are kept in the cvstate | |
117 // For some degree of consistency we use the TypeFunc enum to | |
118 // soak up spots in the inputs even though we only use early Control | |
119 // and Memory slots. (So far.) | |
120 static const uint first_var; // = TypeFunc::Parms + 1; | |
121 | |
122 #ifdef ASSERT | |
123 enum State { NullS=0, BlockS=1, LoopS=2, IfThenS=4, ElseS=8, EndifS= 16 }; | |
124 GrowableArray<int>* _state; | |
125 State state() { return (State)(_state->top()); } | |
126 #endif | |
127 | |
128 // Users should not care about slices only MergedMem so no access for them. | |
129 Node* memory(uint alias_idx); | |
130 | |
131 public: | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
132 IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false, bool has_declarations = false); |
0 | 133 ~IdealKit() { |
134 stop(); | |
135 drain_delay_transform(); | |
136 } | |
137 // Control | |
138 Node* ctrl() { return _cvstate->in(TypeFunc::Control); } | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
139 void set_ctrl(Node* ctrl) { _cvstate->set_req(TypeFunc::Control, ctrl); } |
0 | 140 Node* top() { return C->top(); } |
141 MergeMemNode* merged_memory() { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); } | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
142 void set_all_memory(Node* mem) { _cvstate->set_req(TypeFunc::Memory, mem); } |
0 | 143 void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); } |
144 Node* value(IdealVariable& v) { return _cvstate->in(first_var + v.id()); } | |
145 void dead(IdealVariable& v) { set(v, (Node*)NULL); } | |
146 void if_then(Node* left, BoolTest::mask relop, Node* right, | |
147 float prob = PROB_FAIR, float cnt = COUNT_UNKNOWN, | |
148 bool push_new_state = true); | |
149 void else_(); | |
150 void end_if(); | |
151 void loop(IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit, | |
152 float prob = PROB_LIKELY(0.9), float cnt = COUNT_UNKNOWN); | |
153 void end_loop(); | |
154 Node* make_label(int goto_ct); | |
155 void bind(Node* lab); | |
156 void goto_(Node* lab, bool bind = false); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
157 void declarations_done(); |
0 | 158 void drain_delay_transform(); |
159 | |
160 Node* IfTrue(IfNode* iff) { return transform(new (C,1) IfTrueNode(iff)); } | |
161 Node* IfFalse(IfNode* iff) { return transform(new (C,1) IfFalseNode(iff)); } | |
162 | |
163 // Data | |
164 Node* ConI(jint k) { return (Node*)gvn().intcon(k); } | |
165 Node* makecon(const Type *t) const { return _gvn.makecon(t); } | |
166 | |
167 Node* AddI(Node* l, Node* r) { return transform(new (C,3) AddINode(l, r)); } | |
168 Node* SubI(Node* l, Node* r) { return transform(new (C,3) SubINode(l, r)); } | |
169 Node* AndI(Node* l, Node* r) { return transform(new (C,3) AndINode(l, r)); } | |
170 Node* MaxI(Node* l, Node* r) { return transform(new (C,3) MaxINode(l, r)); } | |
171 Node* LShiftI(Node* l, Node* r) { return transform(new (C,3) LShiftINode(l, r)); } | |
172 Node* CmpI(Node* l, Node* r) { return transform(new (C,3) CmpINode(l, r)); } | |
173 Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C,2) BoolNode(cmp, relop)); } | |
174 void increment(IdealVariable& v, Node* j) { set(v, AddI(value(v), j)); } | |
175 void decrement(IdealVariable& v, Node* j) { set(v, SubI(value(v), j)); } | |
176 | |
177 Node* CmpL(Node* l, Node* r) { return transform(new (C,3) CmpLNode(l, r)); } | |
178 | |
179 // TLS | |
180 Node* thread() { return gvn().transform(new (C, 1) ThreadLocalNode()); } | |
181 | |
182 // Pointers | |
183 Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C,4) AddPNode(base, ptr, off)); } | |
184 Node* CmpP(Node* l, Node* r) { return transform(new (C,3) CmpPNode(l, r)); } | |
185 #ifdef _LP64 | |
186 Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorLNode(l, r)); } | |
187 #else // _LP64 | |
188 Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorINode(l, r)); } | |
189 #endif // _LP64 | |
190 Node* URShiftX(Node* l, Node* r) { return transform(new (C,3) URShiftXNode(l, r)); } | |
191 Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } | |
192 Node* CastPX(Node* ctl, Node* p) { return transform(new (C,2) CastP2XNode(ctl, p)); } | |
193 // Add a fixed offset to a pointer | |
194 Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset); | |
195 | |
196 // Memory operations | |
197 | |
198 // This is the base version which is given an alias index. | |
199 Node* load(Node* ctl, | |
200 Node* adr, | |
201 const Type* t, | |
202 BasicType bt, | |
203 int adr_idx, | |
204 bool require_atomic_access = false); | |
205 | |
206 // Return the new StoreXNode | |
207 Node* store(Node* ctl, | |
208 Node* adr, | |
209 Node* val, | |
210 BasicType bt, | |
211 int adr_idx, | |
212 bool require_atomic_access = false); | |
213 | |
214 // Store a card mark ordered after store_oop | |
215 Node* storeCM(Node* ctl, | |
216 Node* adr, | |
217 Node* val, | |
218 Node* oop_store, | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
851
diff
changeset
|
219 int oop_adr_idx, |
0 | 220 BasicType bt, |
221 int adr_idx); | |
222 | |
223 // Trivial call | |
224 void make_leaf_call(const TypeFunc *slow_call_type, | |
225 address slow_call, | |
226 const char *leaf_name, | |
227 Node* parm0, | |
228 Node* parm1 = NULL, | |
229 Node* parm2 = NULL); | |
230 }; |