Mercurial > hg > truffle
annotate src/share/vm/c1/c1_FrameMap.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 126ea7725993 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
337
diff
changeset
|
2 * Copyright (c) 2000, 2008, 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:
337
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
337
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:
337
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_c1_FrameMap.cpp.incl" | |
27 | |
28 | |
29 | |
30 //----------------------------------------------------- | |
31 | |
32 // Convert method signature into an array of BasicTypes for the arguments | |
33 BasicTypeArray* FrameMap::signature_type_array_for(const ciMethod* method) { | |
34 ciSignature* sig = method->signature(); | |
35 BasicTypeList* sta = new BasicTypeList(method->arg_size()); | |
36 // add receiver, if any | |
37 if (!method->is_static()) sta->append(T_OBJECT); | |
38 // add remaining arguments | |
39 for (int i = 0; i < sig->count(); i++) { | |
40 ciType* type = sig->type_at(i); | |
41 BasicType t = type->basic_type(); | |
42 if (t == T_ARRAY) { | |
43 t = T_OBJECT; | |
44 } | |
45 sta->append(t); | |
46 } | |
47 // done | |
48 return sta; | |
49 } | |
50 | |
51 | |
52 CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing) { | |
53 // compute the size of the arguments first. The signature array | |
54 // that java_calling_convention takes includes a T_VOID after double | |
55 // work items but our signatures do not. | |
56 int i; | |
57 int sizeargs = 0; | |
58 for (i = 0; i < signature->length(); i++) { | |
59 sizeargs += type2size[signature->at(i)]; | |
60 } | |
61 | |
62 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); | |
63 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); | |
64 int sig_index = 0; | |
65 for (i = 0; i < sizeargs; i++, sig_index++) { | |
66 sig_bt[i] = signature->at(sig_index); | |
67 if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { | |
68 sig_bt[i + 1] = T_VOID; | |
69 i++; | |
70 } | |
71 } | |
72 | |
73 intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing); | |
74 LIR_OprList* args = new LIR_OprList(signature->length()); | |
75 for (i = 0; i < sizeargs;) { | |
76 BasicType t = sig_bt[i]; | |
77 assert(t != T_VOID, "should be skipping these"); | |
78 | |
79 LIR_Opr opr = map_to_opr(t, regs + i, outgoing); | |
80 args->append(opr); | |
81 if (opr->is_address()) { | |
82 LIR_Address* addr = opr->as_address_ptr(); | |
83 assert(addr->disp() == (int)addr->disp(), "out of range value"); | |
84 out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4); | |
85 } | |
86 i += type2size[t]; | |
87 } | |
88 assert(args->length() == signature->length(), "size mismatch"); | |
89 out_preserve += SharedRuntime::out_preserve_stack_slots(); | |
90 | |
91 if (outgoing) { | |
92 // update the space reserved for arguments. | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
93 update_reserved_argument_area_size(out_preserve * BytesPerWord); |
0 | 94 } |
95 return new CallingConvention(args, out_preserve); | |
96 } | |
97 | |
98 | |
99 CallingConvention* FrameMap::c_calling_convention(const BasicTypeArray* signature) { | |
100 // compute the size of the arguments first. The signature array | |
101 // that java_calling_convention takes includes a T_VOID after double | |
102 // work items but our signatures do not. | |
103 int i; | |
104 int sizeargs = 0; | |
105 for (i = 0; i < signature->length(); i++) { | |
106 sizeargs += type2size[signature->at(i)]; | |
107 } | |
108 | |
109 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); | |
110 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); | |
111 int sig_index = 0; | |
112 for (i = 0; i < sizeargs; i++, sig_index++) { | |
113 sig_bt[i] = signature->at(sig_index); | |
114 if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { | |
115 sig_bt[i + 1] = T_VOID; | |
116 i++; | |
117 } | |
118 } | |
119 | |
120 intptr_t out_preserve = SharedRuntime::c_calling_convention(sig_bt, regs, sizeargs); | |
121 LIR_OprList* args = new LIR_OprList(signature->length()); | |
122 for (i = 0; i < sizeargs;) { | |
123 BasicType t = sig_bt[i]; | |
124 assert(t != T_VOID, "should be skipping these"); | |
125 | |
126 // C calls are always outgoing | |
127 bool outgoing = true; | |
128 LIR_Opr opr = map_to_opr(t, regs + i, outgoing); | |
129 // they might be of different types if for instance floating point | |
130 // values are passed in cpu registers, but the sizes must match. | |
131 assert(type2size[opr->type()] == type2size[t], "type mismatch"); | |
132 args->append(opr); | |
133 if (opr->is_address()) { | |
134 LIR_Address* addr = opr->as_address_ptr(); | |
135 out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4); | |
136 } | |
137 i += type2size[t]; | |
138 } | |
139 assert(args->length() == signature->length(), "size mismatch"); | |
140 out_preserve += SharedRuntime::out_preserve_stack_slots(); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
141 update_reserved_argument_area_size(out_preserve * BytesPerWord); |
0 | 142 return new CallingConvention(args, out_preserve); |
143 } | |
144 | |
145 | |
146 //-------------------------------------------------------- | |
147 // FrameMap | |
148 //-------------------------------------------------------- | |
149 | |
150 bool FrameMap::_init_done = false; | |
151 Register FrameMap::_cpu_rnr2reg [FrameMap::nof_cpu_regs]; | |
152 int FrameMap::_cpu_reg2rnr [FrameMap::nof_cpu_regs]; | |
153 | |
154 | |
155 FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) { | |
1584 | 156 assert(_init_done, "should already be completed"); |
0 | 157 |
158 _framesize = -1; | |
159 _num_spills = -1; | |
160 | |
161 assert(monitors >= 0, "not set"); | |
162 _num_monitors = monitors; | |
163 assert(reserved_argument_area_size >= 0, "not set"); | |
164 _reserved_argument_area_size = MAX2(4, reserved_argument_area_size) * BytesPerWord; | |
165 | |
166 _argcount = method->arg_size(); | |
167 _argument_locations = new intArray(_argcount, -1); | |
168 _incoming_arguments = java_calling_convention(signature_type_array_for(method), false); | |
169 _oop_map_arg_count = _incoming_arguments->reserved_stack_slots(); | |
170 | |
171 int java_index = 0; | |
172 for (int i = 0; i < _incoming_arguments->length(); i++) { | |
173 LIR_Opr opr = _incoming_arguments->at(i); | |
174 if (opr->is_address()) { | |
175 LIR_Address* address = opr->as_address_ptr(); | |
176 _argument_locations->at_put(java_index, address->disp() - STACK_BIAS); | |
177 _incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type())))); | |
178 } | |
179 java_index += type2size[opr->type()]; | |
180 } | |
181 | |
182 } | |
183 | |
184 | |
185 bool FrameMap::finalize_frame(int nof_slots) { | |
186 assert(nof_slots >= 0, "must be positive"); | |
187 assert(_num_spills == -1, "can only be set once"); | |
188 _num_spills = nof_slots; | |
189 assert(_framesize == -1, "should only be calculated once"); | |
190 _framesize = round_to(in_bytes(sp_offset_for_monitor_base(0)) + | |
191 _num_monitors * sizeof(BasicObjectLock) + | |
192 sizeof(intptr_t) + // offset of deopt orig pc | |
193 frame_pad_in_bytes, | |
194 StackAlignmentInBytes) / 4; | |
195 int java_index = 0; | |
196 for (int i = 0; i < _incoming_arguments->length(); i++) { | |
197 LIR_Opr opr = _incoming_arguments->at(i); | |
198 if (opr->is_stack()) { | |
199 _argument_locations->at_put(java_index, in_bytes(framesize_in_bytes()) + | |
200 _argument_locations->at(java_index)); | |
201 } | |
202 java_index += type2size[opr->type()]; | |
203 } | |
204 // make sure it's expressible on the platform | |
205 return validate_frame(); | |
206 } | |
207 | |
208 VMReg FrameMap::sp_offset2vmreg(ByteSize offset) const { | |
209 int offset_in_bytes = in_bytes(offset); | |
210 assert(offset_in_bytes % 4 == 0, "must be multiple of 4 bytes"); | |
211 assert(offset_in_bytes / 4 < framesize() + oop_map_arg_count(), "out of range"); | |
212 return VMRegImpl::stack2reg(offset_in_bytes / 4); | |
213 } | |
214 | |
215 | |
216 bool FrameMap::location_for_sp_offset(ByteSize byte_offset_from_sp, | |
217 Location::Type loc_type, | |
218 Location* loc) const { | |
219 int offset = in_bytes(byte_offset_from_sp); | |
220 assert(offset >= 0, "incorrect offset"); | |
221 if (!Location::legal_offset_in_bytes(offset)) { | |
222 return false; | |
223 } | |
224 Location tmp_loc = Location::new_stk_loc(loc_type, offset); | |
225 *loc = tmp_loc; | |
226 return true; | |
227 } | |
228 | |
229 | |
230 bool FrameMap::locations_for_slot (int index, Location::Type loc_type, | |
231 Location* loc, Location* second) const { | |
232 ByteSize offset_from_sp = sp_offset_for_slot(index); | |
233 if (!location_for_sp_offset(offset_from_sp, loc_type, loc)) { | |
234 return false; | |
235 } | |
236 if (second != NULL) { | |
237 // two word item | |
238 offset_from_sp = offset_from_sp + in_ByteSize(4); | |
239 return location_for_sp_offset(offset_from_sp, loc_type, second); | |
240 } | |
241 return true; | |
242 } | |
243 | |
244 ////////////////////// | |
245 // Public accessors // | |
246 ////////////////////// | |
247 | |
248 | |
249 ByteSize FrameMap::sp_offset_for_slot(const int index) const { | |
250 if (index < argcount()) { | |
251 int offset = _argument_locations->at(index); | |
252 assert(offset != -1, "not a memory argument"); | |
253 assert(offset >= framesize() * 4, "argument inside of frame"); | |
254 return in_ByteSize(offset); | |
255 } | |
256 ByteSize offset = sp_offset_for_spill(index - argcount()); | |
257 assert(in_bytes(offset) < framesize() * 4, "spill outside of frame"); | |
258 return offset; | |
259 } | |
260 | |
261 | |
262 ByteSize FrameMap::sp_offset_for_double_slot(const int index) const { | |
263 ByteSize offset = sp_offset_for_slot(index); | |
264 if (index >= argcount()) { | |
265 assert(in_bytes(offset) + 4 < framesize() * 4, "spill outside of frame"); | |
266 } | |
267 return offset; | |
268 } | |
269 | |
270 | |
271 ByteSize FrameMap::sp_offset_for_spill(const int index) const { | |
272 assert(index >= 0 && index < _num_spills, "out of range"); | |
273 int offset = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) + | |
274 index * spill_slot_size_in_bytes; | |
275 return in_ByteSize(offset); | |
276 } | |
277 | |
278 ByteSize FrameMap::sp_offset_for_monitor_base(const int index) const { | |
279 int end_of_spills = round_to(first_available_sp_in_frame + _reserved_argument_area_size, sizeof(double)) + | |
280 _num_spills * spill_slot_size_in_bytes; | |
304 | 281 int offset = (int) round_to(end_of_spills, HeapWordSize) + index * sizeof(BasicObjectLock); |
0 | 282 return in_ByteSize(offset); |
283 } | |
284 | |
285 ByteSize FrameMap::sp_offset_for_monitor_lock(int index) const { | |
286 check_monitor_index(index); | |
287 return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::lock_offset_in_bytes());; | |
288 } | |
289 | |
290 ByteSize FrameMap::sp_offset_for_monitor_object(int index) const { | |
291 check_monitor_index(index); | |
292 return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes()); | |
293 } | |
294 | |
295 void FrameMap::print_frame_layout() const { | |
296 int svar; | |
297 tty->print_cr("#####################################"); | |
298 tty->print_cr("Frame size in words %d", framesize()); | |
299 | |
300 if( _num_monitors > 0) { | |
301 tty->print_cr("monitor [0]:%d | [%2d]:%d", | |
302 in_bytes(sp_offset_for_monitor_base(0)), | |
303 in_bytes(sp_offset_for_monitor_base(_num_monitors))); | |
304 } | |
305 if( _num_spills > 0) { | |
306 svar = _num_spills - 1; | |
307 if(svar == 0) | |
308 tty->print_cr("spill [0]:%d", in_bytes(sp_offset_for_spill(0))); | |
309 else | |
310 tty->print_cr("spill [0]:%d | [%2d]:%d", in_bytes(sp_offset_for_spill(0)), | |
311 svar, | |
312 in_bytes(sp_offset_for_spill(svar))); | |
313 } | |
314 } | |
315 | |
316 | |
317 // For OopMaps, map a local variable or spill index to an VMReg. | |
318 // This is the offset from sp() in the frame of the slot for the index, | |
319 // skewed by SharedInfo::stack0 to indicate a stack location (vs.a register.) | |
320 // | |
321 // C ABI size + | |
322 // framesize + framesize + | |
323 // stack0 stack0 stack0 0 <- VMReg->value() | |
324 // | | | <registers> | | |
325 // ..........|..............|..............|.............| | |
326 // 0 1 2 3 | <C ABI area> | 4 5 6 ...... | <- local indices | |
327 // ^ ^ sp() | |
328 // | | | |
329 // arguments non-argument locals | |
330 | |
331 | |
332 VMReg FrameMap::regname(LIR_Opr opr) const { | |
333 if (opr->is_single_cpu()) { | |
334 assert(!opr->is_virtual(), "should not see virtual registers here"); | |
335 return opr->as_register()->as_VMReg(); | |
336 } else if (opr->is_single_stack()) { | |
337 return sp_offset2vmreg(sp_offset_for_slot(opr->single_stack_ix())); | |
338 } else if (opr->is_address()) { | |
339 LIR_Address* addr = opr->as_address_ptr(); | |
340 assert(addr->base() == stack_pointer(), "sp based addressing only"); | |
341 return sp_offset2vmreg(in_ByteSize(addr->index()->as_jint())); | |
342 } | |
343 ShouldNotReachHere(); | |
344 return VMRegImpl::Bad(); | |
345 } | |
346 | |
347 | |
348 | |
349 | |
350 // ------------ extra spill slots --------------- |