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