annotate src/share/vm/opto/optoreg.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 a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 //------------------------------OptoReg----------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // We eventually need Registers for the Real World. Registers are essentially
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // non-SSA names. A Register is represented as a number. Non-regular values
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // (e.g., Control, Memory, I/O) use the Special register. The actual machine
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // registers (as described in the ADL file for a machine) start at zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // Stack-slots (spill locations) start at the nest Chunk past the last machine
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // register.
a61af66fc99e Initial load
duke
parents:
diff changeset
32 //
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // Note that stack spill-slots are treated as a very large register set.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // They have all the correct properties for a Register: not aliased (unique
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // named). There is some simple mapping from a stack-slot register number
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // to the actual location on the stack; this mapping depends on the calling
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // conventions and is described in the ADL.
a61af66fc99e Initial load
duke
parents:
diff changeset
38 //
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // Note that Name is not enum. C++ standard defines that the range of enum
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // is the range of smallest bit-field that can represent all enumerators
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // declared in the enum. The result of assigning a value to enum is undefined
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // if the value is outside the enumeration's valid range. OptoReg::Name is
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // typedef'ed as int, because it needs to be able to represent spill-slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 //
a61af66fc99e Initial load
duke
parents:
diff changeset
45 class OptoReg VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 friend class C2Compiler;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
49 typedef int Name;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // Chunk 0
a61af66fc99e Initial load
duke
parents:
diff changeset
52 Physical = AdlcVMDeps::Physical, // Start of physical regs
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // A few oddballs at the edge of the world
a61af66fc99e Initial load
duke
parents:
diff changeset
54 Special = -2, // All special (not allocated) values
a61af66fc99e Initial load
duke
parents:
diff changeset
55 Bad = -1 // Not a register
a61af66fc99e Initial load
duke
parents:
diff changeset
56 };
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 static const VMReg opto2vm[REG_COUNT];
a61af66fc99e Initial load
duke
parents:
diff changeset
61 static Name vm2opto[ConcreteRegisterImpl::number_of_registers];
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Stack pointer register
a61af66fc99e Initial load
duke
parents:
diff changeset
66 static OptoReg::Name c_frame_pointer;
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Increment a register number. As in:
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // "for ( OptoReg::Name i; i=Control; i = add(i,1) ) ..."
a61af66fc99e Initial load
duke
parents:
diff changeset
72 static Name add( Name x, int y ) { return Name(x+y); }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // (We would like to have an operator+ for RegName, but it is not
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // a class, so this would be illegal in C++.)
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 static void dump( int );
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Get the stack slot number of an OptoReg::Name
a61af66fc99e Initial load
duke
parents:
diff changeset
80 static unsigned int reg2stack( OptoReg::Name r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
81 assert( r >= stack0(), " must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
82 return r - stack0();
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // convert a stack slot number into an OptoReg::Name
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static OptoReg::Name stack2reg( int idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return Name(stack0() + idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 static bool is_stack(Name n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 return n >= stack0();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static bool is_valid(Name n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 return (n != Bad);
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static bool is_reg(Name n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 return is_valid(n) && !is_stack(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static VMReg as_VMReg(OptoReg::Name n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (is_reg(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // Must use table, it'd be nice if Bad was indexable...
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return opto2vm[n];
a61af66fc99e Initial load
duke
parents:
diff changeset
106 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 assert(!is_stack(n), "must un warp");
a61af66fc99e Initial load
duke
parents:
diff changeset
108 return VMRegImpl::Bad();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Can un-warp a stack slot or convert a register or Bad
a61af66fc99e Initial load
duke
parents:
diff changeset
113 static VMReg as_VMReg(OptoReg::Name n, int frame_size, int arg_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (is_reg(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // Must use table, it'd be nice if Bad was indexable...
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return opto2vm[n];
a61af66fc99e Initial load
duke
parents:
diff changeset
117 } else if (is_stack(n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 int stack_slot = reg2stack(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (stack_slot < arg_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return VMRegImpl::stack2reg(stack_slot + frame_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return VMRegImpl::stack2reg(stack_slot - arg_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // return return VMRegImpl::stack2reg(reg2stack(OptoReg::add(n, -arg_count)));
a61af66fc99e Initial load
duke
parents:
diff changeset
124 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return VMRegImpl::Bad();
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 static OptoReg::Name as_OptoReg(VMReg r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (r->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert(false, "must warp");
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return stack2reg(r->reg2stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
133 } else if (r->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // Must use table, it'd be nice if Bad was indexable...
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return vm2opto[r->value()];
a61af66fc99e Initial load
duke
parents:
diff changeset
136 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 return Bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 static OptoReg::Name stack0() {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 return VMRegImpl::stack0->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 static const char* regname(OptoReg::Name n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 return as_VMReg(n)->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 };
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 //---------------------------OptoRegPair-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // Pairs of 32-bit registers for the allocator.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // This is a very similar class to VMRegPair. C2 only interfaces with VMRegPair
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // via the calling convention code which is shared between the compilers.
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Since C2 uses OptoRegs for register allocation it is more efficient to use
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // VMRegPair internally for nodes that can contain a pair of OptoRegs rather
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // than use VMRegPair and continually be converting back and forth. So normally
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // C2 will take in a VMRegPair from the calling convention code and immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // convert them to an OptoRegPair and stay in the OptoReg world. The only over
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // conversion between OptoRegs and VMRegs is for debug info and oopMaps. This
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // is not a high bandwidth spot and so it is not an issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // Note that onde other consequence of staying in the OptoReg world with OptoRegPairs
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // is that there are "physical" OptoRegs that are not representable in the VMReg
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // world, notably flags. [ But by design there is "space" in the VMReg world
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // for such registers they just may not be concrete ]. So if we were to use VMRegPair
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // then the VMReg world would have to have a representation for these registers
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // so that a OptoReg->VMReg->OptoReg would reproduce ther original OptoReg. As it
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // stands if you convert a flag (condition code) to a VMReg you will get VMRegImpl::Bad
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // and converting that will return OptoReg::Bad losing the identity of the OptoReg.
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 class OptoRegPair {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
173 short _second;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 short _first;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
176 void set_bad ( ) { _second = OptoReg::Bad; _first = OptoReg::Bad; }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void set1 ( OptoReg::Name n ) { _second = OptoReg::Bad; _first = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 void set2 ( OptoReg::Name n ) { _second = n + 1; _first = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 void set_pair( OptoReg::Name second, OptoReg::Name first ) { _second= second; _first= first; }
a61af66fc99e Initial load
duke
parents:
diff changeset
180 void set_ptr ( OptoReg::Name ptr ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
182 _second = ptr+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
183 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _second = OptoReg::Bad;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
186 _first = ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 OptoReg::Name second() const { return _second; }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 OptoReg::Name first() const { return _first; }
a61af66fc99e Initial load
duke
parents:
diff changeset
191 OptoRegPair(OptoReg::Name second, OptoReg::Name first) { _second = second; _first = first; }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 OptoRegPair(OptoReg::Name f) { _second = OptoReg::Bad; _first = f; }
a61af66fc99e Initial load
duke
parents:
diff changeset
193 OptoRegPair() { _second = OptoReg::Bad; _first = OptoReg::Bad; }
a61af66fc99e Initial load
duke
parents:
diff changeset
194 };