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