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