Mercurial > hg > truffle
annotate src/share/vm/runtime/deoptimization.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 | d2ede61b7a12 |
children | d5d065957597 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1255
diff
changeset
|
2 * Copyright (c) 1997, 2010, 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:
1255
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1255
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:
1255
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_deoptimization.cpp.incl" | |
27 | |
28 bool DeoptimizationMarker::_is_active = false; | |
29 | |
30 Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame, | |
31 int caller_adjustment, | |
32 int number_of_frames, | |
33 intptr_t* frame_sizes, | |
34 address* frame_pcs, | |
35 BasicType return_type) { | |
36 _size_of_deoptimized_frame = size_of_deoptimized_frame; | |
37 _caller_adjustment = caller_adjustment; | |
38 _number_of_frames = number_of_frames; | |
39 _frame_sizes = frame_sizes; | |
40 _frame_pcs = frame_pcs; | |
41 _register_block = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2); | |
42 _return_type = return_type; | |
43 // PD (x86 only) | |
44 _counter_temp = 0; | |
45 _initial_fp = 0; | |
46 _unpack_kind = 0; | |
47 _sender_sp_temp = 0; | |
48 | |
49 _total_frame_sizes = size_of_frames(); | |
50 } | |
51 | |
52 | |
53 Deoptimization::UnrollBlock::~UnrollBlock() { | |
54 FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes); | |
55 FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs); | |
56 FREE_C_HEAP_ARRAY(intptr_t, _register_block); | |
57 } | |
58 | |
59 | |
60 intptr_t* Deoptimization::UnrollBlock::value_addr_at(int register_number) const { | |
61 assert(register_number < RegisterMap::reg_count, "checking register number"); | |
62 return &_register_block[register_number * 2]; | |
63 } | |
64 | |
65 | |
66 | |
67 int Deoptimization::UnrollBlock::size_of_frames() const { | |
68 // Acount first for the adjustment of the initial frame | |
69 int result = _caller_adjustment; | |
70 for (int index = 0; index < number_of_frames(); index++) { | |
71 result += frame_sizes()[index]; | |
72 } | |
73 return result; | |
74 } | |
75 | |
76 | |
77 void Deoptimization::UnrollBlock::print() { | |
78 ttyLocker ttyl; | |
79 tty->print_cr("UnrollBlock"); | |
80 tty->print_cr(" size_of_deoptimized_frame = %d", _size_of_deoptimized_frame); | |
81 tty->print( " frame_sizes: "); | |
82 for (int index = 0; index < number_of_frames(); index++) { | |
83 tty->print("%d ", frame_sizes()[index]); | |
84 } | |
85 tty->cr(); | |
86 } | |
87 | |
88 | |
89 // In order to make fetch_unroll_info work properly with escape | |
90 // analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and | |
91 // ResetNoHandleMark and HandleMark were removed from it. The actual reallocation | |
92 // of previously eliminated objects occurs in realloc_objects, which is | |
93 // called from the method fetch_unroll_info_helper below. | |
94 JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread)) | |
95 // It is actually ok to allocate handles in a leaf method. It causes no safepoints, | |
96 // but makes the entry a little slower. There is however a little dance we have to | |
97 // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro | |
98 | |
99 // fetch_unroll_info() is called at the beginning of the deoptimization | |
100 // handler. Note this fact before we start generating temporary frames | |
101 // that can confuse an asynchronous stack walker. This counter is | |
102 // decremented at the end of unpack_frames(). | |
103 thread->inc_in_deopt_handler(); | |
104 | |
105 return fetch_unroll_info_helper(thread); | |
106 JRT_END | |
107 | |
108 | |
109 // This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) | |
110 Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread) { | |
111 | |
112 // Note: there is a safepoint safety issue here. No matter whether we enter | |
113 // via vanilla deopt or uncommon trap we MUST NOT stop at a safepoint once | |
114 // the vframeArray is created. | |
115 // | |
116 | |
117 // Allocate our special deoptimization ResourceMark | |
118 DeoptResourceMark* dmark = new DeoptResourceMark(thread); | |
119 assert(thread->deopt_mark() == NULL, "Pending deopt!"); | |
120 thread->set_deopt_mark(dmark); | |
121 | |
122 frame stub_frame = thread->last_frame(); // Makes stack walkable as side effect | |
123 RegisterMap map(thread, true); | |
124 RegisterMap dummy_map(thread, false); | |
125 // Now get the deoptee with a valid map | |
126 frame deoptee = stub_frame.sender(&map); | |
127 | |
128 // Create a growable array of VFrames where each VFrame represents an inlined | |
129 // Java frame. This storage is allocated with the usual system arena. | |
130 assert(deoptee.is_compiled_frame(), "Wrong frame type"); | |
131 GrowableArray<compiledVFrame*>* chunk = new GrowableArray<compiledVFrame*>(10); | |
132 vframe* vf = vframe::new_vframe(&deoptee, &map, thread); | |
133 while (!vf->is_top()) { | |
134 assert(vf->is_compiled_frame(), "Wrong frame type"); | |
135 chunk->push(compiledVFrame::cast(vf)); | |
136 vf = vf->sender(); | |
137 } | |
138 assert(vf->is_compiled_frame(), "Wrong frame type"); | |
139 chunk->push(compiledVFrame::cast(vf)); | |
140 | |
141 #ifdef COMPILER2 | |
142 // Reallocate the non-escaping objects and restore their fields. Then | |
143 // relock objects if synchronization on them was eliminated. | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
144 if (DoEscapeAnalysis) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
145 if (EliminateAllocations) { |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
146 assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
147 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
148 |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
149 // The flag return_oop() indicates call sites which return oop |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
150 // in compiled code. Such sites include java method calls, |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
151 // runtime calls (for example, used to allocate new objects/arrays |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
152 // on slow code path) and any other calls generated in compiled code. |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
153 // It is not guaranteed that we can get such information here only |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
154 // by analyzing bytecode in deoptimized frames. This is why this flag |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
155 // is set during method compilation (see Compile::Process_OopMap_Node()). |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
156 bool save_oop_result = chunk->at(0)->scope()->return_oop(); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
157 Handle return_value; |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
158 if (save_oop_result) { |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
159 // Reallocation may trigger GC. If deoptimization happened on return from |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
160 // call which returns oop we need to save it since it is not in oopmap. |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
161 oop result = deoptee.saved_oop_result(&map); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
162 assert(result == NULL || result->is_oop(), "must be oop"); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
163 return_value = Handle(thread, result); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
164 assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
165 if (TraceDeoptimization) { |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
166 tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
167 } |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
168 } |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
169 bool reallocated = false; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
170 if (objects != NULL) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
171 JRT_BLOCK |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
172 reallocated = realloc_objects(thread, &deoptee, objects, THREAD); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
173 JRT_END |
0 | 174 } |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
175 if (reallocated) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
176 reassign_fields(&deoptee, &map, objects); |
0 | 177 #ifndef PRODUCT |
178 if (TraceDeoptimization) { | |
179 ttyLocker ttyl; | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
180 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
181 print_objects(objects); |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
182 } |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
183 #endif |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
184 } |
1253
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
185 if (save_oop_result) { |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
186 // Restore result. |
f70b0d9ab095
6910618: C2: Error: assert(d->is_oop(),"JVM_ArrayCopy: dst not an oop")
kvn
parents:
1206
diff
changeset
|
187 deoptee.set_saved_oop_result(&map, return_value()); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
188 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
189 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
190 if (EliminateLocks) { |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
191 #ifndef PRODUCT |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
192 bool first = true; |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
193 #endif |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
194 for (int i = 0; i < chunk->length(); i++) { |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
195 compiledVFrame* cvf = chunk->at(i); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
196 assert (cvf->scope() != NULL,"expect only compiled java frames"); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
197 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
198 if (monitors->is_nonempty()) { |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
199 relock_objects(monitors, thread); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
200 #ifndef PRODUCT |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
201 if (TraceDeoptimization) { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
202 ttyLocker ttyl; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
203 for (int j = 0; j < monitors->length(); j++) { |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
204 MonitorInfo* mi = monitors->at(j); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
205 if (mi->eliminated()) { |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
206 if (first) { |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
207 first = false; |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
208 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
209 } |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
210 tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
211 } |
0 | 212 } |
213 } | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
214 #endif |
0 | 215 } |
216 } | |
217 } | |
218 } | |
219 #endif // COMPILER2 | |
220 // Ensure that no safepoint is taken after pointers have been stored | |
221 // in fields of rematerialized objects. If a safepoint occurs from here on | |
222 // out the java state residing in the vframeArray will be missed. | |
223 No_Safepoint_Verifier no_safepoint; | |
224 | |
225 vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk); | |
226 | |
227 assert(thread->vframe_array_head() == NULL, "Pending deopt!");; | |
228 thread->set_vframe_array_head(array); | |
229 | |
230 // Now that the vframeArray has been created if we have any deferred local writes | |
231 // added by jvmti then we can free up that structure as the data is now in the | |
232 // vframeArray | |
233 | |
234 if (thread->deferred_locals() != NULL) { | |
235 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread->deferred_locals(); | |
236 int i = 0; | |
237 do { | |
238 // Because of inlining we could have multiple vframes for a single frame | |
239 // and several of the vframes could have deferred writes. Find them all. | |
240 if (list->at(i)->id() == array->original().id()) { | |
241 jvmtiDeferredLocalVariableSet* dlv = list->at(i); | |
242 list->remove_at(i); | |
243 // individual jvmtiDeferredLocalVariableSet are CHeapObj's | |
244 delete dlv; | |
245 } else { | |
246 i++; | |
247 } | |
248 } while ( i < list->length() ); | |
249 if (list->length() == 0) { | |
250 thread->set_deferred_locals(NULL); | |
251 // free the list and elements back to C heap. | |
252 delete list; | |
253 } | |
254 | |
255 } | |
256 | |
1692 | 257 #ifndef SHARK |
0 | 258 // Compute the caller frame based on the sender sp of stub_frame and stored frame sizes info. |
259 CodeBlob* cb = stub_frame.cb(); | |
260 // Verify we have the right vframeArray | |
261 assert(cb->frame_size() >= 0, "Unexpected frame size"); | |
262 intptr_t* unpack_sp = stub_frame.sp() + cb->frame_size(); | |
263 | |
1204 | 264 // If the deopt call site is a MethodHandle invoke call site we have |
265 // to adjust the unpack_sp. | |
266 nmethod* deoptee_nm = deoptee.cb()->as_nmethod_or_null(); | |
267 if (deoptee_nm != NULL && deoptee_nm->is_method_handle_return(deoptee.pc())) | |
268 unpack_sp = deoptee.unextended_sp(); | |
269 | |
0 | 270 #ifdef ASSERT |
271 assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); | |
272 Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp); | |
273 #endif | |
1692 | 274 #else |
275 intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp(); | |
276 #endif // !SHARK | |
277 | |
0 | 278 // This is a guarantee instead of an assert because if vframe doesn't match |
279 // we will unpack the wrong deoptimized frame and wind up in strange places | |
280 // where it will be very difficult to figure out what went wrong. Better | |
281 // to die an early death here than some very obscure death later when the | |
282 // trail is cold. | |
283 // Note: on ia64 this guarantee can be fooled by frames with no memory stack | |
284 // in that it will fail to detect a problem when there is one. This needs | |
285 // more work in tiger timeframe. | |
286 guarantee(array->unextended_sp() == unpack_sp, "vframe_array_head must contain the vframeArray to unpack"); | |
287 | |
288 int number_of_frames = array->frames(); | |
289 | |
290 // Compute the vframes' sizes. Note that frame_sizes[] entries are ordered from outermost to innermost | |
291 // virtual activation, which is the reverse of the elements in the vframes array. | |
292 intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames); | |
293 // +1 because we always have an interpreter return address for the final slot. | |
294 address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1); | |
295 int callee_parameters = 0; | |
296 int callee_locals = 0; | |
297 int popframe_extra_args = 0; | |
298 // Create an interpreter return address for the stub to use as its return | |
299 // address so the skeletal frames are perfectly walkable | |
300 frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); | |
301 | |
302 // PopFrame requires that the preserved incoming arguments from the recently-popped topmost | |
303 // activation be put back on the expression stack of the caller for reexecution | |
304 if (JvmtiExport::can_pop_frame() && thread->popframe_forcing_deopt_reexecution()) { | |
305 popframe_extra_args = in_words(thread->popframe_preserved_args_size_in_words()); | |
306 } | |
307 | |
308 // | |
309 // frame_sizes/frame_pcs[0] oldest frame (int or c2i) | |
310 // frame_sizes/frame_pcs[1] next oldest frame (int) | |
311 // frame_sizes/frame_pcs[n] youngest frame (int) | |
312 // | |
313 // Now a pc in frame_pcs is actually the return address to the frame's caller (a frame | |
314 // owns the space for the return address to it's caller). Confusing ain't it. | |
315 // | |
316 // The vframe array can address vframes with indices running from | |
317 // 0.._frames-1. Index 0 is the youngest frame and _frame - 1 is the oldest (root) frame. | |
318 // When we create the skeletal frames we need the oldest frame to be in the zero slot | |
319 // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk. | |
320 // so things look a little strange in this loop. | |
321 // | |
322 for (int index = 0; index < array->frames(); index++ ) { | |
323 // frame[number_of_frames - 1 ] = on_stack_size(youngest) | |
324 // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) | |
325 // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest))) | |
326 frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(callee_parameters, | |
327 callee_locals, | |
328 index == 0, | |
329 popframe_extra_args); | |
330 // This pc doesn't have to be perfect just good enough to identify the frame | |
331 // as interpreted so the skeleton frame will be walkable | |
332 // The correct pc will be set when the skeleton frame is completely filled out | |
333 // The final pc we store in the loop is wrong and will be overwritten below | |
334 frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset; | |
335 | |
336 callee_parameters = array->element(index)->method()->size_of_parameters(); | |
337 callee_locals = array->element(index)->method()->max_locals(); | |
338 popframe_extra_args = 0; | |
339 } | |
340 | |
341 // Compute whether the root vframe returns a float or double value. | |
342 BasicType return_type; | |
343 { | |
344 HandleMark hm; | |
345 methodHandle method(thread, array->element(0)->method()); | |
346 Bytecode_invoke* invoke = Bytecode_invoke_at_check(method, array->element(0)->bci()); | |
347 return_type = (invoke != NULL) ? invoke->result_type(thread) : T_ILLEGAL; | |
348 } | |
349 | |
350 // Compute information for handling adapters and adjusting the frame size of the caller. | |
351 int caller_adjustment = 0; | |
352 | |
353 // Find the current pc for sender of the deoptee. Since the sender may have been deoptimized | |
354 // itself since the deoptee vframeArray was created we must get a fresh value of the pc rather | |
355 // than simply use array->sender.pc(). This requires us to walk the current set of frames | |
356 // | |
357 frame deopt_sender = stub_frame.sender(&dummy_map); // First is the deoptee frame | |
358 deopt_sender = deopt_sender.sender(&dummy_map); // Now deoptee caller | |
359 | |
360 // Compute the amount the oldest interpreter frame will have to adjust | |
361 // its caller's stack by. If the caller is a compiled frame then | |
362 // we pretend that the callee has no parameters so that the | |
363 // extension counts for the full amount of locals and not just | |
364 // locals-parms. This is because without a c2i adapter the parm | |
365 // area as created by the compiled frame will not be usable by | |
366 // the interpreter. (Depending on the calling convention there | |
367 // may not even be enough space). | |
368 | |
369 // QQQ I'd rather see this pushed down into last_frame_adjust | |
370 // and have it take the sender (aka caller). | |
371 | |
372 if (deopt_sender.is_compiled_frame()) { | |
373 caller_adjustment = last_frame_adjust(0, callee_locals); | |
374 } else if (callee_locals > callee_parameters) { | |
375 // The caller frame may need extending to accommodate | |
376 // non-parameter locals of the first unpacked interpreted frame. | |
377 // Compute that adjustment. | |
378 caller_adjustment = last_frame_adjust(callee_parameters, callee_locals); | |
379 } | |
380 | |
381 | |
382 // If the sender is deoptimized the we must retrieve the address of the handler | |
383 // since the frame will "magically" show the original pc before the deopt | |
384 // and we'd undo the deopt. | |
385 | |
386 frame_pcs[0] = deopt_sender.raw_pc(); | |
387 | |
1692 | 388 #ifndef SHARK |
0 | 389 assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); |
1692 | 390 #endif // SHARK |
0 | 391 |
392 UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, | |
393 caller_adjustment * BytesPerWord, | |
394 number_of_frames, | |
395 frame_sizes, | |
396 frame_pcs, | |
397 return_type); | |
398 #if defined(IA32) || defined(AMD64) | |
399 // We need a way to pass fp to the unpacking code so the skeletal frames | |
400 // come out correct. This is only needed for x86 because of c2 using ebp | |
401 // as an allocatable register. So this update is useless (and harmless) | |
402 // on the other platforms. It would be nice to do this in a different | |
403 // way but even the old style deoptimization had a problem with deriving | |
404 // this value. NEEDS_CLEANUP | |
405 // Note: now that c1 is using c2's deopt blob we must do this on all | |
406 // x86 based platforms | |
407 intptr_t** fp_addr = (intptr_t**) (((address)info) + info->initial_fp_offset_in_bytes()); | |
408 *fp_addr = array->sender().fp(); // was adapter_caller | |
409 #endif /* IA32 || AMD64 */ | |
410 | |
411 if (array->frames() > 1) { | |
412 if (VerifyStack && TraceDeoptimization) { | |
413 tty->print_cr("Deoptimizing method containing inlining"); | |
414 } | |
415 } | |
416 | |
417 array->set_unroll_block(info); | |
418 return info; | |
419 } | |
420 | |
421 // Called to cleanup deoptimization data structures in normal case | |
422 // after unpacking to stack and when stack overflow error occurs | |
423 void Deoptimization::cleanup_deopt_info(JavaThread *thread, | |
424 vframeArray *array) { | |
425 | |
426 // Get array if coming from exception | |
427 if (array == NULL) { | |
428 array = thread->vframe_array_head(); | |
429 } | |
430 thread->set_vframe_array_head(NULL); | |
431 | |
432 // Free the previous UnrollBlock | |
433 vframeArray* old_array = thread->vframe_array_last(); | |
434 thread->set_vframe_array_last(array); | |
435 | |
436 if (old_array != NULL) { | |
437 UnrollBlock* old_info = old_array->unroll_block(); | |
438 old_array->set_unroll_block(NULL); | |
439 delete old_info; | |
440 delete old_array; | |
441 } | |
442 | |
443 // Deallocate any resource creating in this routine and any ResourceObjs allocated | |
444 // inside the vframeArray (StackValueCollections) | |
445 | |
446 delete thread->deopt_mark(); | |
447 thread->set_deopt_mark(NULL); | |
448 | |
449 | |
450 if (JvmtiExport::can_pop_frame()) { | |
451 #ifndef CC_INTERP | |
452 // Regardless of whether we entered this routine with the pending | |
453 // popframe condition bit set, we should always clear it now | |
454 thread->clear_popframe_condition(); | |
455 #else | |
456 // C++ interpeter will clear has_pending_popframe when it enters | |
457 // with method_resume. For deopt_resume2 we clear it now. | |
458 if (thread->popframe_forcing_deopt_reexecution()) | |
459 thread->clear_popframe_condition(); | |
460 #endif /* CC_INTERP */ | |
461 } | |
462 | |
463 // unpack_frames() is called at the end of the deoptimization handler | |
464 // and (in C2) at the end of the uncommon trap handler. Note this fact | |
465 // so that an asynchronous stack walker can work again. This counter is | |
466 // incremented at the beginning of fetch_unroll_info() and (in C2) at | |
467 // the beginning of uncommon_trap(). | |
468 thread->dec_in_deopt_handler(); | |
469 } | |
470 | |
471 | |
472 // Return BasicType of value being returned | |
473 JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_mode)) | |
474 | |
475 // We are already active int he special DeoptResourceMark any ResourceObj's we | |
476 // allocate will be freed at the end of the routine. | |
477 | |
478 // It is actually ok to allocate handles in a leaf method. It causes no safepoints, | |
479 // but makes the entry a little slower. There is however a little dance we have to | |
480 // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro | |
481 ResetNoHandleMark rnhm; // No-op in release/product versions | |
482 HandleMark hm; | |
483 | |
484 frame stub_frame = thread->last_frame(); | |
485 | |
486 // Since the frame to unpack is the top frame of this thread, the vframe_array_head | |
487 // must point to the vframeArray for the unpack frame. | |
488 vframeArray* array = thread->vframe_array_head(); | |
489 | |
490 #ifndef PRODUCT | |
491 if (TraceDeoptimization) { | |
492 tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode); | |
493 } | |
494 #endif | |
495 | |
496 UnrollBlock* info = array->unroll_block(); | |
497 | |
498 // Unpack the interpreter frames and any adapter frame (c2 only) we might create. | |
499 array->unpack_to_stack(stub_frame, exec_mode); | |
500 | |
501 BasicType bt = info->return_type(); | |
502 | |
503 // If we have an exception pending, claim that the return type is an oop | |
504 // so the deopt_blob does not overwrite the exception_oop. | |
505 | |
506 if (exec_mode == Unpack_exception) | |
507 bt = T_OBJECT; | |
508 | |
509 // Cleanup thread deopt data | |
510 cleanup_deopt_info(thread, array); | |
511 | |
512 #ifndef PRODUCT | |
513 if (VerifyStack) { | |
514 ResourceMark res_mark; | |
515 | |
516 // Verify that the just-unpacked frames match the interpreter's | |
517 // notions of expression stack and locals | |
518 vframeArray* cur_array = thread->vframe_array_last(); | |
519 RegisterMap rm(thread, false); | |
520 rm.set_include_argument_oops(false); | |
521 bool is_top_frame = true; | |
522 int callee_size_of_parameters = 0; | |
523 int callee_max_locals = 0; | |
524 for (int i = 0; i < cur_array->frames(); i++) { | |
525 vframeArrayElement* el = cur_array->element(i); | |
526 frame* iframe = el->iframe(); | |
527 guarantee(iframe->is_interpreted_frame(), "Wrong frame type"); | |
528 | |
529 // Get the oop map for this bci | |
530 InterpreterOopMap mask; | |
531 int cur_invoke_parameter_size = 0; | |
532 bool try_next_mask = false; | |
533 int next_mask_expression_stack_size = -1; | |
534 int top_frame_expression_stack_adjustment = 0; | |
535 methodHandle mh(thread, iframe->interpreter_frame_method()); | |
536 OopMapCache::compute_one_oop_map(mh, iframe->interpreter_frame_bci(), &mask); | |
537 BytecodeStream str(mh); | |
538 str.set_start(iframe->interpreter_frame_bci()); | |
539 int max_bci = mh->code_size(); | |
540 // Get to the next bytecode if possible | |
541 assert(str.bci() < max_bci, "bci in interpreter frame out of bounds"); | |
542 // Check to see if we can grab the number of outgoing arguments | |
543 // at an uncommon trap for an invoke (where the compiler | |
544 // generates debug info before the invoke has executed) | |
545 Bytecodes::Code cur_code = str.next(); | |
546 if (cur_code == Bytecodes::_invokevirtual || | |
547 cur_code == Bytecodes::_invokespecial || | |
548 cur_code == Bytecodes::_invokestatic || | |
549 cur_code == Bytecodes::_invokeinterface) { | |
550 Bytecode_invoke* invoke = Bytecode_invoke_at(mh, iframe->interpreter_frame_bci()); | |
551 symbolHandle signature(thread, invoke->signature()); | |
552 ArgumentSizeComputer asc(signature); | |
553 cur_invoke_parameter_size = asc.size(); | |
554 if (cur_code != Bytecodes::_invokestatic) { | |
555 // Add in receiver | |
556 ++cur_invoke_parameter_size; | |
557 } | |
558 } | |
559 if (str.bci() < max_bci) { | |
560 Bytecodes::Code bc = str.next(); | |
561 if (bc >= 0) { | |
562 // The interpreter oop map generator reports results before | |
563 // the current bytecode has executed except in the case of | |
564 // calls. It seems to be hard to tell whether the compiler | |
565 // has emitted debug information matching the "state before" | |
566 // a given bytecode or the state after, so we try both | |
567 switch (cur_code) { | |
568 case Bytecodes::_invokevirtual: | |
569 case Bytecodes::_invokespecial: | |
570 case Bytecodes::_invokestatic: | |
571 case Bytecodes::_invokeinterface: | |
572 case Bytecodes::_athrow: | |
573 break; | |
574 default: { | |
575 InterpreterOopMap next_mask; | |
576 OopMapCache::compute_one_oop_map(mh, str.bci(), &next_mask); | |
577 next_mask_expression_stack_size = next_mask.expression_stack_size(); | |
578 // Need to subtract off the size of the result type of | |
579 // the bytecode because this is not described in the | |
580 // debug info but returned to the interpreter in the TOS | |
581 // caching register | |
582 BasicType bytecode_result_type = Bytecodes::result_type(cur_code); | |
583 if (bytecode_result_type != T_ILLEGAL) { | |
584 top_frame_expression_stack_adjustment = type2size[bytecode_result_type]; | |
585 } | |
586 assert(top_frame_expression_stack_adjustment >= 0, ""); | |
587 try_next_mask = true; | |
588 break; | |
589 } | |
590 } | |
591 } | |
592 } | |
593 | |
594 // Verify stack depth and oops in frame | |
595 // This assertion may be dependent on the platform we're running on and may need modification (tested on x86 and sparc) | |
596 if (!( | |
597 /* SPARC */ | |
598 (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_size_of_parameters) || | |
599 /* x86 */ | |
600 (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_max_locals) || | |
601 (try_next_mask && | |
602 (iframe->interpreter_frame_expression_stack_size() == (next_mask_expression_stack_size - | |
603 top_frame_expression_stack_adjustment))) || | |
604 (is_top_frame && (exec_mode == Unpack_exception) && iframe->interpreter_frame_expression_stack_size() == 0) || | |
605 (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute) && | |
606 (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size)) | |
607 )) { | |
608 ttyLocker ttyl; | |
609 | |
610 // Print out some information that will help us debug the problem | |
611 tty->print_cr("Wrong number of expression stack elements during deoptimization"); | |
612 tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1); | |
613 tty->print_cr(" Fabricated interpreter frame had %d expression stack elements", | |
614 iframe->interpreter_frame_expression_stack_size()); | |
615 tty->print_cr(" Interpreter oop map had %d expression stack elements", mask.expression_stack_size()); | |
616 tty->print_cr(" try_next_mask = %d", try_next_mask); | |
617 tty->print_cr(" next_mask_expression_stack_size = %d", next_mask_expression_stack_size); | |
618 tty->print_cr(" callee_size_of_parameters = %d", callee_size_of_parameters); | |
619 tty->print_cr(" callee_max_locals = %d", callee_max_locals); | |
620 tty->print_cr(" top_frame_expression_stack_adjustment = %d", top_frame_expression_stack_adjustment); | |
621 tty->print_cr(" exec_mode = %d", exec_mode); | |
622 tty->print_cr(" cur_invoke_parameter_size = %d", cur_invoke_parameter_size); | |
623 tty->print_cr(" Thread = " INTPTR_FORMAT ", thread ID = " UINTX_FORMAT, thread, thread->osthread()->thread_id()); | |
624 tty->print_cr(" Interpreted frames:"); | |
625 for (int k = 0; k < cur_array->frames(); k++) { | |
626 vframeArrayElement* el = cur_array->element(k); | |
627 tty->print_cr(" %s (bci %d)", el->method()->name_and_sig_as_C_string(), el->bci()); | |
628 } | |
629 cur_array->print_on_2(tty); | |
630 guarantee(false, "wrong number of expression stack elements during deopt"); | |
631 } | |
632 VerifyOopClosure verify; | |
633 iframe->oops_interpreted_do(&verify, &rm, false); | |
634 callee_size_of_parameters = mh->size_of_parameters(); | |
635 callee_max_locals = mh->max_locals(); | |
636 is_top_frame = false; | |
637 } | |
638 } | |
639 #endif /* !PRODUCT */ | |
640 | |
641 | |
642 return bt; | |
643 JRT_END | |
644 | |
645 | |
646 int Deoptimization::deoptimize_dependents() { | |
647 Threads::deoptimized_wrt_marked_nmethods(); | |
648 return 0; | |
649 } | |
650 | |
651 | |
652 #ifdef COMPILER2 | |
653 bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { | |
654 Handle pending_exception(thread->pending_exception()); | |
655 const char* exception_file = thread->exception_file(); | |
656 int exception_line = thread->exception_line(); | |
657 thread->clear_pending_exception(); | |
658 | |
659 for (int i = 0; i < objects->length(); i++) { | |
660 assert(objects->at(i)->is_object(), "invalid debug information"); | |
661 ObjectValue* sv = (ObjectValue*) objects->at(i); | |
662 | |
663 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | |
664 oop obj = NULL; | |
665 | |
666 if (k->oop_is_instance()) { | |
667 instanceKlass* ik = instanceKlass::cast(k()); | |
668 obj = ik->allocate_instance(CHECK_(false)); | |
669 } else if (k->oop_is_typeArray()) { | |
670 typeArrayKlass* ak = typeArrayKlass::cast(k()); | |
671 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); | |
672 int len = sv->field_size() / type2size[ak->element_type()]; | |
673 obj = ak->allocate(len, CHECK_(false)); | |
674 } else if (k->oop_is_objArray()) { | |
675 objArrayKlass* ak = objArrayKlass::cast(k()); | |
676 obj = ak->allocate(sv->field_size(), CHECK_(false)); | |
677 } | |
678 | |
679 assert(obj != NULL, "allocation failed"); | |
680 assert(sv->value().is_null(), "redundant reallocation"); | |
681 sv->set_value(obj); | |
682 } | |
683 | |
684 if (pending_exception.not_null()) { | |
685 thread->set_pending_exception(pending_exception(), exception_file, exception_line); | |
686 } | |
687 | |
688 return true; | |
689 } | |
690 | |
691 // This assumes that the fields are stored in ObjectValue in the same order | |
692 // they are yielded by do_nonstatic_fields. | |
693 class FieldReassigner: public FieldClosure { | |
694 frame* _fr; | |
695 RegisterMap* _reg_map; | |
696 ObjectValue* _sv; | |
697 instanceKlass* _ik; | |
698 oop _obj; | |
699 | |
700 int _i; | |
701 public: | |
702 FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) : | |
703 _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {} | |
704 | |
705 int i() const { return _i; } | |
706 | |
707 | |
708 void do_field(fieldDescriptor* fd) { | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
709 intptr_t val; |
0 | 710 StackValue* value = |
711 StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i())); | |
712 int offset = fd->offset(); | |
713 switch (fd->field_type()) { | |
714 case T_OBJECT: case T_ARRAY: | |
715 assert(value->type() == T_OBJECT, "Agreement."); | |
716 _obj->obj_field_put(offset, value->get_obj()()); | |
717 break; | |
718 | |
719 case T_LONG: case T_DOUBLE: { | |
720 assert(value->type() == T_INT, "Agreement."); | |
721 StackValue* low = | |
722 StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i)); | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
723 #ifdef _LP64 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
724 jlong res = (jlong)low->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
725 #else |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
726 #ifdef SPARC |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
727 // For SPARC we have to swap high and low words. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
728 jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
729 #else |
0 | 730 jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
731 #endif //SPARC |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
732 #endif |
0 | 733 _obj->long_field_put(offset, res); |
734 break; | |
735 } | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
736 // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. |
0 | 737 case T_INT: case T_FLOAT: // 4 bytes. |
738 assert(value->type() == T_INT, "Agreement."); | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
739 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
740 _obj->int_field_put(offset, (jint)*((jint*)&val)); |
0 | 741 break; |
742 | |
743 case T_SHORT: case T_CHAR: // 2 bytes | |
744 assert(value->type() == T_INT, "Agreement."); | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
745 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
746 _obj->short_field_put(offset, (jshort)*((jint*)&val)); |
0 | 747 break; |
748 | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
749 case T_BOOLEAN: case T_BYTE: // 1 byte |
0 | 750 assert(value->type() == T_INT, "Agreement."); |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
751 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
752 _obj->bool_field_put(offset, (jboolean)*((jint*)&val)); |
0 | 753 break; |
754 | |
755 default: | |
756 ShouldNotReachHere(); | |
757 } | |
758 _i++; | |
759 } | |
760 }; | |
761 | |
762 // restore elements of an eliminated type array | |
763 void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) { | |
764 int index = 0; | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
765 intptr_t val; |
0 | 766 |
767 for (int i = 0; i < sv->field_size(); i++) { | |
768 StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); | |
769 switch(type) { | |
44
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
770 case T_LONG: case T_DOUBLE: { |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
771 assert(value->type() == T_INT, "Agreement."); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
772 StackValue* low = |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
773 StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
774 #ifdef _LP64 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
775 jlong res = (jlong)low->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
776 #else |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
777 #ifdef SPARC |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
778 // For SPARC we have to swap high and low words. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
779 jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
780 #else |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
781 jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
782 #endif //SPARC |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
783 #endif |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
784 obj->long_at_put(index, res); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
785 break; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
786 } |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
787 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
788 // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
789 case T_INT: case T_FLOAT: // 4 bytes. |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
790 assert(value->type() == T_INT, "Agreement."); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
791 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
792 obj->int_at_put(index, (jint)*((jint*)&val)); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
793 break; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
794 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
795 case T_SHORT: case T_CHAR: // 2 bytes |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
796 assert(value->type() == T_INT, "Agreement."); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
797 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
798 obj->short_at_put(index, (jshort)*((jint*)&val)); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
799 break; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
800 |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
801 case T_BOOLEAN: case T_BYTE: // 1 byte |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
802 assert(value->type() == T_INT, "Agreement."); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
803 val = value->get_int(); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
804 obj->bool_at_put(index, (jboolean)*((jint*)&val)); |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
805 break; |
52fed2ec0afb
6667620: (Escape Analysis) fix deoptimization for scalar replaced objects
kvn
parents:
0
diff
changeset
|
806 |
0 | 807 default: |
808 ShouldNotReachHere(); | |
809 } | |
810 index++; | |
811 } | |
812 } | |
813 | |
814 | |
815 // restore fields of an eliminated object array | |
816 void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) { | |
817 for (int i = 0; i < sv->field_size(); i++) { | |
818 StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); | |
819 assert(value->type() == T_OBJECT, "object element expected"); | |
820 obj->obj_at_put(i, value->get_obj()()); | |
821 } | |
822 } | |
823 | |
824 | |
825 // restore fields of all eliminated objects and arrays | |
826 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) { | |
827 for (int i = 0; i < objects->length(); i++) { | |
828 ObjectValue* sv = (ObjectValue*) objects->at(i); | |
829 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | |
830 Handle obj = sv->value(); | |
831 assert(obj.not_null(), "reallocation was missed"); | |
832 | |
833 if (k->oop_is_instance()) { | |
834 instanceKlass* ik = instanceKlass::cast(k()); | |
835 FieldReassigner reassign(fr, reg_map, sv, obj()); | |
836 ik->do_nonstatic_fields(&reassign); | |
837 } else if (k->oop_is_typeArray()) { | |
838 typeArrayKlass* ak = typeArrayKlass::cast(k()); | |
839 reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); | |
840 } else if (k->oop_is_objArray()) { | |
841 reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj()); | |
842 } | |
843 } | |
844 } | |
845 | |
846 | |
847 // relock objects for which synchronization was eliminated | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
848 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) { |
0 | 849 for (int i = 0; i < monitors->length(); i++) { |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
850 MonitorInfo* mon_info = monitors->at(i); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
851 if (mon_info->eliminated()) { |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
852 assert(mon_info->owner() != NULL, "reallocation was missed"); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
853 Handle obj = Handle(mon_info->owner()); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
854 markOop mark = obj->mark(); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
855 if (UseBiasedLocking && mark->has_bias_pattern()) { |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
856 // New allocated objects may have the mark set to anonymously biased. |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
857 // Also the deoptimized method may called methods with synchronization |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
858 // where the thread-local object is bias locked to the current thread. |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
859 assert(mark->is_biased_anonymously() || |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
860 mark->biased_locker() == thread, "should be locked to current thread"); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
861 // Reset mark word to unbiased prototype. |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
862 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
863 obj->set_mark(unbiased_prototype); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
864 } |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
865 BasicLock* lock = mon_info->lock(); |
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
866 ObjectSynchronizer::slow_enter(obj, lock, thread); |
0 | 867 } |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
44
diff
changeset
|
868 assert(mon_info->owner()->is_locked(), "object must be locked now"); |
0 | 869 } |
870 } | |
871 | |
872 | |
873 #ifndef PRODUCT | |
874 // print information about reallocated objects | |
875 void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) { | |
876 fieldDescriptor fd; | |
877 | |
878 for (int i = 0; i < objects->length(); i++) { | |
879 ObjectValue* sv = (ObjectValue*) objects->at(i); | |
880 KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); | |
881 Handle obj = sv->value(); | |
882 | |
883 tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); | |
884 k->as_klassOop()->print_value(); | |
885 tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); | |
886 tty->cr(); | |
887 | |
888 if (Verbose) { | |
889 k->oop_print_on(obj(), tty); | |
890 } | |
891 } | |
892 } | |
893 #endif | |
894 #endif // COMPILER2 | |
895 | |
896 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) { | |
897 | |
898 #ifndef PRODUCT | |
899 if (TraceDeoptimization) { | |
900 ttyLocker ttyl; | |
901 tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread); | |
902 fr.print_on(tty); | |
903 tty->print_cr(" Virtual frames (innermost first):"); | |
904 for (int index = 0; index < chunk->length(); index++) { | |
905 compiledVFrame* vf = chunk->at(index); | |
906 tty->print(" %2d - ", index); | |
907 vf->print_value(); | |
908 int bci = chunk->at(index)->raw_bci(); | |
909 const char* code_name; | |
910 if (bci == SynchronizationEntryBCI) { | |
911 code_name = "sync entry"; | |
912 } else { | |
913 Bytecodes::Code code = Bytecodes::code_at(vf->method(), bci); | |
914 code_name = Bytecodes::name(code); | |
915 } | |
916 tty->print(" - %s", code_name); | |
917 tty->print_cr(" @ bci %d ", bci); | |
918 if (Verbose) { | |
919 vf->print(); | |
920 tty->cr(); | |
921 } | |
922 } | |
923 } | |
924 #endif | |
925 | |
926 // Register map for next frame (used for stack crawl). We capture | |
927 // the state of the deopt'ing frame's caller. Thus if we need to | |
928 // stuff a C2I adapter we can properly fill in the callee-save | |
929 // register locations. | |
930 frame caller = fr.sender(reg_map); | |
931 int frame_size = caller.sp() - fr.sp(); | |
932 | |
933 frame sender = caller; | |
934 | |
935 // Since the Java thread being deoptimized will eventually adjust it's own stack, | |
936 // the vframeArray containing the unpacking information is allocated in the C heap. | |
937 // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames(). | |
938 vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr); | |
939 | |
940 // Compare the vframeArray to the collected vframes | |
941 assert(array->structural_compare(thread, chunk), "just checking"); | |
942 Events::log("# vframes = %d", (intptr_t)chunk->length()); | |
943 | |
944 #ifndef PRODUCT | |
945 if (TraceDeoptimization) { | |
946 ttyLocker ttyl; | |
947 tty->print_cr(" Created vframeArray " INTPTR_FORMAT, array); | |
948 } | |
949 #endif // PRODUCT | |
950 | |
951 return array; | |
952 } | |
953 | |
954 | |
955 static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { | |
956 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); | |
957 for (int i = 0; i < monitors->length(); i++) { | |
958 MonitorInfo* mon_info = monitors->at(i); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
196
diff
changeset
|
959 if (!mon_info->eliminated() && mon_info->owner() != NULL) { |
0 | 960 objects_to_revoke->append(Handle(mon_info->owner())); |
961 } | |
962 } | |
963 } | |
964 | |
965 | |
966 void Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) { | |
967 if (!UseBiasedLocking) { | |
968 return; | |
969 } | |
970 | |
971 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); | |
972 | |
973 // Unfortunately we don't have a RegisterMap available in most of | |
974 // the places we want to call this routine so we need to walk the | |
975 // stack again to update the register map. | |
976 if (map == NULL || !map->update_map()) { | |
977 StackFrameStream sfs(thread, true); | |
978 bool found = false; | |
979 while (!found && !sfs.is_done()) { | |
980 frame* cur = sfs.current(); | |
981 sfs.next(); | |
982 found = cur->id() == fr.id(); | |
983 } | |
984 assert(found, "frame to be deoptimized not found on target thread's stack"); | |
985 map = sfs.register_map(); | |
986 } | |
987 | |
988 vframe* vf = vframe::new_vframe(&fr, map, thread); | |
989 compiledVFrame* cvf = compiledVFrame::cast(vf); | |
990 // Revoke monitors' biases in all scopes | |
991 while (!cvf->is_top()) { | |
992 collect_monitors(cvf, objects_to_revoke); | |
993 cvf = compiledVFrame::cast(cvf->sender()); | |
994 } | |
995 collect_monitors(cvf, objects_to_revoke); | |
996 | |
997 if (SafepointSynchronize::is_at_safepoint()) { | |
998 BiasedLocking::revoke_at_safepoint(objects_to_revoke); | |
999 } else { | |
1000 BiasedLocking::revoke(objects_to_revoke); | |
1001 } | |
1002 } | |
1003 | |
1004 | |
1005 void Deoptimization::revoke_biases_of_monitors(CodeBlob* cb) { | |
1006 if (!UseBiasedLocking) { | |
1007 return; | |
1008 } | |
1009 | |
1010 assert(SafepointSynchronize::is_at_safepoint(), "must only be called from safepoint"); | |
1011 GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); | |
1012 for (JavaThread* jt = Threads::first(); jt != NULL ; jt = jt->next()) { | |
1013 if (jt->has_last_Java_frame()) { | |
1014 StackFrameStream sfs(jt, true); | |
1015 while (!sfs.is_done()) { | |
1016 frame* cur = sfs.current(); | |
1017 if (cb->contains(cur->pc())) { | |
1018 vframe* vf = vframe::new_vframe(cur, sfs.register_map(), jt); | |
1019 compiledVFrame* cvf = compiledVFrame::cast(vf); | |
1020 // Revoke monitors' biases in all scopes | |
1021 while (!cvf->is_top()) { | |
1022 collect_monitors(cvf, objects_to_revoke); | |
1023 cvf = compiledVFrame::cast(cvf->sender()); | |
1024 } | |
1025 collect_monitors(cvf, objects_to_revoke); | |
1026 } | |
1027 sfs.next(); | |
1028 } | |
1029 } | |
1030 } | |
1031 BiasedLocking::revoke_at_safepoint(objects_to_revoke); | |
1032 } | |
1033 | |
1034 | |
1035 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) { | |
1036 assert(fr.can_be_deoptimized(), "checking frame type"); | |
1037 | |
1038 gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal); | |
1039 | |
1040 EventMark m("Deoptimization (pc=" INTPTR_FORMAT ", sp=" INTPTR_FORMAT ")", fr.pc(), fr.id()); | |
1041 | |
1042 // Patch the nmethod so that when execution returns to it we will | |
1043 // deopt the execution state and return to the interpreter. | |
1044 fr.deoptimize(thread); | |
1045 } | |
1046 | |
1047 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) { | |
1048 // Deoptimize only if the frame comes from compile code. | |
1049 // Do not deoptimize the frame which is already patched | |
1050 // during the execution of the loops below. | |
1051 if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { | |
1052 return; | |
1053 } | |
1054 ResourceMark rm; | |
1055 DeoptimizationMarker dm; | |
1056 if (UseBiasedLocking) { | |
1057 revoke_biases_of_monitors(thread, fr, map); | |
1058 } | |
1059 deoptimize_single_frame(thread, fr); | |
1060 | |
1061 } | |
1062 | |
1063 | |
1064 void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { | |
1065 // Compute frame and register map based on thread and sp. | |
1066 RegisterMap reg_map(thread, UseBiasedLocking); | |
1067 frame fr = thread->last_frame(); | |
1068 while (fr.id() != id) { | |
1069 fr = fr.sender(®_map); | |
1070 } | |
1071 deoptimize(thread, fr, ®_map); | |
1072 } | |
1073 | |
1074 | |
1075 // JVMTI PopFrame support | |
1076 JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address)) | |
1077 { | |
1078 thread->popframe_preserve_args(in_ByteSize(bytes_to_save), start_address); | |
1079 } | |
1080 JRT_END | |
1081 | |
1082 | |
1692 | 1083 #if defined(COMPILER2) || defined(SHARK) |
0 | 1084 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { |
1085 // in case of an unresolved klass entry, load the class. | |
1086 if (constant_pool->tag_at(index).is_unresolved_klass()) { | |
1087 klassOop tk = constant_pool->klass_at(index, CHECK); | |
1088 return; | |
1089 } | |
1090 | |
1091 if (!constant_pool->tag_at(index).is_symbol()) return; | |
1092 | |
1093 Handle class_loader (THREAD, instanceKlass::cast(constant_pool->pool_holder())->class_loader()); | |
1094 symbolHandle symbol (THREAD, constant_pool->symbol_at(index)); | |
1095 | |
1096 // class name? | |
1097 if (symbol->byte_at(0) != '(') { | |
1098 Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); | |
1099 SystemDictionary::resolve_or_null(symbol, class_loader, protection_domain, CHECK); | |
1100 return; | |
1101 } | |
1102 | |
1103 // then it must be a signature! | |
1104 for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) { | |
1105 if (ss.is_object()) { | |
1106 symbolOop s = ss.as_symbol(CHECK); | |
1107 symbolHandle class_name (THREAD, s); | |
1108 Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); | |
1109 SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK); | |
1110 } | |
1111 } | |
1112 } | |
1113 | |
1114 | |
1115 void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index) { | |
1116 EXCEPTION_MARK; | |
1117 load_class_by_index(constant_pool, index, THREAD); | |
1118 if (HAS_PENDING_EXCEPTION) { | |
1119 // Exception happened during classloading. We ignore the exception here, since it | |
1120 // is going to be rethrown since the current activation is going to be deoptimzied and | |
1121 // the interpreter will re-execute the bytecode. | |
1122 CLEAR_PENDING_EXCEPTION; | |
1123 } | |
1124 } | |
1125 | |
1126 JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint trap_request)) { | |
1127 HandleMark hm; | |
1128 | |
1129 // uncommon_trap() is called at the beginning of the uncommon trap | |
1130 // handler. Note this fact before we start generating temporary frames | |
1131 // that can confuse an asynchronous stack walker. This counter is | |
1132 // decremented at the end of unpack_frames(). | |
1133 thread->inc_in_deopt_handler(); | |
1134 | |
1135 // We need to update the map if we have biased locking. | |
1136 RegisterMap reg_map(thread, UseBiasedLocking); | |
1137 frame stub_frame = thread->last_frame(); | |
1138 frame fr = stub_frame.sender(®_map); | |
1139 // Make sure the calling nmethod is not getting deoptimized and removed | |
1140 // before we are done with it. | |
1141 nmethodLocker nl(fr.pc()); | |
1142 | |
1143 { | |
1144 ResourceMark rm; | |
1145 | |
1146 // Revoke biases of any monitors in the frame to ensure we can migrate them | |
1147 revoke_biases_of_monitors(thread, fr, ®_map); | |
1148 | |
1149 DeoptReason reason = trap_request_reason(trap_request); | |
1150 DeoptAction action = trap_request_action(trap_request); | |
1151 jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1 | |
1152 | |
1153 Events::log("Uncommon trap occurred @" INTPTR_FORMAT " unloaded_class_index = %d", fr.pc(), (int) trap_request); | |
1154 vframe* vf = vframe::new_vframe(&fr, ®_map, thread); | |
1155 compiledVFrame* cvf = compiledVFrame::cast(vf); | |
1156 | |
1157 nmethod* nm = cvf->code(); | |
1158 | |
1159 ScopeDesc* trap_scope = cvf->scope(); | |
1160 methodHandle trap_method = trap_scope->method(); | |
1161 int trap_bci = trap_scope->bci(); | |
1162 Bytecodes::Code trap_bc = Bytecode_at(trap_method->bcp_from(trap_bci))->java_code(); | |
1163 | |
1164 // Record this event in the histogram. | |
1165 gather_statistics(reason, action, trap_bc); | |
1166 | |
1167 // Ensure that we can record deopt. history: | |
1168 bool create_if_missing = ProfileTraps; | |
1169 | |
1170 methodDataHandle trap_mdo | |
1171 (THREAD, get_method_data(thread, trap_method, create_if_missing)); | |
1172 | |
1173 // Print a bunch of diagnostics, if requested. | |
1174 if (TraceDeoptimization || LogCompilation) { | |
1175 ResourceMark rm; | |
1176 ttyLocker ttyl; | |
1177 char buf[100]; | |
1178 if (xtty != NULL) { | |
1179 xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT"' %s", | |
1180 os::current_thread_id(), | |
1181 format_trap_request(buf, sizeof(buf), trap_request)); | |
1182 nm->log_identity(xtty); | |
1183 } | |
1184 symbolHandle class_name; | |
1185 bool unresolved = false; | |
1186 if (unloaded_class_index >= 0) { | |
1187 constantPoolHandle constants (THREAD, trap_method->constants()); | |
1188 if (constants->tag_at(unloaded_class_index).is_unresolved_klass()) { | |
1189 class_name = symbolHandle(THREAD, | |
1190 constants->klass_name_at(unloaded_class_index)); | |
1191 unresolved = true; | |
1192 if (xtty != NULL) | |
1193 xtty->print(" unresolved='1'"); | |
1194 } else if (constants->tag_at(unloaded_class_index).is_symbol()) { | |
1195 class_name = symbolHandle(THREAD, | |
1196 constants->symbol_at(unloaded_class_index)); | |
1197 } | |
1198 if (xtty != NULL) | |
1199 xtty->name(class_name); | |
1200 } | |
1201 if (xtty != NULL && trap_mdo.not_null()) { | |
1202 // Dump the relevant MDO state. | |
1203 // This is the deopt count for the current reason, any previous | |
1204 // reasons or recompiles seen at this point. | |
1205 int dcnt = trap_mdo->trap_count(reason); | |
1206 if (dcnt != 0) | |
1207 xtty->print(" count='%d'", dcnt); | |
1208 ProfileData* pdata = trap_mdo->bci_to_data(trap_bci); | |
1209 int dos = (pdata == NULL)? 0: pdata->trap_state(); | |
1210 if (dos != 0) { | |
1211 xtty->print(" state='%s'", format_trap_state(buf, sizeof(buf), dos)); | |
1212 if (trap_state_is_recompiled(dos)) { | |
1213 int recnt2 = trap_mdo->overflow_recompile_count(); | |
1214 if (recnt2 != 0) | |
1215 xtty->print(" recompiles2='%d'", recnt2); | |
1216 } | |
1217 } | |
1218 } | |
1219 if (xtty != NULL) { | |
1220 xtty->stamp(); | |
1221 xtty->end_head(); | |
1222 } | |
1223 if (TraceDeoptimization) { // make noise on the tty | |
1224 tty->print("Uncommon trap occurred in"); | |
1225 nm->method()->print_short_name(tty); | |
1226 tty->print(" (@" INTPTR_FORMAT ") thread=%d reason=%s action=%s unloaded_class_index=%d", | |
1227 fr.pc(), | |
1228 (int) os::current_thread_id(), | |
1229 trap_reason_name(reason), | |
1230 trap_action_name(action), | |
1231 unloaded_class_index); | |
1232 if (class_name.not_null()) { | |
1233 tty->print(unresolved ? " unresolved class: " : " symbol: "); | |
1234 class_name->print_symbol_on(tty); | |
1235 } | |
1236 tty->cr(); | |
1237 } | |
1238 if (xtty != NULL) { | |
1239 // Log the precise location of the trap. | |
1240 for (ScopeDesc* sd = trap_scope; ; sd = sd->sender()) { | |
1241 xtty->begin_elem("jvms bci='%d'", sd->bci()); | |
1242 xtty->method(sd->method()); | |
1243 xtty->end_elem(); | |
1244 if (sd->is_top()) break; | |
1245 } | |
1246 xtty->tail("uncommon_trap"); | |
1247 } | |
1248 } | |
1249 // (End diagnostic printout.) | |
1250 | |
1251 // Load class if necessary | |
1252 if (unloaded_class_index >= 0) { | |
1253 constantPoolHandle constants(THREAD, trap_method->constants()); | |
1254 load_class_by_index(constants, unloaded_class_index); | |
1255 } | |
1256 | |
1257 // Flush the nmethod if necessary and desirable. | |
1258 // | |
1259 // We need to avoid situations where we are re-flushing the nmethod | |
1260 // because of a hot deoptimization site. Repeated flushes at the same | |
1261 // point need to be detected by the compiler and avoided. If the compiler | |
1262 // cannot avoid them (or has a bug and "refuses" to avoid them), this | |
1263 // module must take measures to avoid an infinite cycle of recompilation | |
1264 // and deoptimization. There are several such measures: | |
1265 // | |
1266 // 1. If a recompilation is ordered a second time at some site X | |
1267 // and for the same reason R, the action is adjusted to 'reinterpret', | |
1268 // to give the interpreter time to exercise the method more thoroughly. | |
1269 // If this happens, the method's overflow_recompile_count is incremented. | |
1270 // | |
1271 // 2. If the compiler fails to reduce the deoptimization rate, then | |
1272 // the method's overflow_recompile_count will begin to exceed the set | |
1273 // limit PerBytecodeRecompilationCutoff. If this happens, the action | |
1274 // is adjusted to 'make_not_compilable', and the method is abandoned | |
1275 // to the interpreter. This is a performance hit for hot methods, | |
1276 // but is better than a disastrous infinite cycle of recompilations. | |
1277 // (Actually, only the method containing the site X is abandoned.) | |
1278 // | |
1279 // 3. In parallel with the previous measures, if the total number of | |
1280 // recompilations of a method exceeds the much larger set limit | |
1281 // PerMethodRecompilationCutoff, the method is abandoned. | |
1282 // This should only happen if the method is very large and has | |
1283 // many "lukewarm" deoptimizations. The code which enforces this | |
1284 // limit is elsewhere (class nmethod, class methodOopDesc). | |
1285 // | |
1286 // Note that the per-BCI 'is_recompiled' bit gives the compiler one chance | |
1287 // to recompile at each bytecode independently of the per-BCI cutoff. | |
1288 // | |
1289 // The decision to update code is up to the compiler, and is encoded | |
1290 // in the Action_xxx code. If the compiler requests Action_none | |
1291 // no trap state is changed, no compiled code is changed, and the | |
1292 // computation suffers along in the interpreter. | |
1293 // | |
1294 // The other action codes specify various tactics for decompilation | |
1295 // and recompilation. Action_maybe_recompile is the loosest, and | |
1296 // allows the compiled code to stay around until enough traps are seen, | |
1297 // and until the compiler gets around to recompiling the trapping method. | |
1298 // | |
1299 // The other actions cause immediate removal of the present code. | |
1300 | |
1301 bool update_trap_state = true; | |
1302 bool make_not_entrant = false; | |
1303 bool make_not_compilable = false; | |
1304 bool reset_counters = false; | |
1305 switch (action) { | |
1306 case Action_none: | |
1307 // Keep the old code. | |
1308 update_trap_state = false; | |
1309 break; | |
1310 case Action_maybe_recompile: | |
1311 // Do not need to invalidate the present code, but we can | |
1312 // initiate another | |
1313 // Start compiler without (necessarily) invalidating the nmethod. | |
1314 // The system will tolerate the old code, but new code should be | |
1315 // generated when possible. | |
1316 break; | |
1317 case Action_reinterpret: | |
1318 // Go back into the interpreter for a while, and then consider | |
1319 // recompiling form scratch. | |
1320 make_not_entrant = true; | |
1321 // Reset invocation counter for outer most method. | |
1322 // This will allow the interpreter to exercise the bytecodes | |
1323 // for a while before recompiling. | |
1324 // By contrast, Action_make_not_entrant is immediate. | |
1325 // | |
1326 // Note that the compiler will track null_check, null_assert, | |
1327 // range_check, and class_check events and log them as if they | |
1328 // had been traps taken from compiled code. This will update | |
1329 // the MDO trap history so that the next compilation will | |
1330 // properly detect hot trap sites. | |
1331 reset_counters = true; | |
1332 break; | |
1333 case Action_make_not_entrant: | |
1334 // Request immediate recompilation, and get rid of the old code. | |
1335 // Make them not entrant, so next time they are called they get | |
1336 // recompiled. Unloaded classes are loaded now so recompile before next | |
1337 // time they are called. Same for uninitialized. The interpreter will | |
1338 // link the missing class, if any. | |
1339 make_not_entrant = true; | |
1340 break; | |
1341 case Action_make_not_compilable: | |
1342 // Give up on compiling this method at all. | |
1343 make_not_entrant = true; | |
1344 make_not_compilable = true; | |
1345 break; | |
1346 default: | |
1347 ShouldNotReachHere(); | |
1348 } | |
1349 | |
1350 // Setting +ProfileTraps fixes the following, on all platforms: | |
1351 // 4852688: ProfileInterpreter is off by default for ia64. The result is | |
1352 // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the | |
1353 // recompile relies on a methodDataOop to record heroic opt failures. | |
1354 | |
1355 // Whether the interpreter is producing MDO data or not, we also need | |
1356 // to use the MDO to detect hot deoptimization points and control | |
1357 // aggressive optimization. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1358 bool inc_recompile_count = false; |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1359 ProfileData* pdata = NULL; |
0 | 1360 if (ProfileTraps && update_trap_state && trap_mdo.not_null()) { |
1361 assert(trap_mdo() == get_method_data(thread, trap_method, false), "sanity"); | |
1362 uint this_trap_count = 0; | |
1363 bool maybe_prior_trap = false; | |
1364 bool maybe_prior_recompile = false; | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1365 pdata = query_update_method_data(trap_mdo, trap_bci, reason, |
0 | 1366 //outputs: |
1367 this_trap_count, | |
1368 maybe_prior_trap, | |
1369 maybe_prior_recompile); | |
1370 // Because the interpreter also counts null, div0, range, and class | |
1371 // checks, these traps from compiled code are double-counted. | |
1372 // This is harmless; it just means that the PerXTrapLimit values | |
1373 // are in effect a little smaller than they look. | |
1374 | |
1375 DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); | |
1376 if (per_bc_reason != Reason_none) { | |
1377 // Now take action based on the partially known per-BCI history. | |
1378 if (maybe_prior_trap | |
1379 && this_trap_count >= (uint)PerBytecodeTrapLimit) { | |
1380 // If there are too many traps at this BCI, force a recompile. | |
1381 // This will allow the compiler to see the limit overflow, and | |
1382 // take corrective action, if possible. The compiler generally | |
1383 // does not use the exact PerBytecodeTrapLimit value, but instead | |
1384 // changes its tactics if it sees any traps at all. This provides | |
1385 // a little hysteresis, delaying a recompile until a trap happens | |
1386 // several times. | |
1387 // | |
1388 // Actually, since there is only one bit of counter per BCI, | |
1389 // the possible per-BCI counts are {0,1,(per-method count)}. | |
1390 // This produces accurate results if in fact there is only | |
1391 // one hot trap site, but begins to get fuzzy if there are | |
1392 // many sites. For example, if there are ten sites each | |
1393 // trapping two or more times, they each get the blame for | |
1394 // all of their traps. | |
1395 make_not_entrant = true; | |
1396 } | |
1397 | |
1398 // Detect repeated recompilation at the same BCI, and enforce a limit. | |
1399 if (make_not_entrant && maybe_prior_recompile) { | |
1400 // More than one recompile at this point. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1401 inc_recompile_count = maybe_prior_trap; |
0 | 1402 } |
1403 } else { | |
1404 // For reasons which are not recorded per-bytecode, we simply | |
1405 // force recompiles unconditionally. | |
1406 // (Note that PerMethodRecompilationCutoff is enforced elsewhere.) | |
1407 make_not_entrant = true; | |
1408 } | |
1409 | |
1410 // Go back to the compiler if there are too many traps in this method. | |
1411 if (this_trap_count >= (uint)PerMethodTrapLimit) { | |
1412 // If there are too many traps in this method, force a recompile. | |
1413 // This will allow the compiler to see the limit overflow, and | |
1414 // take corrective action, if possible. | |
1415 // (This condition is an unlikely backstop only, because the | |
1416 // PerBytecodeTrapLimit is more likely to take effect first, | |
1417 // if it is applicable.) | |
1418 make_not_entrant = true; | |
1419 } | |
1420 | |
1421 // Here's more hysteresis: If there has been a recompile at | |
1422 // this trap point already, run the method in the interpreter | |
1423 // for a while to exercise it more thoroughly. | |
1424 if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { | |
1425 reset_counters = true; | |
1426 } | |
1427 | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1428 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1429 |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1430 // Take requested actions on the method: |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1431 |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1432 // Recompile |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1433 if (make_not_entrant) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1434 if (!nm->make_not_entrant()) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1435 return; // the call did not change nmethod's state |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1436 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1437 |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1438 if (pdata != NULL) { |
0 | 1439 // Record the recompilation event, if any. |
1440 int tstate0 = pdata->trap_state(); | |
1441 int tstate1 = trap_state_set_recompiled(tstate0, true); | |
1442 if (tstate1 != tstate0) | |
1443 pdata->set_trap_state(tstate1); | |
1444 } | |
1445 } | |
1446 | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1447 if (inc_recompile_count) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1448 trap_mdo->inc_overflow_recompile_count(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1449 if ((uint)trap_mdo->overflow_recompile_count() > |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1450 (uint)PerBytecodeRecompilationCutoff) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1451 // Give up on the method containing the bad BCI. |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1452 if (trap_method() == nm->method()) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1453 make_not_compilable = true; |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1454 } else { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1455 trap_method->set_not_compilable(); |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1456 // But give grace to the enclosing nm->method(). |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1457 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1458 } |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1459 } |
0 | 1460 |
1461 // Reset invocation counters | |
1462 if (reset_counters) { | |
1463 if (nm->is_osr_method()) | |
1464 reset_invocation_counter(trap_scope, CompileThreshold); | |
1465 else | |
1466 reset_invocation_counter(trap_scope); | |
1467 } | |
1468 | |
1469 // Give up compiling | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1470 if (make_not_compilable && !nm->method()->is_not_compilable()) { |
0 | 1471 assert(make_not_entrant, "consistent"); |
1472 nm->method()->set_not_compilable(); | |
1473 } | |
1474 | |
1475 } // Free marked resources | |
1476 | |
1477 } | |
1478 JRT_END | |
1479 | |
1480 methodDataOop | |
1481 Deoptimization::get_method_data(JavaThread* thread, methodHandle m, | |
1482 bool create_if_missing) { | |
1483 Thread* THREAD = thread; | |
1484 methodDataOop mdo = m()->method_data(); | |
1485 if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { | |
1486 // Build an MDO. Ignore errors like OutOfMemory; | |
1487 // that simply means we won't have an MDO to update. | |
1488 methodOopDesc::build_interpreter_method_data(m, THREAD); | |
1489 if (HAS_PENDING_EXCEPTION) { | |
1490 assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); | |
1491 CLEAR_PENDING_EXCEPTION; | |
1492 } | |
1493 mdo = m()->method_data(); | |
1494 } | |
1495 return mdo; | |
1496 } | |
1497 | |
1498 ProfileData* | |
1499 Deoptimization::query_update_method_data(methodDataHandle trap_mdo, | |
1500 int trap_bci, | |
1501 Deoptimization::DeoptReason reason, | |
1502 //outputs: | |
1503 uint& ret_this_trap_count, | |
1504 bool& ret_maybe_prior_trap, | |
1505 bool& ret_maybe_prior_recompile) { | |
1506 uint prior_trap_count = trap_mdo->trap_count(reason); | |
1507 uint this_trap_count = trap_mdo->inc_trap_count(reason); | |
1508 | |
1509 // If the runtime cannot find a place to store trap history, | |
1510 // it is estimated based on the general condition of the method. | |
1511 // If the method has ever been recompiled, or has ever incurred | |
1512 // a trap with the present reason , then this BCI is assumed | |
1513 // (pessimistically) to be the culprit. | |
1514 bool maybe_prior_trap = (prior_trap_count != 0); | |
1515 bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0); | |
1516 ProfileData* pdata = NULL; | |
1517 | |
1518 | |
1519 // For reasons which are recorded per bytecode, we check per-BCI data. | |
1520 DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); | |
1521 if (per_bc_reason != Reason_none) { | |
1522 // Find the profile data for this BCI. If there isn't one, | |
1523 // try to allocate one from the MDO's set of spares. | |
1524 // This will let us detect a repeated trap at this point. | |
1525 pdata = trap_mdo->allocate_bci_to_data(trap_bci); | |
1526 | |
1527 if (pdata != NULL) { | |
1528 // Query the trap state of this profile datum. | |
1529 int tstate0 = pdata->trap_state(); | |
1530 if (!trap_state_has_reason(tstate0, per_bc_reason)) | |
1531 maybe_prior_trap = false; | |
1532 if (!trap_state_is_recompiled(tstate0)) | |
1533 maybe_prior_recompile = false; | |
1534 | |
1535 // Update the trap state of this profile datum. | |
1536 int tstate1 = tstate0; | |
1537 // Record the reason. | |
1538 tstate1 = trap_state_add_reason(tstate1, per_bc_reason); | |
1539 // Store the updated state on the MDO, for next time. | |
1540 if (tstate1 != tstate0) | |
1541 pdata->set_trap_state(tstate1); | |
1542 } else { | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1543 if (LogCompilation && xtty != NULL) { |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1544 ttyLocker ttyl; |
0 | 1545 // Missing MDP? Leave a small complaint in the log. |
1546 xtty->elem("missing_mdp bci='%d'", trap_bci); | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1547 } |
0 | 1548 } |
1549 } | |
1550 | |
1551 // Return results: | |
1552 ret_this_trap_count = this_trap_count; | |
1553 ret_maybe_prior_trap = maybe_prior_trap; | |
1554 ret_maybe_prior_recompile = maybe_prior_recompile; | |
1555 return pdata; | |
1556 } | |
1557 | |
1558 void | |
1559 Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) { | |
1560 ResourceMark rm; | |
1561 // Ignored outputs: | |
1562 uint ignore_this_trap_count; | |
1563 bool ignore_maybe_prior_trap; | |
1564 bool ignore_maybe_prior_recompile; | |
1565 query_update_method_data(trap_mdo, trap_bci, | |
1566 (DeoptReason)reason, | |
1567 ignore_this_trap_count, | |
1568 ignore_maybe_prior_trap, | |
1569 ignore_maybe_prior_recompile); | |
1570 } | |
1571 | |
1572 void Deoptimization::reset_invocation_counter(ScopeDesc* trap_scope, jint top_count) { | |
1573 ScopeDesc* sd = trap_scope; | |
1574 for (; !sd->is_top(); sd = sd->sender()) { | |
1575 // Reset ICs of inlined methods, since they can trigger compilations also. | |
1576 sd->method()->invocation_counter()->reset(); | |
1577 } | |
1578 InvocationCounter* c = sd->method()->invocation_counter(); | |
1579 if (top_count != _no_count) { | |
1580 // It was an OSR method, so bump the count higher. | |
1581 c->set(c->state(), top_count); | |
1582 } else { | |
1583 c->reset(); | |
1584 } | |
1585 sd->method()->backedge_counter()->reset(); | |
1586 } | |
1587 | |
1588 Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) { | |
1589 | |
1590 // Still in Java no safepoints | |
1591 { | |
1592 // This enters VM and may safepoint | |
1593 uncommon_trap_inner(thread, trap_request); | |
1594 } | |
1595 return fetch_unroll_info_helper(thread); | |
1596 } | |
1597 | |
1598 // Local derived constants. | |
1599 // Further breakdown of DataLayout::trap_state, as promised by DataLayout. | |
1600 const int DS_REASON_MASK = DataLayout::trap_mask >> 1; | |
1601 const int DS_RECOMPILE_BIT = DataLayout::trap_mask - DS_REASON_MASK; | |
1602 | |
1603 //---------------------------trap_state_reason--------------------------------- | |
1604 Deoptimization::DeoptReason | |
1605 Deoptimization::trap_state_reason(int trap_state) { | |
1606 // This assert provides the link between the width of DataLayout::trap_bits | |
1607 // and the encoding of "recorded" reasons. It ensures there are enough | |
1608 // bits to store all needed reasons in the per-BCI MDO profile. | |
1609 assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits"); | |
1610 int recompile_bit = (trap_state & DS_RECOMPILE_BIT); | |
1611 trap_state -= recompile_bit; | |
1612 if (trap_state == DS_REASON_MASK) { | |
1613 return Reason_many; | |
1614 } else { | |
1615 assert((int)Reason_none == 0, "state=0 => Reason_none"); | |
1616 return (DeoptReason)trap_state; | |
1617 } | |
1618 } | |
1619 //-------------------------trap_state_has_reason------------------------------- | |
1620 int Deoptimization::trap_state_has_reason(int trap_state, int reason) { | |
1621 assert(reason_is_recorded_per_bytecode((DeoptReason)reason), "valid reason"); | |
1622 assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits"); | |
1623 int recompile_bit = (trap_state & DS_RECOMPILE_BIT); | |
1624 trap_state -= recompile_bit; | |
1625 if (trap_state == DS_REASON_MASK) { | |
1626 return -1; // true, unspecifically (bottom of state lattice) | |
1627 } else if (trap_state == reason) { | |
1628 return 1; // true, definitely | |
1629 } else if (trap_state == 0) { | |
1630 return 0; // false, definitely (top of state lattice) | |
1631 } else { | |
1632 return 0; // false, definitely | |
1633 } | |
1634 } | |
1635 //-------------------------trap_state_add_reason------------------------------- | |
1636 int Deoptimization::trap_state_add_reason(int trap_state, int reason) { | |
1637 assert(reason_is_recorded_per_bytecode((DeoptReason)reason) || reason == Reason_many, "valid reason"); | |
1638 int recompile_bit = (trap_state & DS_RECOMPILE_BIT); | |
1639 trap_state -= recompile_bit; | |
1640 if (trap_state == DS_REASON_MASK) { | |
1641 return trap_state + recompile_bit; // already at state lattice bottom | |
1642 } else if (trap_state == reason) { | |
1643 return trap_state + recompile_bit; // the condition is already true | |
1644 } else if (trap_state == 0) { | |
1645 return reason + recompile_bit; // no condition has yet been true | |
1646 } else { | |
1647 return DS_REASON_MASK + recompile_bit; // fall to state lattice bottom | |
1648 } | |
1649 } | |
1650 //-----------------------trap_state_is_recompiled------------------------------ | |
1651 bool Deoptimization::trap_state_is_recompiled(int trap_state) { | |
1652 return (trap_state & DS_RECOMPILE_BIT) != 0; | |
1653 } | |
1654 //-----------------------trap_state_set_recompiled----------------------------- | |
1655 int Deoptimization::trap_state_set_recompiled(int trap_state, bool z) { | |
1656 if (z) return trap_state | DS_RECOMPILE_BIT; | |
1657 else return trap_state & ~DS_RECOMPILE_BIT; | |
1658 } | |
1659 //---------------------------format_trap_state--------------------------------- | |
1660 // This is used for debugging and diagnostics, including hotspot.log output. | |
1661 const char* Deoptimization::format_trap_state(char* buf, size_t buflen, | |
1662 int trap_state) { | |
1663 DeoptReason reason = trap_state_reason(trap_state); | |
1664 bool recomp_flag = trap_state_is_recompiled(trap_state); | |
1665 // Re-encode the state from its decoded components. | |
1666 int decoded_state = 0; | |
1667 if (reason_is_recorded_per_bytecode(reason) || reason == Reason_many) | |
1668 decoded_state = trap_state_add_reason(decoded_state, reason); | |
1669 if (recomp_flag) | |
1670 decoded_state = trap_state_set_recompiled(decoded_state, recomp_flag); | |
1671 // If the state re-encodes properly, format it symbolically. | |
1672 // Because this routine is used for debugging and diagnostics, | |
1673 // be robust even if the state is a strange value. | |
1674 size_t len; | |
1675 if (decoded_state != trap_state) { | |
1676 // Random buggy state that doesn't decode?? | |
1677 len = jio_snprintf(buf, buflen, "#%d", trap_state); | |
1678 } else { | |
1679 len = jio_snprintf(buf, buflen, "%s%s", | |
1680 trap_reason_name(reason), | |
1681 recomp_flag ? " recompiled" : ""); | |
1682 } | |
1683 if (len >= buflen) | |
1684 buf[buflen-1] = '\0'; | |
1685 return buf; | |
1686 } | |
1687 | |
1688 | |
1689 //--------------------------------statics-------------------------------------- | |
1690 Deoptimization::DeoptAction Deoptimization::_unloaded_action | |
1691 = Deoptimization::Action_reinterpret; | |
1692 const char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { | |
1693 // Note: Keep this in sync. with enum DeoptReason. | |
1694 "none", | |
1695 "null_check", | |
1696 "null_assert", | |
1697 "range_check", | |
1698 "class_check", | |
1699 "array_check", | |
1700 "intrinsic", | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1204
diff
changeset
|
1701 "bimorphic", |
0 | 1702 "unloaded", |
1703 "uninitialized", | |
1704 "unreached", | |
1705 "unhandled", | |
1706 "constraint", | |
1707 "div0_check", | |
1172 | 1708 "age", |
1709 "predicate" | |
0 | 1710 }; |
1711 const char* Deoptimization::_trap_action_name[Action_LIMIT] = { | |
1712 // Note: Keep this in sync. with enum DeoptAction. | |
1713 "none", | |
1714 "maybe_recompile", | |
1715 "reinterpret", | |
1716 "make_not_entrant", | |
1717 "make_not_compilable" | |
1718 }; | |
1719 | |
1720 const char* Deoptimization::trap_reason_name(int reason) { | |
1721 if (reason == Reason_many) return "many"; | |
1722 if ((uint)reason < Reason_LIMIT) | |
1723 return _trap_reason_name[reason]; | |
1724 static char buf[20]; | |
1725 sprintf(buf, "reason%d", reason); | |
1726 return buf; | |
1727 } | |
1728 const char* Deoptimization::trap_action_name(int action) { | |
1729 if ((uint)action < Action_LIMIT) | |
1730 return _trap_action_name[action]; | |
1731 static char buf[20]; | |
1732 sprintf(buf, "action%d", action); | |
1733 return buf; | |
1734 } | |
1735 | |
1736 // This is used for debugging and diagnostics, including hotspot.log output. | |
1737 const char* Deoptimization::format_trap_request(char* buf, size_t buflen, | |
1738 int trap_request) { | |
1739 jint unloaded_class_index = trap_request_index(trap_request); | |
1740 const char* reason = trap_reason_name(trap_request_reason(trap_request)); | |
1741 const char* action = trap_action_name(trap_request_action(trap_request)); | |
1742 size_t len; | |
1743 if (unloaded_class_index < 0) { | |
1744 len = jio_snprintf(buf, buflen, "reason='%s' action='%s'", | |
1745 reason, action); | |
1746 } else { | |
1747 len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'", | |
1748 reason, action, unloaded_class_index); | |
1749 } | |
1750 if (len >= buflen) | |
1751 buf[buflen-1] = '\0'; | |
1752 return buf; | |
1753 } | |
1754 | |
1755 juint Deoptimization::_deoptimization_hist | |
1756 [Deoptimization::Reason_LIMIT] | |
1757 [1 + Deoptimization::Action_LIMIT] | |
1758 [Deoptimization::BC_CASE_LIMIT] | |
1759 = {0}; | |
1760 | |
1761 enum { | |
1762 LSB_BITS = 8, | |
1763 LSB_MASK = right_n_bits(LSB_BITS) | |
1764 }; | |
1765 | |
1766 void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action, | |
1767 Bytecodes::Code bc) { | |
1768 assert(reason >= 0 && reason < Reason_LIMIT, "oob"); | |
1769 assert(action >= 0 && action < Action_LIMIT, "oob"); | |
1770 _deoptimization_hist[Reason_none][0][0] += 1; // total | |
1771 _deoptimization_hist[reason][0][0] += 1; // per-reason total | |
1772 juint* cases = _deoptimization_hist[reason][1+action]; | |
1773 juint* bc_counter_addr = NULL; | |
1774 juint bc_counter = 0; | |
1775 // Look for an unused counter, or an exact match to this BC. | |
1776 if (bc != Bytecodes::_illegal) { | |
1777 for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) { | |
1778 juint* counter_addr = &cases[bc_case]; | |
1779 juint counter = *counter_addr; | |
1780 if ((counter == 0 && bc_counter_addr == NULL) | |
1781 || (Bytecodes::Code)(counter & LSB_MASK) == bc) { | |
1782 // this counter is either free or is already devoted to this BC | |
1783 bc_counter_addr = counter_addr; | |
1784 bc_counter = counter | bc; | |
1785 } | |
1786 } | |
1787 } | |
1788 if (bc_counter_addr == NULL) { | |
1789 // Overflow, or no given bytecode. | |
1790 bc_counter_addr = &cases[BC_CASE_LIMIT-1]; | |
1791 bc_counter = (*bc_counter_addr & ~LSB_MASK); // clear LSB | |
1792 } | |
1793 *bc_counter_addr = bc_counter + (1 << LSB_BITS); | |
1794 } | |
1795 | |
1796 jint Deoptimization::total_deoptimization_count() { | |
1797 return _deoptimization_hist[Reason_none][0][0]; | |
1798 } | |
1799 | |
1800 jint Deoptimization::deoptimization_count(DeoptReason reason) { | |
1801 assert(reason >= 0 && reason < Reason_LIMIT, "oob"); | |
1802 return _deoptimization_hist[reason][0][0]; | |
1803 } | |
1804 | |
1805 void Deoptimization::print_statistics() { | |
1806 juint total = total_deoptimization_count(); | |
1807 juint account = total; | |
1808 if (total != 0) { | |
1809 ttyLocker ttyl; | |
1810 if (xtty != NULL) xtty->head("statistics type='deoptimization'"); | |
1811 tty->print_cr("Deoptimization traps recorded:"); | |
1812 #define PRINT_STAT_LINE(name, r) \ | |
1813 tty->print_cr(" %4d (%4.1f%%) %s", (int)(r), ((r) * 100.0) / total, name); | |
1814 PRINT_STAT_LINE("total", total); | |
1815 // For each non-zero entry in the histogram, print the reason, | |
1816 // the action, and (if specifically known) the type of bytecode. | |
1817 for (int reason = 0; reason < Reason_LIMIT; reason++) { | |
1818 for (int action = 0; action < Action_LIMIT; action++) { | |
1819 juint* cases = _deoptimization_hist[reason][1+action]; | |
1820 for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) { | |
1821 juint counter = cases[bc_case]; | |
1822 if (counter != 0) { | |
1823 char name[1*K]; | |
1824 Bytecodes::Code bc = (Bytecodes::Code)(counter & LSB_MASK); | |
1825 if (bc_case == BC_CASE_LIMIT && (int)bc == 0) | |
1826 bc = Bytecodes::_illegal; | |
1827 sprintf(name, "%s/%s/%s", | |
1828 trap_reason_name(reason), | |
1829 trap_action_name(action), | |
1830 Bytecodes::is_defined(bc)? Bytecodes::name(bc): "other"); | |
1831 juint r = counter >> LSB_BITS; | |
1832 tty->print_cr(" %40s: " UINT32_FORMAT " (%.1f%%)", name, r, (r * 100.0) / total); | |
1833 account -= r; | |
1834 } | |
1835 } | |
1836 } | |
1837 } | |
1838 if (account != 0) { | |
1839 PRINT_STAT_LINE("unaccounted", account); | |
1840 } | |
1841 #undef PRINT_STAT_LINE | |
1842 if (xtty != NULL) xtty->tail("statistics"); | |
1843 } | |
1844 } | |
1692 | 1845 #else // COMPILER2 || SHARK |
0 | 1846 |
1847 | |
1848 // Stubs for C1 only system. | |
1849 bool Deoptimization::trap_state_is_recompiled(int trap_state) { | |
1850 return false; | |
1851 } | |
1852 | |
1853 const char* Deoptimization::trap_reason_name(int reason) { | |
1854 return "unknown"; | |
1855 } | |
1856 | |
1857 void Deoptimization::print_statistics() { | |
1858 // no output | |
1859 } | |
1860 | |
1861 void | |
1862 Deoptimization::update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason) { | |
1863 // no udpate | |
1864 } | |
1865 | |
1866 int Deoptimization::trap_state_has_reason(int trap_state, int reason) { | |
1867 return 0; | |
1868 } | |
1869 | |
1870 void Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action, | |
1871 Bytecodes::Code bc) { | |
1872 // no update | |
1873 } | |
1874 | |
1875 const char* Deoptimization::format_trap_state(char* buf, size_t buflen, | |
1876 int trap_state) { | |
1877 jio_snprintf(buf, buflen, "#%d", trap_state); | |
1878 return buf; | |
1879 } | |
1880 | |
1692 | 1881 #endif // COMPILER2 || SHARK |