Mercurial > hg > truffle
annotate src/share/vm/runtime/vframe_hp.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 | c18cbe5936b8 |
children | 4853c5cad3aa f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
903
diff
changeset
|
2 * Copyright (c) 1997, 2009, 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:
903
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
903
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:
903
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_vframe_hp.cpp.incl" | |
27 | |
28 | |
29 // ------------- compiledVFrame -------------- | |
30 | |
31 StackValueCollection* compiledVFrame::locals() const { | |
32 // Natives has no scope | |
33 if (scope() == NULL) return new StackValueCollection(0); | |
34 GrowableArray<ScopeValue*>* scv_list = scope()->locals(); | |
35 if (scv_list == NULL) return new StackValueCollection(0); | |
36 | |
37 // scv_list is the list of ScopeValues describing the JVM stack state. | |
38 // There is one scv_list entry for every JVM stack state in use. | |
39 int length = scv_list->length(); | |
40 StackValueCollection* result = new StackValueCollection(length); | |
41 // In rare instances set_locals may have occurred in which case | |
42 // there are local values that are not described by the ScopeValue anymore | |
43 GrowableArray<jvmtiDeferredLocalVariable*>* deferred = NULL; | |
44 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals(); | |
45 if (list != NULL ) { | |
46 // In real life this never happens or is typically a single element search | |
47 for (int i = 0; i < list->length(); i++) { | |
48 if (list->at(i)->matches((vframe*)this)) { | |
49 deferred = list->at(i)->locals(); | |
50 break; | |
51 } | |
52 } | |
53 } | |
54 | |
55 for( int i = 0; i < length; i++ ) { | |
56 result->add( create_stack_value(scv_list->at(i)) ); | |
57 } | |
58 | |
59 // Replace specified locals with any deferred writes that are present | |
60 if (deferred != NULL) { | |
61 for ( int l = 0; l < deferred->length() ; l ++) { | |
62 jvmtiDeferredLocalVariable* val = deferred->at(l); | |
63 switch (val->type()) { | |
64 case T_BOOLEAN: | |
65 result->set_int_at(val->index(), val->value().z); | |
66 break; | |
67 case T_CHAR: | |
68 result->set_int_at(val->index(), val->value().c); | |
69 break; | |
70 case T_FLOAT: | |
71 result->set_float_at(val->index(), val->value().f); | |
72 break; | |
73 case T_DOUBLE: | |
74 result->set_double_at(val->index(), val->value().d); | |
75 break; | |
76 case T_BYTE: | |
77 result->set_int_at(val->index(), val->value().b); | |
78 break; | |
79 case T_SHORT: | |
80 result->set_int_at(val->index(), val->value().s); | |
81 break; | |
82 case T_INT: | |
83 result->set_int_at(val->index(), val->value().i); | |
84 break; | |
85 case T_LONG: | |
86 result->set_long_at(val->index(), val->value().j); | |
87 break; | |
88 case T_OBJECT: | |
89 { | |
90 Handle obj((oop)val->value().l); | |
91 result->set_obj_at(val->index(), obj); | |
92 } | |
93 break; | |
94 default: | |
95 ShouldNotReachHere(); | |
96 } | |
97 } | |
98 } | |
99 | |
100 return result; | |
101 } | |
102 | |
103 | |
104 void compiledVFrame::set_locals(StackValueCollection* values) const { | |
105 | |
106 fatal("Should use update_local for each local update"); | |
107 } | |
108 | |
109 void compiledVFrame::update_local(BasicType type, int index, jvalue value) { | |
110 | |
111 #ifdef ASSERT | |
112 | |
113 assert(fr().is_deoptimized_frame(), "frame must be scheduled for deoptimization"); | |
114 #endif /* ASSERT */ | |
115 GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = thread()->deferred_locals(); | |
116 if (deferred != NULL ) { | |
117 // See if this vframe has already had locals with deferred writes | |
118 int f; | |
119 for ( f = 0 ; f < deferred->length() ; f++ ) { | |
120 if (deferred->at(f)->matches(this)) { | |
121 // Matching, vframe now see if the local already had deferred write | |
122 GrowableArray<jvmtiDeferredLocalVariable*>* locals = deferred->at(f)->locals(); | |
123 int l; | |
124 for (l = 0 ; l < locals->length() ; l++ ) { | |
125 if (locals->at(l)->index() == index) { | |
126 locals->at(l)->set_value(value); | |
127 return; | |
128 } | |
129 } | |
130 // No matching local already present. Push a new value onto the deferred collection | |
131 locals->push(new jvmtiDeferredLocalVariable(index, type, value)); | |
132 return; | |
133 } | |
134 } | |
135 // No matching vframe must push a new vframe | |
136 } else { | |
137 // No deferred updates pending for this thread. | |
138 // allocate in C heap | |
139 deferred = new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true); | |
140 thread()->set_deferred_locals(deferred); | |
141 } | |
142 deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id())); | |
143 assert(deferred->top()->id() == fr().id(), "Huh? Must match"); | |
144 deferred->top()->set_local_at(index, type, value); | |
145 } | |
146 | |
147 StackValueCollection* compiledVFrame::expressions() const { | |
148 // Natives has no scope | |
149 if (scope() == NULL) return new StackValueCollection(0); | |
150 GrowableArray<ScopeValue*>* scv_list = scope()->expressions(); | |
151 if (scv_list == NULL) return new StackValueCollection(0); | |
152 | |
153 // scv_list is the list of ScopeValues describing the JVM stack state. | |
154 // There is one scv_list entry for every JVM stack state in use. | |
155 int length = scv_list->length(); | |
156 StackValueCollection* result = new StackValueCollection(length); | |
157 for( int i = 0; i < length; i++ ) | |
158 result->add( create_stack_value(scv_list->at(i)) ); | |
159 | |
160 return result; | |
161 } | |
162 | |
163 | |
164 // The implementation of the following two methods was factorized into the | |
165 // class StackValue because it is also used from within deoptimization.cpp for | |
166 // rematerialization and relocking of non-escaping objects. | |
167 | |
168 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const { | |
169 return StackValue::create_stack_value(&_fr, register_map(), sv); | |
170 } | |
171 | |
172 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const { | |
173 return StackValue::resolve_monitor_lock(&_fr, location); | |
174 } | |
175 | |
176 | |
177 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const { | |
178 // Natives has no scope | |
179 if (scope() == NULL) { | |
180 nmethod* nm = code(); | |
181 methodOop method = nm->method(); | |
182 assert(method->is_native(), ""); | |
183 if (!method->is_synchronized()) { | |
184 return new GrowableArray<MonitorInfo*>(0); | |
185 } | |
186 // This monitor is really only needed for UseBiasedLocking, but | |
187 // return it in all cases for now as it might be useful for stack | |
188 // traces and tools as well | |
189 GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1); | |
190 // Casting away const | |
191 frame& fr = (frame&) _fr; | |
192 MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm), | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
193 fr.compiled_synchronized_native_monitor(nm), false, false); |
0 | 194 monitors->push(info); |
195 return monitors; | |
196 } | |
197 GrowableArray<MonitorValue*>* monitors = scope()->monitors(); | |
198 if (monitors == NULL) { | |
199 return new GrowableArray<MonitorInfo*>(0); | |
200 } | |
201 GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length()); | |
202 for (int index = 0; index < monitors->length(); index++) { | |
203 MonitorValue* mv = monitors->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
204 ScopeValue* ov = mv->owner(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
205 StackValue *owner_sv = create_stack_value(ov); // it is an oop |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
206 if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
207 assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
208 // Put klass for scalar replaced object. |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
209 ScopeValue* kv = ((ObjectValue *)ov)->klass(); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
210 assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object"); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
211 KlassHandle k(((ConstantOopReadValue*)kv)->value()()); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
212 result->push(new MonitorInfo(k->as_klassOop(), resolve_monitor_lock(mv->basic_lock()), |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
213 mv->eliminated(), true)); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
214 } else { |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
215 result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
216 mv->eliminated(), false)); |
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
217 } |
0 | 218 } |
219 return result; | |
220 } | |
221 | |
222 | |
223 compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm) | |
224 : javaVFrame(fr, reg_map, thread) { | |
225 _scope = NULL; | |
226 // Compiled method (native stub or Java code) | |
227 // native wrappers have no scope data, it is implied | |
228 if (!nm->is_native_method()) { | |
229 _scope = nm->scope_desc_at(_fr.pc()); | |
230 } | |
231 } | |
232 | |
233 compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope) | |
234 : javaVFrame(fr, reg_map, thread) { | |
235 _scope = scope; | |
236 guarantee(_scope != NULL, "scope must be present"); | |
237 } | |
238 | |
239 | |
240 bool compiledVFrame::is_top() const { | |
241 // FIX IT: Remove this when new native stubs are in place | |
242 if (scope() == NULL) return true; | |
243 return scope()->is_top(); | |
244 } | |
245 | |
246 | |
247 nmethod* compiledVFrame::code() const { | |
248 return CodeCache::find_nmethod(_fr.pc()); | |
249 } | |
250 | |
251 | |
252 methodOop compiledVFrame::method() const { | |
253 if (scope() == NULL) { | |
254 // native nmethods have no scope the method is implied | |
255 nmethod* nm = code(); | |
256 assert(nm->is_native_method(), "must be native"); | |
257 return nm->method(); | |
258 } | |
259 return scope()->method()(); | |
260 } | |
261 | |
262 | |
263 int compiledVFrame::bci() const { | |
264 int raw = raw_bci(); | |
265 return raw == SynchronizationEntryBCI ? 0 : raw; | |
266 } | |
267 | |
268 | |
269 int compiledVFrame::raw_bci() const { | |
270 if (scope() == NULL) { | |
271 // native nmethods have no scope the method/bci is implied | |
272 nmethod* nm = code(); | |
273 assert(nm->is_native_method(), "must be native"); | |
274 return 0; | |
275 } | |
276 return scope()->bci(); | |
277 } | |
278 | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
279 bool compiledVFrame::should_reexecute() const { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
280 if (scope() == NULL) { |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
281 // native nmethods have no scope the method/bci is implied |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
282 nmethod* nm = code(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
283 assert(nm->is_native_method(), "must be native"); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
284 return false; |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
285 } |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
286 return scope()->should_reexecute(); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
287 } |
0 | 288 |
289 vframe* compiledVFrame::sender() const { | |
290 const frame f = fr(); | |
291 if (scope() == NULL) { | |
292 // native nmethods have no scope the method/bci is implied | |
293 nmethod* nm = code(); | |
294 assert(nm->is_native_method(), "must be native"); | |
295 return vframe::sender(); | |
296 } else { | |
297 return scope()->is_top() | |
298 ? vframe::sender() | |
299 : new compiledVFrame(&f, register_map(), thread(), scope()->sender()); | |
300 } | |
301 } | |
302 | |
303 jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(methodOop method, int bci, intptr_t* id) { | |
304 _method = method; | |
305 _bci = bci; | |
306 _id = id; | |
307 // Alway will need at least one, must be on C heap | |
308 _locals = new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariable*> (1, true); | |
309 } | |
310 | |
311 jvmtiDeferredLocalVariableSet::~jvmtiDeferredLocalVariableSet() { | |
312 for (int i = 0; i < _locals->length() ; i++ ) { | |
313 delete _locals->at(i); | |
314 } | |
315 // Free growableArray and c heap for elements | |
316 delete _locals; | |
317 } | |
318 | |
319 bool jvmtiDeferredLocalVariableSet::matches(vframe* vf) { | |
320 if (!vf->is_compiled_frame()) return false; | |
321 compiledVFrame* cvf = (compiledVFrame*)vf; | |
322 return cvf->fr().id() == id() && cvf->method() == method() && cvf->bci() == bci(); | |
323 } | |
324 | |
325 void jvmtiDeferredLocalVariableSet::set_local_at(int idx, BasicType type, jvalue val) { | |
326 int i; | |
327 for ( i = 0 ; i < locals()->length() ; i++ ) { | |
328 if ( locals()->at(i)->index() == idx) { | |
329 assert(locals()->at(i)->type() == type, "Wrong type"); | |
330 locals()->at(i)->set_value(val); | |
331 return; | |
332 } | |
333 } | |
334 locals()->push(new jvmtiDeferredLocalVariable(idx, type, val)); | |
335 } | |
336 | |
337 void jvmtiDeferredLocalVariableSet::oops_do(OopClosure* f) { | |
338 | |
339 f->do_oop((oop*) &_method); | |
340 for ( int i = 0; i < locals()->length(); i++ ) { | |
341 if ( locals()->at(i)->type() == T_OBJECT) { | |
342 f->do_oop(locals()->at(i)->oop_addr()); | |
343 } | |
344 } | |
345 } | |
346 | |
347 jvmtiDeferredLocalVariable::jvmtiDeferredLocalVariable(int index, BasicType type, jvalue value) { | |
348 _index = index; | |
349 _type = type; | |
350 _value = value; | |
351 } | |
352 | |
353 | |
354 #ifndef PRODUCT | |
355 void compiledVFrame::verify() const { | |
356 Unimplemented(); | |
357 } | |
358 #endif // PRODUCT |