Mercurial > hg > truffle
annotate src/share/vm/c1/c1_Runtime1.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | d8ce2825b193 |
rev | line source |
---|---|
0 | 1 /* |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4825
diff
changeset
|
2 * Copyright (c) 1999, 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:
1247
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1247
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:
1247
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/codeBuffer.hpp" | |
27 #include "c1/c1_CodeStubs.hpp" | |
28 #include "c1/c1_Defs.hpp" | |
29 #include "c1/c1_FrameMap.hpp" | |
30 #include "c1/c1_LIRAssembler.hpp" | |
31 #include "c1/c1_MacroAssembler.hpp" | |
32 #include "c1/c1_Runtime1.hpp" | |
33 #include "classfile/systemDictionary.hpp" | |
34 #include "classfile/vmSymbols.hpp" | |
35 #include "code/codeBlob.hpp" | |
36 #include "code/compiledIC.hpp" | |
37 #include "code/pcDesc.hpp" | |
38 #include "code/scopeDesc.hpp" | |
39 #include "code/vtableStubs.hpp" | |
40 #include "compiler/disassembler.hpp" | |
41 #include "gc_interface/collectedHeap.hpp" | |
42 #include "interpreter/bytecode.hpp" | |
43 #include "interpreter/interpreter.hpp" | |
44 #include "memory/allocation.inline.hpp" | |
45 #include "memory/barrierSet.hpp" | |
46 #include "memory/oopFactory.hpp" | |
47 #include "memory/resourceArea.hpp" | |
48 #include "oops/objArrayKlass.hpp" | |
49 #include "oops/oop.inline.hpp" | |
50 #include "runtime/biasedLocking.hpp" | |
51 #include "runtime/compilationPolicy.hpp" | |
52 #include "runtime/interfaceSupport.hpp" | |
53 #include "runtime/javaCalls.hpp" | |
54 #include "runtime/sharedRuntime.hpp" | |
55 #include "runtime/threadCritical.hpp" | |
56 #include "runtime/vframe.hpp" | |
57 #include "runtime/vframeArray.hpp" | |
58 #include "utilities/copy.hpp" | |
59 #include "utilities/events.hpp" | |
0 | 60 |
61 | |
62 // Implementation of StubAssembler | |
63 | |
64 StubAssembler::StubAssembler(CodeBuffer* code, const char * name, int stub_id) : C1_MacroAssembler(code) { | |
65 _name = name; | |
66 _must_gc_arguments = false; | |
67 _frame_size = no_frame_size; | |
68 _num_rt_args = 0; | |
69 _stub_id = stub_id; | |
70 } | |
71 | |
72 | |
73 void StubAssembler::set_info(const char* name, bool must_gc_arguments) { | |
74 _name = name; | |
75 _must_gc_arguments = must_gc_arguments; | |
76 } | |
77 | |
78 | |
79 void StubAssembler::set_frame_size(int size) { | |
80 if (_frame_size == no_frame_size) { | |
81 _frame_size = size; | |
82 } | |
83 assert(_frame_size == size, "can't change the frame size"); | |
84 } | |
85 | |
86 | |
87 void StubAssembler::set_num_rt_args(int args) { | |
88 if (_num_rt_args == 0) { | |
89 _num_rt_args = args; | |
90 } | |
91 assert(_num_rt_args == args, "can't change the number of args"); | |
92 } | |
93 | |
94 // Implementation of Runtime1 | |
95 | |
96 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids]; | |
97 const char *Runtime1::_blob_names[] = { | |
98 RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME) | |
99 }; | |
100 | |
101 #ifndef PRODUCT | |
102 // statistics | |
103 int Runtime1::_generic_arraycopy_cnt = 0; | |
104 int Runtime1::_primitive_arraycopy_cnt = 0; | |
105 int Runtime1::_oop_arraycopy_cnt = 0; | |
2446 | 106 int Runtime1::_generic_arraycopystub_cnt = 0; |
0 | 107 int Runtime1::_arraycopy_slowcase_cnt = 0; |
2446 | 108 int Runtime1::_arraycopy_checkcast_cnt = 0; |
109 int Runtime1::_arraycopy_checkcast_attempt_cnt = 0; | |
0 | 110 int Runtime1::_new_type_array_slowcase_cnt = 0; |
111 int Runtime1::_new_object_array_slowcase_cnt = 0; | |
112 int Runtime1::_new_instance_slowcase_cnt = 0; | |
113 int Runtime1::_new_multi_array_slowcase_cnt = 0; | |
114 int Runtime1::_monitorenter_slowcase_cnt = 0; | |
115 int Runtime1::_monitorexit_slowcase_cnt = 0; | |
116 int Runtime1::_patch_code_slowcase_cnt = 0; | |
117 int Runtime1::_throw_range_check_exception_count = 0; | |
118 int Runtime1::_throw_index_exception_count = 0; | |
119 int Runtime1::_throw_div0_exception_count = 0; | |
120 int Runtime1::_throw_null_pointer_exception_count = 0; | |
121 int Runtime1::_throw_class_cast_exception_count = 0; | |
122 int Runtime1::_throw_incompatible_class_change_error_count = 0; | |
123 int Runtime1::_throw_array_store_exception_count = 0; | |
124 int Runtime1::_throw_count = 0; | |
2446 | 125 |
126 static int _byte_arraycopy_cnt = 0; | |
127 static int _short_arraycopy_cnt = 0; | |
128 static int _int_arraycopy_cnt = 0; | |
129 static int _long_arraycopy_cnt = 0; | |
130 static int _oop_arraycopy_cnt = 0; | |
131 | |
132 address Runtime1::arraycopy_count_address(BasicType type) { | |
133 switch (type) { | |
134 case T_BOOLEAN: | |
135 case T_BYTE: return (address)&_byte_arraycopy_cnt; | |
136 case T_CHAR: | |
137 case T_SHORT: return (address)&_short_arraycopy_cnt; | |
138 case T_FLOAT: | |
139 case T_INT: return (address)&_int_arraycopy_cnt; | |
140 case T_DOUBLE: | |
141 case T_LONG: return (address)&_long_arraycopy_cnt; | |
142 case T_ARRAY: | |
143 case T_OBJECT: return (address)&_oop_arraycopy_cnt; | |
144 default: | |
145 ShouldNotReachHere(); | |
146 return NULL; | |
147 } | |
148 } | |
149 | |
150 | |
0 | 151 #endif |
152 | |
153 // Simple helper to see if the caller of a runtime stub which | |
154 // entered the VM has been deoptimized | |
155 | |
156 static bool caller_is_deopted() { | |
157 JavaThread* thread = JavaThread::current(); | |
158 RegisterMap reg_map(thread, false); | |
159 frame runtime_frame = thread->last_frame(); | |
160 frame caller_frame = runtime_frame.sender(®_map); | |
161 assert(caller_frame.is_compiled_frame(), "must be compiled"); | |
162 return caller_frame.is_deoptimized_frame(); | |
163 } | |
164 | |
165 // Stress deoptimization | |
166 static void deopt_caller() { | |
167 if ( !caller_is_deopted()) { | |
168 JavaThread* thread = JavaThread::current(); | |
169 RegisterMap reg_map(thread, false); | |
170 frame runtime_frame = thread->last_frame(); | |
171 frame caller_frame = runtime_frame.sender(®_map); | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
172 Deoptimization::deoptimize_frame(thread, caller_frame.id()); |
0 | 173 assert(caller_is_deopted(), "Must be deoptimized"); |
174 } | |
175 } | |
176 | |
177 | |
1584 | 178 void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) { |
0 | 179 assert(0 <= id && id < number_of_ids, "illegal stub id"); |
180 ResourceMark rm; | |
181 // create code buffer for code storage | |
1748 | 182 CodeBuffer code(buffer_blob); |
0 | 183 |
1584 | 184 Compilation::setup_code_buffer(&code, 0); |
0 | 185 |
186 // create assembler for code generation | |
187 StubAssembler* sasm = new StubAssembler(&code, name_for(id), id); | |
188 // generate code for runtime stub | |
189 OopMapSet* oop_maps; | |
190 oop_maps = generate_code_for(id, sasm); | |
191 assert(oop_maps == NULL || sasm->frame_size() != no_frame_size, | |
192 "if stub has an oop map it must have a valid frame size"); | |
193 | |
194 #ifdef ASSERT | |
195 // Make sure that stubs that need oopmaps have them | |
196 switch (id) { | |
197 // These stubs don't need to have an oopmap | |
198 case dtrace_object_alloc_id: | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
199 case g1_pre_barrier_slow_id: |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
200 case g1_post_barrier_slow_id: |
0 | 201 case slow_subtype_check_id: |
202 case fpu2long_stub_id: | |
203 case unwind_exception_id: | |
1783 | 204 case counter_overflow_id: |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
205 #if defined(SPARC) || defined(PPC) |
0 | 206 case handle_exception_nofpu_id: // Unused on sparc |
207 #endif | |
208 break; | |
209 | |
210 // All other stubs should have oopmaps | |
211 default: | |
212 assert(oop_maps != NULL, "must have an oopmap"); | |
213 } | |
214 #endif | |
215 | |
216 // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned) | |
217 sasm->align(BytesPerWord); | |
218 // make sure all code is in code buffer | |
219 sasm->flush(); | |
220 // create blob - distinguish a few special cases | |
221 CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id), | |
222 &code, | |
223 CodeOffsets::frame_never_safe, | |
224 sasm->frame_size(), | |
225 oop_maps, | |
226 sasm->must_gc_arguments()); | |
227 // install blob | |
228 assert(blob != NULL, "blob must exist"); | |
229 _blobs[id] = blob; | |
230 } | |
231 | |
232 | |
1584 | 233 void Runtime1::initialize(BufferBlob* blob) { |
234 // platform-dependent initialization | |
235 initialize_pd(); | |
236 // generate stubs | |
237 for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id); | |
238 // printing | |
0 | 239 #ifndef PRODUCT |
1584 | 240 if (PrintSimpleStubs) { |
241 ResourceMark rm; | |
242 for (int id = 0; id < number_of_ids; id++) { | |
243 _blobs[id]->print(); | |
244 if (_blobs[id]->oop_maps() != NULL) { | |
245 _blobs[id]->oop_maps()->print(); | |
0 | 246 } |
247 } | |
1584 | 248 } |
0 | 249 #endif |
250 } | |
251 | |
252 | |
253 CodeBlob* Runtime1::blob_for(StubID id) { | |
254 assert(0 <= id && id < number_of_ids, "illegal stub id"); | |
255 return _blobs[id]; | |
256 } | |
257 | |
258 | |
259 const char* Runtime1::name_for(StubID id) { | |
260 assert(0 <= id && id < number_of_ids, "illegal stub id"); | |
261 return _blob_names[id]; | |
262 } | |
263 | |
264 const char* Runtime1::name_for_address(address entry) { | |
265 for (int id = 0; id < number_of_ids; id++) { | |
266 if (entry == entry_for((StubID)id)) return name_for((StubID)id); | |
267 } | |
268 | |
269 #define FUNCTION_CASE(a, f) \ | |
270 if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f)) return #f | |
271 | |
272 FUNCTION_CASE(entry, os::javaTimeMillis); | |
273 FUNCTION_CASE(entry, os::javaTimeNanos); | |
274 FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end); | |
275 FUNCTION_CASE(entry, SharedRuntime::d2f); | |
276 FUNCTION_CASE(entry, SharedRuntime::d2i); | |
277 FUNCTION_CASE(entry, SharedRuntime::d2l); | |
278 FUNCTION_CASE(entry, SharedRuntime::dcos); | |
279 FUNCTION_CASE(entry, SharedRuntime::dexp); | |
280 FUNCTION_CASE(entry, SharedRuntime::dlog); | |
281 FUNCTION_CASE(entry, SharedRuntime::dlog10); | |
282 FUNCTION_CASE(entry, SharedRuntime::dpow); | |
283 FUNCTION_CASE(entry, SharedRuntime::drem); | |
284 FUNCTION_CASE(entry, SharedRuntime::dsin); | |
285 FUNCTION_CASE(entry, SharedRuntime::dtan); | |
286 FUNCTION_CASE(entry, SharedRuntime::f2i); | |
287 FUNCTION_CASE(entry, SharedRuntime::f2l); | |
288 FUNCTION_CASE(entry, SharedRuntime::frem); | |
289 FUNCTION_CASE(entry, SharedRuntime::l2d); | |
290 FUNCTION_CASE(entry, SharedRuntime::l2f); | |
291 FUNCTION_CASE(entry, SharedRuntime::ldiv); | |
292 FUNCTION_CASE(entry, SharedRuntime::lmul); | |
293 FUNCTION_CASE(entry, SharedRuntime::lrem); | |
294 FUNCTION_CASE(entry, SharedRuntime::lrem); | |
295 FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry); | |
296 FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit); | |
6135 | 297 FUNCTION_CASE(entry, is_instance_of); |
0 | 298 FUNCTION_CASE(entry, trace_block_entry); |
6006
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4872
diff
changeset
|
299 #ifdef TRACE_HAVE_INTRINSICS |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4872
diff
changeset
|
300 FUNCTION_CASE(entry, TRACE_TIME_METHOD); |
0105f367a14c
7160570: Intrinsification support for tracing framework
rbackman
parents:
4872
diff
changeset
|
301 #endif |
0 | 302 |
303 #undef FUNCTION_CASE | |
304 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
305 // Soft float adds more runtime names. |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
306 return pd_name_for_address(entry); |
0 | 307 } |
308 | |
309 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
310 JRT_ENTRY(void, Runtime1::new_instance(JavaThread* thread, Klass* klass)) |
0 | 311 NOT_PRODUCT(_new_instance_slowcase_cnt++;) |
312 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
313 assert(klass->is_klass(), "not a class"); |
0 | 314 instanceKlassHandle h(thread, klass); |
315 h->check_valid_for_instantiation(true, CHECK); | |
316 // make sure klass is initialized | |
317 h->initialize(CHECK); | |
318 // allocate instance and return via TLS | |
319 oop obj = h->allocate_instance(CHECK); | |
320 thread->set_vm_result(obj); | |
321 JRT_END | |
322 | |
323 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
324 JRT_ENTRY(void, Runtime1::new_type_array(JavaThread* thread, Klass* klass, jint length)) |
0 | 325 NOT_PRODUCT(_new_type_array_slowcase_cnt++;) |
326 // Note: no handle for klass needed since they are not used | |
327 // anymore after new_typeArray() and no GC can happen before. | |
328 // (This may have to change if this code changes!) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
329 assert(klass->is_klass(), "not a class"); |
0 | 330 BasicType elt_type = typeArrayKlass::cast(klass)->element_type(); |
331 oop obj = oopFactory::new_typeArray(elt_type, length, CHECK); | |
332 thread->set_vm_result(obj); | |
333 // This is pretty rare but this runtime patch is stressful to deoptimization | |
334 // if we deoptimize here so force a deopt to stress the path. | |
335 if (DeoptimizeALot) { | |
336 deopt_caller(); | |
337 } | |
338 | |
339 JRT_END | |
340 | |
341 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
342 JRT_ENTRY(void, Runtime1::new_object_array(JavaThread* thread, Klass* array_klass, jint length)) |
0 | 343 NOT_PRODUCT(_new_object_array_slowcase_cnt++;) |
344 | |
345 // Note: no handle for klass needed since they are not used | |
346 // anymore after new_objArray() and no GC can happen before. | |
347 // (This may have to change if this code changes!) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
348 assert(array_klass->is_klass(), "not a class"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
349 Klass* elem_klass = objArrayKlass::cast(array_klass)->element_klass(); |
0 | 350 objArrayOop obj = oopFactory::new_objArray(elem_klass, length, CHECK); |
351 thread->set_vm_result(obj); | |
352 // This is pretty rare but this runtime patch is stressful to deoptimization | |
353 // if we deoptimize here so force a deopt to stress the path. | |
354 if (DeoptimizeALot) { | |
355 deopt_caller(); | |
356 } | |
357 JRT_END | |
358 | |
359 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
360 JRT_ENTRY(void, Runtime1::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims)) |
0 | 361 NOT_PRODUCT(_new_multi_array_slowcase_cnt++;) |
362 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
363 assert(klass->is_klass(), "not a class"); |
0 | 364 assert(rank >= 1, "rank must be nonzero"); |
365 oop obj = arrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK); | |
366 thread->set_vm_result(obj); | |
367 JRT_END | |
368 | |
369 | |
370 JRT_ENTRY(void, Runtime1::unimplemented_entry(JavaThread* thread, StubID id)) | |
371 tty->print_cr("Runtime1::entry_for(%d) returned unimplemented entry point", id); | |
372 JRT_END | |
373 | |
374 | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2142
diff
changeset
|
375 JRT_ENTRY(void, Runtime1::throw_array_store_exception(JavaThread* thread, oopDesc* obj)) |
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2142
diff
changeset
|
376 ResourceMark rm(thread); |
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2142
diff
changeset
|
377 const char* klass_name = Klass::cast(obj->klass())->external_name(); |
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2142
diff
changeset
|
378 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayStoreException(), klass_name); |
0 | 379 JRT_END |
380 | |
381 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3269
diff
changeset
|
382 // counter_overflow() is called from within C1-compiled methods. The enclosing method is the method |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3269
diff
changeset
|
383 // associated with the top activation record. The inlinee (that is possibly included in the enclosing |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3269
diff
changeset
|
384 // method) method oop is passed as an argument. In order to do that it is embedded in the code as |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3269
diff
changeset
|
385 // a constant. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
386 static nmethod* counter_overflow_helper(JavaThread* THREAD, int branch_bci, Method* m) { |
1783 | 387 nmethod* osr_nm = NULL; |
388 methodHandle method(THREAD, m); | |
389 | |
390 RegisterMap map(THREAD, false); | |
391 frame fr = THREAD->last_frame().sender(&map); | |
0 | 392 nmethod* nm = (nmethod*) fr.cb(); |
1783 | 393 assert(nm!= NULL && nm->is_nmethod(), "Sanity check"); |
394 methodHandle enclosing_method(THREAD, nm->method()); | |
395 | |
396 CompLevel level = (CompLevel)nm->comp_level(); | |
397 int bci = InvocationEntryBci; | |
398 if (branch_bci != InvocationEntryBci) { | |
399 // Compute desination bci | |
400 address pc = method()->code_base() + branch_bci; | |
2142 | 401 Bytecodes::Code branch = Bytecodes::code_at(method(), pc); |
1783 | 402 int offset = 0; |
403 switch (branch) { | |
404 case Bytecodes::_if_icmplt: case Bytecodes::_iflt: | |
405 case Bytecodes::_if_icmpgt: case Bytecodes::_ifgt: | |
406 case Bytecodes::_if_icmple: case Bytecodes::_ifle: | |
407 case Bytecodes::_if_icmpge: case Bytecodes::_ifge: | |
408 case Bytecodes::_if_icmpeq: case Bytecodes::_if_acmpeq: case Bytecodes::_ifeq: | |
409 case Bytecodes::_if_icmpne: case Bytecodes::_if_acmpne: case Bytecodes::_ifne: | |
410 case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: case Bytecodes::_goto: | |
411 offset = (int16_t)Bytes::get_Java_u2(pc + 1); | |
412 break; | |
413 case Bytecodes::_goto_w: | |
414 offset = Bytes::get_Java_u4(pc + 1); | |
415 break; | |
416 default: ; | |
0 | 417 } |
1783 | 418 bci = branch_bci + offset; |
419 } | |
4825
20334ed5ed3c
7131259: compile_method and CompilationPolicy::event shouldn't be declared TRAPS
iveresov
parents:
4048
diff
changeset
|
420 assert(!HAS_PENDING_EXCEPTION, "Should not have any exceptions pending"); |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3269
diff
changeset
|
421 osr_nm = CompilationPolicy::policy()->event(enclosing_method, method, branch_bci, bci, level, nm, THREAD); |
4825
20334ed5ed3c
7131259: compile_method and CompilationPolicy::event shouldn't be declared TRAPS
iveresov
parents:
4048
diff
changeset
|
422 assert(!HAS_PENDING_EXCEPTION, "Event handler should not throw any exceptions"); |
1783 | 423 return osr_nm; |
424 } | |
425 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
426 JRT_BLOCK_ENTRY(address, Runtime1::counter_overflow(JavaThread* thread, int bci, Method* method)) |
1783 | 427 nmethod* osr_nm; |
428 JRT_BLOCK | |
429 osr_nm = counter_overflow_helper(thread, bci, method); | |
430 if (osr_nm != NULL) { | |
431 RegisterMap map(thread, false); | |
432 frame fr = thread->last_frame().sender(&map); | |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1783
diff
changeset
|
433 Deoptimization::deoptimize_frame(thread, fr.id()); |
0 | 434 } |
1783 | 435 JRT_BLOCK_END |
436 return NULL; | |
0 | 437 JRT_END |
438 | |
439 extern void vm_exit(int code); | |
440 | |
441 // Enter this method from compiled code handler below. This is where we transition | |
442 // to VM mode. This is done as a helper routine so that the method called directly | |
443 // from compiled code does not have to transition to VM. This allows the entry | |
444 // method to see if the nmethod that we have just looked up a handler for has | |
445 // been deoptimized while we were in the vm. This simplifies the assembly code | |
446 // cpu directories. | |
447 // | |
448 // We are entering here from exception stub (via the entry method below) | |
449 // If there is a compiled exception handler in this method, we will continue there; | |
450 // otherwise we will unwind the stack and continue at the caller of top frame method | |
451 // Note: we enter in Java using a special JRT wrapper. This wrapper allows us to | |
452 // control the area where we can allow a safepoint. After we exit the safepoint area we can | |
453 // check to see if the handler we are going to return is now in a nmethod that has | |
454 // been deoptimized. If that is the case we return the deopt blob | |
455 // unpack_with_exception entry instead. This makes life for the exception blob easier | |
456 // because making that same check and diverting is painful from assembly language. | |
457 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
458 // Reset method handle flag. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
459 thread->set_is_method_handle_return(false); |
0 | 460 |
461 Handle exception(thread, ex); | |
462 nm = CodeCache::find_nmethod(pc); | |
463 assert(nm != NULL, "this is not an nmethod"); | |
464 // Adjust the pc as needed/ | |
465 if (nm->is_deopt_pc(pc)) { | |
466 RegisterMap map(thread, false); | |
467 frame exception_frame = thread->last_frame().sender(&map); | |
468 // if the frame isn't deopted then pc must not correspond to the caller of last_frame | |
469 assert(exception_frame.is_deoptimized_frame(), "must be deopted"); | |
470 pc = exception_frame.pc(); | |
471 } | |
472 #ifdef ASSERT | |
473 assert(exception.not_null(), "NULL exceptions should be handled by throw_exception"); | |
474 assert(exception->is_oop(), "just checking"); | |
475 // Check that exception is a subclass of Throwable, otherwise we have a VerifyError | |
1142 | 476 if (!(exception->is_a(SystemDictionary::Throwable_klass()))) { |
0 | 477 if (ExitVMOnVerifyError) vm_exit(-1); |
478 ShouldNotReachHere(); | |
479 } | |
480 #endif | |
481 | |
482 // Check the stack guard pages and reenable them if necessary and there is | |
483 // enough space on the stack to do so. Use fast exceptions only if the guard | |
484 // pages are enabled. | |
485 bool guard_pages_enabled = thread->stack_yellow_zone_enabled(); | |
486 if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack(); | |
487 | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
488 if (JvmtiExport::can_post_on_exceptions()) { |
0 | 489 // To ensure correct notification of exception catches and throws |
490 // we have to deoptimize here. If we attempted to notify the | |
491 // catches and throws during this exception lookup it's possible | |
492 // we could deoptimize on the way out of the VM and end back in | |
493 // the interpreter at the throw site. This would result in double | |
494 // notifications since the interpreter would also notify about | |
495 // these same catches and throws as it unwound the frame. | |
496 | |
497 RegisterMap reg_map(thread); | |
498 frame stub_frame = thread->last_frame(); | |
499 frame caller_frame = stub_frame.sender(®_map); | |
500 | |
501 // We don't really want to deoptimize the nmethod itself since we | |
502 // can actually continue in the exception handler ourselves but I | |
503 // don't see an easy way to have the desired effect. | |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1783
diff
changeset
|
504 Deoptimization::deoptimize_frame(thread, caller_frame.id()); |
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1783
diff
changeset
|
505 assert(caller_is_deopted(), "Must be deoptimized"); |
0 | 506 |
507 return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); | |
508 } | |
509 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
510 // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions |
0 | 511 if (guard_pages_enabled) { |
512 address fast_continuation = nm->handler_for_exception_and_pc(exception, pc); | |
513 if (fast_continuation != NULL) { | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
514 // Set flag if return address is a method handle call site. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
515 thread->set_is_method_handle_return(nm->is_method_handle_return(pc)); |
0 | 516 return fast_continuation; |
517 } | |
518 } | |
519 | |
520 // If the stack guard pages are enabled, check whether there is a handler in | |
521 // the current method. Otherwise (guard pages disabled), force an unwind and | |
522 // skip the exception cache update (i.e., just leave continuation==NULL). | |
523 address continuation = NULL; | |
524 if (guard_pages_enabled) { | |
525 | |
526 // New exception handling mechanism can support inlined methods | |
527 // with exception handlers since the mappings are from PC to PC | |
528 | |
529 // debugging support | |
530 // tracing | |
531 if (TraceExceptions) { | |
532 ttyLocker ttyl; | |
533 ResourceMark rm; | |
534 tty->print_cr("Exception <%s> (0x%x) thrown in compiled method <%s> at PC " PTR_FORMAT " for thread 0x%x", | |
535 exception->print_value_string(), (address)exception(), nm->method()->print_value_string(), pc, thread); | |
536 } | |
537 // for AbortVMOnException flag | |
538 NOT_PRODUCT(Exceptions::debug_check_abort(exception)); | |
539 | |
540 // Clear out the exception oop and pc since looking up an | |
541 // exception handler can cause class loading, which might throw an | |
542 // exception and those fields are expected to be clear during | |
543 // normal bytecode execution. | |
544 thread->set_exception_oop(NULL); | |
545 thread->set_exception_pc(NULL); | |
546 | |
547 continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false); | |
548 // If an exception was thrown during exception dispatch, the exception oop may have changed | |
549 thread->set_exception_oop(exception()); | |
550 thread->set_exception_pc(pc); | |
551 | |
552 // the exception cache is used only by non-implicit exceptions | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
553 if (continuation != NULL) { |
0 | 554 nm->add_handler_for_exception_and_pc(exception, pc, continuation); |
555 } | |
556 } | |
557 | |
558 thread->set_vm_result(exception()); | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
559 // Set flag if return address is a method handle call site. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
560 thread->set_is_method_handle_return(nm->is_method_handle_return(pc)); |
0 | 561 |
562 if (TraceExceptions) { | |
563 ttyLocker ttyl; | |
564 ResourceMark rm; | |
565 tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, | |
566 thread, continuation, pc); | |
567 } | |
568 | |
569 return continuation; | |
570 JRT_END | |
571 | |
572 // Enter this method from compiled code only if there is a Java exception handler | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
573 // in the method handling the exception. |
0 | 574 // We are entering here from exception stub. We don't do a normal VM transition here. |
575 // We do it in a helper. This is so we can check to see if the nmethod we have just | |
576 // searched for an exception handler has been deoptimized in the meantime. | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
577 address Runtime1::exception_handler_for_pc(JavaThread* thread) { |
0 | 578 oop exception = thread->exception_oop(); |
579 address pc = thread->exception_pc(); | |
580 // Still in Java mode | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
581 DEBUG_ONLY(ResetNoHandleMark rnhm); |
0 | 582 nmethod* nm = NULL; |
583 address continuation = NULL; | |
584 { | |
585 // Enter VM mode by calling the helper | |
586 ResetNoHandleMark rnhm; | |
587 continuation = exception_handler_for_pc_helper(thread, exception, pc, nm); | |
588 } | |
589 // Back in JAVA, use no oops DON'T safepoint | |
590 | |
591 // Now check to see if the nmethod we were called from is now deoptimized. | |
592 // If so we must return to the deopt blob and deoptimize the nmethod | |
593 if (nm != NULL && caller_is_deopted()) { | |
594 continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); | |
595 } | |
596 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
597 assert(continuation != NULL, "no handler found"); |
0 | 598 return continuation; |
599 } | |
600 | |
601 | |
602 JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index)) | |
603 NOT_PRODUCT(_throw_range_check_exception_count++;) | |
604 char message[jintAsStringSize]; | |
605 sprintf(message, "%d", index); | |
606 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), message); | |
607 JRT_END | |
608 | |
609 | |
610 JRT_ENTRY(void, Runtime1::throw_index_exception(JavaThread* thread, int index)) | |
611 NOT_PRODUCT(_throw_index_exception_count++;) | |
612 char message[16]; | |
613 sprintf(message, "%d", index); | |
614 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IndexOutOfBoundsException(), message); | |
615 JRT_END | |
616 | |
617 | |
618 JRT_ENTRY(void, Runtime1::throw_div0_exception(JavaThread* thread)) | |
619 NOT_PRODUCT(_throw_div0_exception_count++;) | |
620 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero"); | |
621 JRT_END | |
622 | |
623 | |
624 JRT_ENTRY(void, Runtime1::throw_null_pointer_exception(JavaThread* thread)) | |
625 NOT_PRODUCT(_throw_null_pointer_exception_count++;) | |
626 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException()); | |
627 JRT_END | |
628 | |
629 | |
630 JRT_ENTRY(void, Runtime1::throw_class_cast_exception(JavaThread* thread, oopDesc* object)) | |
631 NOT_PRODUCT(_throw_class_cast_exception_count++;) | |
632 ResourceMark rm(thread); | |
633 char* message = SharedRuntime::generate_class_cast_message( | |
634 thread, Klass::cast(object->klass())->external_name()); | |
635 SharedRuntime::throw_and_post_jvmti_exception( | |
636 thread, vmSymbols::java_lang_ClassCastException(), message); | |
637 JRT_END | |
638 | |
639 | |
640 JRT_ENTRY(void, Runtime1::throw_incompatible_class_change_error(JavaThread* thread)) | |
641 NOT_PRODUCT(_throw_incompatible_class_change_error_count++;) | |
642 ResourceMark rm(thread); | |
643 SharedRuntime::throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError()); | |
644 JRT_END | |
645 | |
646 | |
647 JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) | |
648 NOT_PRODUCT(_monitorenter_slowcase_cnt++;) | |
649 if (PrintBiasedLockingStatistics) { | |
650 Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); | |
651 } | |
652 Handle h_obj(thread, obj); | |
653 assert(h_obj()->is_oop(), "must be NULL or an object"); | |
654 if (UseBiasedLocking) { | |
655 // Retry fast entry if bias is revoked to avoid unnecessary inflation | |
656 ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK); | |
657 } else { | |
658 if (UseFastLocking) { | |
659 // When using fast locking, the compiled code has already tried the fast case | |
660 assert(obj == lock->obj(), "must match"); | |
661 ObjectSynchronizer::slow_enter(h_obj, lock->lock(), THREAD); | |
662 } else { | |
663 lock->set_obj(obj); | |
664 ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD); | |
665 } | |
666 } | |
667 JRT_END | |
668 | |
669 | |
670 JRT_LEAF(void, Runtime1::monitorexit(JavaThread* thread, BasicObjectLock* lock)) | |
671 NOT_PRODUCT(_monitorexit_slowcase_cnt++;) | |
672 assert(thread == JavaThread::current(), "threads must correspond"); | |
673 assert(thread->last_Java_sp(), "last_Java_sp must be set"); | |
674 // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown | |
675 EXCEPTION_MARK; | |
676 | |
677 oop obj = lock->obj(); | |
678 assert(obj->is_oop(), "must be NULL or an object"); | |
679 if (UseFastLocking) { | |
680 // When using fast locking, the compiled code has already tried the fast case | |
681 ObjectSynchronizer::slow_exit(obj, lock->lock(), THREAD); | |
682 } else { | |
683 ObjectSynchronizer::fast_exit(obj, lock->lock(), THREAD); | |
684 } | |
685 JRT_END | |
686 | |
4048
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
687 // Cf. OptoRuntime::deoptimize_caller_frame |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
688 JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread)) |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
689 // Called from within the owner thread, so no need for safepoint |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
690 RegisterMap reg_map(thread, false); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
691 frame stub_frame = thread->last_frame(); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
692 assert(stub_frame.is_runtime_frame(), "sanity check"); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
693 frame caller_frame = stub_frame.sender(®_map); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
694 |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
695 // We are coming from a compiled method; check this is true. |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
696 assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity"); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
697 |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
698 // Deoptimize the caller frame. |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
699 Deoptimization::deoptimize_frame(thread, caller_frame.id()); |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
700 |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
701 // Return to the now deoptimized frame. |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
702 JRT_END |
cec1757a0134
7102657: JSR 292: C1 deoptimizes unlinked invokedynamic call sites infinitely
twisti
parents:
3899
diff
changeset
|
703 |
0 | 704 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
705 static Klass* resolve_field_return_klass(methodHandle caller, int bci, TRAPS) { |
2142 | 706 Bytecode_field field_access(caller, bci); |
0 | 707 // This can be static or non-static field access |
2142 | 708 Bytecodes::Code code = field_access.code(); |
0 | 709 |
710 // We must load class, initialize class and resolvethe field | |
711 FieldAccessInfo result; // initialize class if needed | |
712 constantPoolHandle constants(THREAD, caller->constants()); | |
2142 | 713 LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK_NULL); |
0 | 714 return result.klass()(); |
715 } | |
716 | |
717 | |
718 // | |
719 // This routine patches sites where a class wasn't loaded or | |
720 // initialized at the time the code was generated. It handles | |
721 // references to classes, fields and forcing of initialization. Most | |
722 // of the cases are straightforward and involving simply forcing | |
723 // resolution of a class, rewriting the instruction stream with the | |
724 // needed constant and replacing the call in this function with the | |
725 // patched code. The case for static field is more complicated since | |
726 // the thread which is in the process of initializing a class can | |
727 // access it's static fields but other threads can't so the code | |
728 // either has to deoptimize when this case is detected or execute a | |
729 // check that the current thread is the initializing thread. The | |
730 // current | |
731 // | |
732 // Patches basically look like this: | |
733 // | |
734 // | |
735 // patch_site: jmp patch stub ;; will be patched | |
736 // continue: ... | |
737 // ... | |
738 // ... | |
739 // ... | |
740 // | |
741 // They have a stub which looks like this: | |
742 // | |
743 // ;; patch body | |
744 // movl <const>, reg (for class constants) | |
745 // <or> movl [reg1 + <const>], reg (for field offsets) | |
746 // <or> movl reg, [reg1 + <const>] (for field offsets) | |
747 // <being_init offset> <bytes to copy> <bytes to skip> | |
748 // patch_stub: call Runtime1::patch_code (through a runtime stub) | |
749 // jmp patch_site | |
750 // | |
751 // | |
752 // A normal patch is done by rewriting the patch body, usually a move, | |
753 // and then copying it into place over top of the jmp instruction | |
754 // being careful to flush caches and doing it in an MP-safe way. The | |
755 // constants following the patch body are used to find various pieces | |
756 // of the patch relative to the call site for Runtime1::patch_code. | |
757 // The case for getstatic and putstatic is more complicated because | |
758 // getstatic and putstatic have special semantics when executing while | |
759 // the class is being initialized. getstatic/putstatic on a class | |
760 // which is being_initialized may be executed by the initializing | |
761 // thread but other threads have to block when they execute it. This | |
762 // is accomplished in compiled code by executing a test of the current | |
763 // thread against the initializing thread of the class. It's emitted | |
764 // as boilerplate in their stub which allows the patched code to be | |
765 // executed before it's copied back into the main body of the nmethod. | |
766 // | |
767 // being_init: get_thread(<tmp reg> | |
768 // cmpl [reg1 + <init_thread_offset>], <tmp reg> | |
769 // jne patch_stub | |
770 // movl [reg1 + <const>], reg (for field offsets) <or> | |
771 // movl reg, [reg1 + <const>] (for field offsets) | |
772 // jmp continue | |
773 // <being_init offset> <bytes to copy> <bytes to skip> | |
774 // patch_stub: jmp Runtim1::patch_code (through a runtime stub) | |
775 // jmp patch_site | |
776 // | |
777 // If the class is being initialized the patch body is rewritten and | |
778 // the patch site is rewritten to jump to being_init, instead of | |
779 // patch_stub. Whenever this code is executed it checks the current | |
780 // thread against the intializing thread so other threads will enter | |
781 // the runtime and end up blocked waiting the class to finish | |
782 // initializing inside the calls to resolve_field below. The | |
783 // initializing class will continue on it's way. Once the class is | |
784 // fully_initialized, the intializing_thread of the class becomes | |
785 // NULL, so the next thread to execute this code will fail the test, | |
786 // call into patch_code and complete the patching process by copying | |
787 // the patch body back into the main part of the nmethod and resume | |
788 // executing. | |
789 // | |
790 // | |
791 | |
792 JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_id )) | |
793 NOT_PRODUCT(_patch_code_slowcase_cnt++;) | |
794 | |
795 ResourceMark rm(thread); | |
796 RegisterMap reg_map(thread, false); | |
797 frame runtime_frame = thread->last_frame(); | |
798 frame caller_frame = runtime_frame.sender(®_map); | |
799 | |
800 // last java frame on stack | |
801 vframeStream vfst(thread, true); | |
802 assert(!vfst.at_end(), "Java frame must exist"); | |
803 | |
804 methodHandle caller_method(THREAD, vfst.method()); | |
805 // Note that caller_method->code() may not be same as caller_code because of OSR's | |
806 // Note also that in the presence of inlining it is not guaranteed | |
807 // that caller_method() == caller_code->method() | |
808 | |
809 int bci = vfst.bci(); | |
2142 | 810 Bytecodes::Code code = caller_method()->java_code_at(bci); |
0 | 811 |
812 #ifndef PRODUCT | |
813 // this is used by assertions in the access_field_patching_id | |
814 BasicType patch_field_type = T_ILLEGAL; | |
815 #endif // PRODUCT | |
816 bool deoptimize_for_volatile = false; | |
817 int patch_field_offset = -1; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
818 KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
819 KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
820 Handle mirror(THREAD, NULL); // oop needed by load_mirror_patching code |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
821 bool load_klass_or_mirror_patch_id = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
822 (stub_id == Runtime1::load_klass_patching_id || stub_id == Runtime1::load_mirror_patching_id); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
823 |
0 | 824 if (stub_id == Runtime1::access_field_patching_id) { |
825 | |
2142 | 826 Bytecode_field field_access(caller_method, bci); |
0 | 827 FieldAccessInfo result; // initialize class if needed |
2142 | 828 Bytecodes::Code code = field_access.code(); |
0 | 829 constantPoolHandle constants(THREAD, caller_method->constants()); |
2142 | 830 LinkResolver::resolve_field(result, constants, field_access.index(), Bytecodes::java_code(code), false, CHECK); |
0 | 831 patch_field_offset = result.field_offset(); |
832 | |
833 // If we're patching a field which is volatile then at compile it | |
834 // must not have been know to be volatile, so the generated code | |
835 // isn't correct for a volatile reference. The nmethod has to be | |
836 // deoptimized so that the code can be regenerated correctly. | |
837 // This check is only needed for access_field_patching since this | |
838 // is the path for patching field offsets. load_klass is only | |
839 // used for patching references to oops which don't need special | |
840 // handling in the volatile case. | |
841 deoptimize_for_volatile = result.access_flags().is_volatile(); | |
842 | |
843 #ifndef PRODUCT | |
844 patch_field_type = result.field_type(); | |
845 #endif | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
846 } else if (load_klass_or_mirror_patch_id) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
847 Klass* k = NULL; |
0 | 848 switch (code) { |
849 case Bytecodes::_putstatic: | |
850 case Bytecodes::_getstatic: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
851 { Klass* klass = resolve_field_return_klass(caller_method, bci, CHECK); |
0 | 852 init_klass = KlassHandle(THREAD, klass); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
853 mirror = Handle(THREAD, klass->java_mirror()); |
0 | 854 } |
855 break; | |
856 case Bytecodes::_new: | |
2142 | 857 { Bytecode_new bnew(caller_method(), caller_method->bcp_from(bci)); |
858 k = caller_method->constants()->klass_at(bnew.index(), CHECK); | |
0 | 859 } |
860 break; | |
861 case Bytecodes::_multianewarray: | |
2142 | 862 { Bytecode_multianewarray mna(caller_method(), caller_method->bcp_from(bci)); |
863 k = caller_method->constants()->klass_at(mna.index(), CHECK); | |
0 | 864 } |
865 break; | |
866 case Bytecodes::_instanceof: | |
2142 | 867 { Bytecode_instanceof io(caller_method(), caller_method->bcp_from(bci)); |
868 k = caller_method->constants()->klass_at(io.index(), CHECK); | |
0 | 869 } |
870 break; | |
871 case Bytecodes::_checkcast: | |
2142 | 872 { Bytecode_checkcast cc(caller_method(), caller_method->bcp_from(bci)); |
873 k = caller_method->constants()->klass_at(cc.index(), CHECK); | |
0 | 874 } |
875 break; | |
876 case Bytecodes::_anewarray: | |
2142 | 877 { Bytecode_anewarray anew(caller_method(), caller_method->bcp_from(bci)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
878 Klass* ek = caller_method->constants()->klass_at(anew.index(), CHECK); |
0 | 879 k = Klass::cast(ek)->array_klass(CHECK); |
880 } | |
881 break; | |
882 case Bytecodes::_ldc: | |
883 case Bytecodes::_ldc_w: | |
884 { | |
2142 | 885 Bytecode_loadconstant cc(caller_method, bci); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
886 oop m = cc.resolve_constant(CHECK); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
887 mirror = Handle(THREAD, m); |
0 | 888 } |
889 break; | |
890 default: Unimplemented(); | |
891 } | |
892 // convert to handle | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
893 load_klass = KlassHandle(THREAD, k); |
0 | 894 } else { |
895 ShouldNotReachHere(); | |
896 } | |
897 | |
898 if (deoptimize_for_volatile) { | |
899 // At compile time we assumed the field wasn't volatile but after | |
900 // loading it turns out it was volatile so we have to throw the | |
901 // compiled code out and let it be regenerated. | |
902 if (TracePatching) { | |
903 tty->print_cr("Deoptimizing for patching volatile field reference"); | |
904 } | |
485
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
905 // It's possible the nmethod was invalidated in the last |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
906 // safepoint, but if it's still alive then make it not_entrant. |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
907 nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
908 if (nm != NULL) { |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
909 nm->make_not_entrant(); |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
910 } |
ac8fe14c93e4
6767587: missing call to make_not_entrant after deoptimizing for patching volatiles
never
parents:
362
diff
changeset
|
911 |
1905
ce6848d0666d
6968367: can_post_on_exceptions is still using VM_DeoptimizeFrame in some places
never
parents:
1783
diff
changeset
|
912 Deoptimization::deoptimize_frame(thread, caller_frame.id()); |
0 | 913 |
914 // Return to the now deoptimized frame. | |
915 } | |
916 | |
1602 | 917 // If we are patching in a non-perm oop, make sure the nmethod |
918 // is on the right list. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
919 if (ScavengeRootsInCode && mirror.not_null() && mirror()->is_scavengable()) { |
1602 | 920 MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag); |
921 nmethod* nm = CodeCache::find_nmethod(caller_frame.pc()); | |
922 guarantee(nm != NULL, "only nmethods can contain non-perm oops"); | |
923 if (!nm->on_scavenge_root_list()) | |
924 CodeCache::add_scavenge_root_nmethod(nm); | |
925 } | |
0 | 926 |
927 // Now copy code back | |
928 | |
929 { | |
930 MutexLockerEx ml_patch (Patching_lock, Mutex::_no_safepoint_check_flag); | |
931 // | |
932 // Deoptimization may have happened while we waited for the lock. | |
933 // In that case we don't bother to do any patching we just return | |
934 // and let the deopt happen | |
935 if (!caller_is_deopted()) { | |
936 NativeGeneralJump* jump = nativeGeneralJump_at(caller_frame.pc()); | |
937 address instr_pc = jump->jump_destination(); | |
938 NativeInstruction* ni = nativeInstruction_at(instr_pc); | |
939 if (ni->is_jump() ) { | |
940 // the jump has not been patched yet | |
941 // The jump destination is slow case and therefore not part of the stubs | |
942 // (stubs are only for StaticCalls) | |
943 | |
944 // format of buffer | |
945 // .... | |
946 // instr byte 0 <-- copy_buff | |
947 // instr byte 1 | |
948 // .. | |
949 // instr byte n-1 | |
950 // n | |
951 // .... <-- call destination | |
952 | |
953 address stub_location = caller_frame.pc() + PatchingStub::patch_info_offset(); | |
954 unsigned char* byte_count = (unsigned char*) (stub_location - 1); | |
955 unsigned char* byte_skip = (unsigned char*) (stub_location - 2); | |
956 unsigned char* being_initialized_entry_offset = (unsigned char*) (stub_location - 3); | |
957 address copy_buff = stub_location - *byte_skip - *byte_count; | |
958 address being_initialized_entry = stub_location - *being_initialized_entry_offset; | |
959 if (TracePatching) { | |
960 tty->print_cr(" Patching %s at bci %d at address 0x%x (%s)", Bytecodes::name(code), bci, | |
961 instr_pc, (stub_id == Runtime1::access_field_patching_id) ? "field" : "klass"); | |
962 nmethod* caller_code = CodeCache::find_nmethod(caller_frame.pc()); | |
963 assert(caller_code != NULL, "nmethod not found"); | |
964 | |
965 // NOTE we use pc() not original_pc() because we already know they are | |
966 // identical otherwise we'd have never entered this block of code | |
967 | |
968 OopMap* map = caller_code->oop_map_for_return_address(caller_frame.pc()); | |
969 assert(map != NULL, "null check"); | |
970 map->print(); | |
971 tty->cr(); | |
972 | |
973 Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); | |
974 } | |
975 // depending on the code below, do_patch says whether to copy the patch body back into the nmethod | |
976 bool do_patch = true; | |
977 if (stub_id == Runtime1::access_field_patching_id) { | |
978 // The offset may not be correct if the class was not loaded at code generation time. | |
979 // Set it now. | |
980 NativeMovRegMem* n_move = nativeMovRegMem_at(copy_buff); | |
981 assert(n_move->offset() == 0 || (n_move->offset() == 4 && (patch_field_type == T_DOUBLE || patch_field_type == T_LONG)), "illegal offset for type"); | |
982 assert(patch_field_offset >= 0, "illegal offset"); | |
983 n_move->add_offset_in_bytes(patch_field_offset); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
984 } else if (load_klass_or_mirror_patch_id) { |
0 | 985 // If a getstatic or putstatic is referencing a klass which |
986 // isn't fully initialized, the patch body isn't copied into | |
987 // place until initialization is complete. In this case the | |
988 // patch site is setup so that any threads besides the | |
989 // initializing thread are forced to come into the VM and | |
990 // block. | |
991 do_patch = (code != Bytecodes::_getstatic && code != Bytecodes::_putstatic) || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
992 InstanceKlass::cast(init_klass())->is_initialized(); |
0 | 993 NativeGeneralJump* jump = nativeGeneralJump_at(instr_pc); |
994 if (jump->jump_destination() == being_initialized_entry) { | |
995 assert(do_patch == true, "initialization must be complete at this point"); | |
996 } else { | |
997 // patch the instruction <move reg, klass> | |
998 NativeMovConstReg* n_copy = nativeMovConstReg_at(copy_buff); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
999 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1000 assert(n_copy->data() == 0 || |
1783 | 1001 n_copy->data() == (intptr_t)Universe::non_oop_word(), |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1002 "illegal init value"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1003 if (stub_id == Runtime1::load_klass_patching_id) { |
0 | 1004 assert(load_klass() != NULL, "klass not set"); |
1005 n_copy->set_data((intx) (load_klass())); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1006 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1007 assert(mirror() != NULL, "klass not set"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1008 n_copy->set_data((intx) (mirror())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1009 } |
0 | 1010 |
1011 if (TracePatching) { | |
1012 Disassembler::decode(copy_buff, copy_buff + *byte_count, tty); | |
1013 } | |
1014 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1015 #if defined(SPARC) || defined(PPC) |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1016 // Update the location in the nmethod with the proper |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1017 // metadata. When the code was generated, a NULL was stuffed |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1018 // in the metadata table and that table needs to be update to |
0 | 1019 // have the right value. On intel the value is kept |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1020 // directly in the instruction instead of in the metadata |
0 | 1021 // table, so set_data above effectively updated the value. |
1022 nmethod* nm = CodeCache::find_nmethod(instr_pc); | |
1023 assert(nm != NULL, "invalid nmethod_pc"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1024 RelocIterator mds(nm, copy_buff, copy_buff + 1); |
0 | 1025 bool found = false; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1026 while (mds.next() && !found) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1027 if (mds.type() == relocInfo::oop_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1028 assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1029 oop_Relocation* r = mds.oop_reloc(); |
0 | 1030 oop* oop_adr = r->oop_addr(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1031 *oop_adr = mirror(); |
0 | 1032 r->fix_oop_relocation(); |
1033 found = true; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1034 } else if (mds.type() == relocInfo::metadata_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1035 assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1036 metadata_Relocation* r = mds.metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1037 Metadata** metadata_adr = r->metadata_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1038 *metadata_adr = load_klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1039 r->fix_metadata_relocation(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1040 found = true; |
0 | 1041 } |
1042 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1043 assert(found, "the metadata must exist!"); |
0 | 1044 #endif |
1045 | |
1046 } | |
1047 } else { | |
1048 ShouldNotReachHere(); | |
1049 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1050 |
0 | 1051 if (do_patch) { |
1052 // replace instructions | |
1053 // first replace the tail, then the call | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1054 #ifdef ARM |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1055 if(load_klass_or_mirror_patch_id && !VM_Version::supports_movw()) { |
3269
7ec4bb02d5f0
7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match
vladidan
parents:
2446
diff
changeset
|
1056 nmethod* nm = CodeCache::find_nmethod(instr_pc); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1057 address addr = NULL; |
3269
7ec4bb02d5f0
7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match
vladidan
parents:
2446
diff
changeset
|
1058 assert(nm != NULL, "invalid nmethod_pc"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1059 RelocIterator mds(nm, copy_buff, copy_buff + 1); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1060 while (mds.next()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1061 if (mds.type() == relocInfo::oop_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1062 assert(stub_id == Runtime1::load_mirror_patching_id, "wrong stub id"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1063 oop_Relocation* r = mds.oop_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1064 addr = (address)r->oop_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1065 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1066 } else if (mds.type() == relocInfo::metadata_type) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1067 assert(stub_id == Runtime1::load_klass_patching_id, "wrong stub id"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1068 metadata_Relocation* r = mds.metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1069 addr = (address)r->metadata_addr(); |
3269
7ec4bb02d5f0
7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match
vladidan
parents:
2446
diff
changeset
|
1070 break; |
7ec4bb02d5f0
7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match
vladidan
parents:
2446
diff
changeset
|
1071 } |
7ec4bb02d5f0
7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match
vladidan
parents:
2446
diff
changeset
|
1072 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1073 assert(addr != NULL, "metadata relocation must exist"); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1074 copy_buff -= *byte_count; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1075 NativeMovConstReg* n_copy2 = nativeMovConstReg_at(copy_buff); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1076 n_copy2->set_pc_relative_offset(addr, instr_pc); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1077 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1078 #endif |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1079 |
0 | 1080 for (int i = NativeCall::instruction_size; i < *byte_count; i++) { |
1081 address ptr = copy_buff + i; | |
1082 int a_byte = (*ptr) & 0xFF; | |
1083 address dst = instr_pc + i; | |
1084 *(unsigned char*)dst = (unsigned char) a_byte; | |
1085 } | |
1086 ICache::invalidate_range(instr_pc, *byte_count); | |
1087 NativeGeneralJump::replace_mt_safe(instr_pc, copy_buff); | |
1088 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1089 if (load_klass_or_mirror_patch_id) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1090 relocInfo::relocType rtype = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1091 (stub_id == Runtime1::load_klass_patching_id) ? |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1092 relocInfo::metadata_type : |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1093 relocInfo::oop_type; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1094 // update relocInfo to metadata |
0 | 1095 nmethod* nm = CodeCache::find_nmethod(instr_pc); |
1096 assert(nm != NULL, "invalid nmethod_pc"); | |
1097 | |
1098 // The old patch site is now a move instruction so update | |
1099 // the reloc info so that it will get updated during | |
1100 // future GCs. | |
1101 RelocIterator iter(nm, (address)instr_pc, (address)(instr_pc + 1)); | |
1102 relocInfo::change_reloc_info_for_address(&iter, (address) instr_pc, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1103 relocInfo::none, rtype); |
0 | 1104 #ifdef SPARC |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1105 // Sparc takes two relocations for an metadata so update the second one. |
0 | 1106 address instr_pc2 = instr_pc + NativeMovConstReg::add_offset; |
1107 RelocIterator iter2(nm, instr_pc2, instr_pc2 + 1); | |
1108 relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1109 relocInfo::none, rtype); |
0 | 1110 #endif |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1111 #ifdef PPC |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1112 { address instr_pc2 = instr_pc + NativeMovConstReg::lo_offset; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1113 RelocIterator iter2(nm, instr_pc2, instr_pc2 + 1); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1114 relocInfo::change_reloc_info_for_address(&iter2, (address) instr_pc2, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1115 relocInfo::none, rtype); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1116 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1603
diff
changeset
|
1117 #endif |
0 | 1118 } |
1119 | |
1120 } else { | |
1121 ICache::invalidate_range(copy_buff, *byte_count); | |
1122 NativeGeneralJump::insert_unconditional(instr_pc, being_initialized_entry); | |
1123 } | |
1124 } | |
1125 } | |
1126 } | |
1127 JRT_END | |
1128 | |
1129 // | |
1130 // Entry point for compiled code. We want to patch a nmethod. | |
1131 // We don't do a normal VM transition here because we want to | |
1132 // know after the patching is complete and any safepoint(s) are taken | |
1133 // if the calling nmethod was deoptimized. We do this by calling a | |
1134 // helper method which does the normal VM transition and when it | |
1135 // completes we can check for deoptimization. This simplifies the | |
1136 // assembly code in the cpu directories. | |
1137 // | |
1138 int Runtime1::move_klass_patching(JavaThread* thread) { | |
1139 // | |
1140 // NOTE: we are still in Java | |
1141 // | |
1142 Thread* THREAD = thread; | |
1143 debug_only(NoHandleMark nhm;) | |
1144 { | |
1145 // Enter VM mode | |
1146 | |
1147 ResetNoHandleMark rnhm; | |
1148 patch_code(thread, load_klass_patching_id); | |
1149 } | |
1150 // Back in JAVA, use no oops DON'T safepoint | |
1151 | |
1152 // Return true if calling code is deoptimized | |
1153 | |
1154 return caller_is_deopted(); | |
1155 } | |
1156 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1157 int Runtime1::move_mirror_patching(JavaThread* thread) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1158 // |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1159 // NOTE: we are still in Java |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1160 // |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1161 Thread* THREAD = thread; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1162 debug_only(NoHandleMark nhm;) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1163 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1164 // Enter VM mode |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1165 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1166 ResetNoHandleMark rnhm; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1167 patch_code(thread, load_mirror_patching_id); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1168 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1169 // Back in JAVA, use no oops DON'T safepoint |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1170 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1171 // Return true if calling code is deoptimized |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1172 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1173 return caller_is_deopted(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1174 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1175 |
0 | 1176 // |
1177 // Entry point for compiled code. We want to patch a nmethod. | |
1178 // We don't do a normal VM transition here because we want to | |
1179 // know after the patching is complete and any safepoint(s) are taken | |
1180 // if the calling nmethod was deoptimized. We do this by calling a | |
1181 // helper method which does the normal VM transition and when it | |
1182 // completes we can check for deoptimization. This simplifies the | |
1183 // assembly code in the cpu directories. | |
1184 // | |
1185 | |
1186 int Runtime1::access_field_patching(JavaThread* thread) { | |
1187 // | |
1188 // NOTE: we are still in Java | |
1189 // | |
1190 Thread* THREAD = thread; | |
1191 debug_only(NoHandleMark nhm;) | |
1192 { | |
1193 // Enter VM mode | |
1194 | |
1195 ResetNoHandleMark rnhm; | |
1196 patch_code(thread, access_field_patching_id); | |
1197 } | |
1198 // Back in JAVA, use no oops DON'T safepoint | |
1199 | |
1200 // Return true if calling code is deoptimized | |
1201 | |
1202 return caller_is_deopted(); | |
1203 JRT_END | |
1204 | |
1205 | |
1206 JRT_LEAF(void, Runtime1::trace_block_entry(jint block_id)) | |
1207 // for now we just print out the block id | |
1208 tty->print("%d ", block_id); | |
1209 JRT_END | |
1210 | |
1211 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1212 // Array copy return codes. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1213 enum { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1214 ac_failed = -1, // arraycopy failed |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1215 ac_ok = 0 // arraycopy succeeded |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1216 }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1217 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1218 |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1219 // Below length is the # elements copied. |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1220 template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1221 oopDesc* dst, T* dst_addr, |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1222 int length) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1223 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1224 // For performance reasons, we assume we are using a card marking write |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1225 // barrier. The assert will fail if this is not the case. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1226 // Note that we use the non-virtual inlineable variant of write_ref_array. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1227 BarrierSet* bs = Universe::heap()->barrier_set(); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1228 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1229 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1230 if (src == dst) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1231 // same object, no check |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1232 bs->write_ref_array_pre(dst_addr, length); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1233 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1234 bs->write_ref_array((HeapWord*)dst_addr, length); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1235 return ac_ok; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1236 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1237 Klass* bound = objArrayKlass::cast(dst->klass())->element_klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1238 Klass* stype = objArrayKlass::cast(src->klass())->element_klass(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1239 if (stype == bound || Klass::cast(stype)->is_subtype_of(bound)) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1240 // Elements are guaranteed to be subtypes, so no check necessary |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1241 bs->write_ref_array_pre(dst_addr, length); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1242 Copy::conjoint_oops_atomic(src_addr, dst_addr, length); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1243 bs->write_ref_array((HeapWord*)dst_addr, length); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1244 return ac_ok; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1245 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1246 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1247 return ac_failed; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1248 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1249 |
0 | 1250 // fast and direct copy of arrays; returning -1, means that an exception may be thrown |
1251 // and we did not copy anything | |
1252 JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length)) | |
1253 #ifndef PRODUCT | |
1254 _generic_arraycopy_cnt++; // Slow-path oop array copy | |
1255 #endif | |
1256 | |
1257 if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed; | |
1258 if (!dst->is_array() || !src->is_array()) return ac_failed; | |
1259 if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed; | |
1260 if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed; | |
1261 | |
1262 if (length == 0) return ac_ok; | |
1263 if (src->is_typeArray()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1264 Klass* const klass_oop = src->klass(); |
0 | 1265 if (klass_oop != dst->klass()) return ac_failed; |
1266 typeArrayKlass* klass = typeArrayKlass::cast(klass_oop); | |
1267 const int l2es = klass->log2_element_size(); | |
1268 const int ihs = klass->array_header_in_bytes() / wordSize; | |
1269 char* src_addr = (char*) ((oopDesc**)src + ihs) + (src_pos << l2es); | |
1270 char* dst_addr = (char*) ((oopDesc**)dst + ihs) + (dst_pos << l2es); | |
1271 // Potential problem: memmove is not guaranteed to be word atomic | |
1272 // Revisit in Merlin | |
1273 memmove(dst_addr, src_addr, length << l2es); | |
1274 return ac_ok; | |
1275 } else if (src->is_objArray() && dst->is_objArray()) { | |
2002 | 1276 if (UseCompressedOops) { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1277 narrowOop *src_addr = objArrayOop(src)->obj_at_addr<narrowOop>(src_pos); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1278 narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1279 return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); |
0 | 1280 } else { |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1281 oop *src_addr = objArrayOop(src)->obj_at_addr<oop>(src_pos); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1282 oop *dst_addr = objArrayOop(dst)->obj_at_addr<oop>(dst_pos); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1283 return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); |
0 | 1284 } |
1285 } | |
1286 return ac_failed; | |
1287 JRT_END | |
1288 | |
1289 | |
1290 JRT_LEAF(void, Runtime1::primitive_arraycopy(HeapWord* src, HeapWord* dst, int length)) | |
1291 #ifndef PRODUCT | |
1292 _primitive_arraycopy_cnt++; | |
1293 #endif | |
1294 | |
1295 if (length == 0) return; | |
1296 // Not guaranteed to be word atomic, but that doesn't matter | |
1297 // for anything but an oop array, which is covered by oop_arraycopy. | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1602
diff
changeset
|
1298 Copy::conjoint_jbytes(src, dst, length); |
0 | 1299 JRT_END |
1300 | |
1301 JRT_LEAF(void, Runtime1::oop_arraycopy(HeapWord* src, HeapWord* dst, int num)) | |
1302 #ifndef PRODUCT | |
1303 _oop_arraycopy_cnt++; | |
1304 #endif | |
1305 | |
1306 if (num == 0) return; | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1307 BarrierSet* bs = Universe::heap()->barrier_set(); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1308 assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt"); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1309 assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well."); |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1310 if (UseCompressedOops) { |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1311 bs->write_ref_array_pre((narrowOop*)dst, num); |
2002 | 1312 Copy::conjoint_oops_atomic((narrowOop*) src, (narrowOop*) dst, num); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1313 } else { |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1314 bs->write_ref_array_pre((oop*)dst, num); |
2002 | 1315 Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num); |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1316 } |
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1142
diff
changeset
|
1317 bs->write_ref_array(dst, num); |
0 | 1318 JRT_END |
1319 | |
1320 | |
6135 | 1321 JRT_LEAF(int, Runtime1::is_instance_of(oopDesc* mirror, oopDesc* obj)) |
1322 // had to return int instead of bool, otherwise there may be a mismatch | |
1323 // between the C calling convention and the Java one. | |
1324 // e.g., on x86, GCC may clear only %al when returning a bool false, but | |
1325 // JVM takes the whole %eax as the return value, which may misinterpret | |
1326 // the return value as a boolean true. | |
1327 | |
1328 assert(mirror != NULL, "should null-check on mirror before calling"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6135
diff
changeset
|
1329 Klass* k = java_lang_Class::as_Klass(mirror); |
6135 | 1330 return (k != NULL && obj != NULL && obj->is_a(k)) ? 1 : 0; |
1331 JRT_END | |
1332 | |
1333 | |
0 | 1334 #ifndef PRODUCT |
1335 void Runtime1::print_statistics() { | |
1336 tty->print_cr("C1 Runtime statistics:"); | |
1337 tty->print_cr(" _resolve_invoke_virtual_cnt: %d", SharedRuntime::_resolve_virtual_ctr); | |
1338 tty->print_cr(" _resolve_invoke_opt_virtual_cnt: %d", SharedRuntime::_resolve_opt_virtual_ctr); | |
1339 tty->print_cr(" _resolve_invoke_static_cnt: %d", SharedRuntime::_resolve_static_ctr); | |
1340 tty->print_cr(" _handle_wrong_method_cnt: %d", SharedRuntime::_wrong_method_ctr); | |
1341 tty->print_cr(" _ic_miss_cnt: %d", SharedRuntime::_ic_miss_ctr); | |
1342 tty->print_cr(" _generic_arraycopy_cnt: %d", _generic_arraycopy_cnt); | |
2446 | 1343 tty->print_cr(" _generic_arraycopystub_cnt: %d", _generic_arraycopystub_cnt); |
1344 tty->print_cr(" _byte_arraycopy_cnt: %d", _byte_arraycopy_cnt); | |
1345 tty->print_cr(" _short_arraycopy_cnt: %d", _short_arraycopy_cnt); | |
1346 tty->print_cr(" _int_arraycopy_cnt: %d", _int_arraycopy_cnt); | |
1347 tty->print_cr(" _long_arraycopy_cnt: %d", _long_arraycopy_cnt); | |
0 | 1348 tty->print_cr(" _primitive_arraycopy_cnt: %d", _primitive_arraycopy_cnt); |
2446 | 1349 tty->print_cr(" _oop_arraycopy_cnt (C): %d", Runtime1::_oop_arraycopy_cnt); |
1350 tty->print_cr(" _oop_arraycopy_cnt (stub): %d", _oop_arraycopy_cnt); | |
0 | 1351 tty->print_cr(" _arraycopy_slowcase_cnt: %d", _arraycopy_slowcase_cnt); |
2446 | 1352 tty->print_cr(" _arraycopy_checkcast_cnt: %d", _arraycopy_checkcast_cnt); |
1353 tty->print_cr(" _arraycopy_checkcast_attempt_cnt:%d", _arraycopy_checkcast_attempt_cnt); | |
0 | 1354 |
1355 tty->print_cr(" _new_type_array_slowcase_cnt: %d", _new_type_array_slowcase_cnt); | |
1356 tty->print_cr(" _new_object_array_slowcase_cnt: %d", _new_object_array_slowcase_cnt); | |
1357 tty->print_cr(" _new_instance_slowcase_cnt: %d", _new_instance_slowcase_cnt); | |
1358 tty->print_cr(" _new_multi_array_slowcase_cnt: %d", _new_multi_array_slowcase_cnt); | |
1359 tty->print_cr(" _monitorenter_slowcase_cnt: %d", _monitorenter_slowcase_cnt); | |
1360 tty->print_cr(" _monitorexit_slowcase_cnt: %d", _monitorexit_slowcase_cnt); | |
1361 tty->print_cr(" _patch_code_slowcase_cnt: %d", _patch_code_slowcase_cnt); | |
1362 | |
1363 tty->print_cr(" _throw_range_check_exception_count: %d:", _throw_range_check_exception_count); | |
1364 tty->print_cr(" _throw_index_exception_count: %d:", _throw_index_exception_count); | |
1365 tty->print_cr(" _throw_div0_exception_count: %d:", _throw_div0_exception_count); | |
1366 tty->print_cr(" _throw_null_pointer_exception_count: %d:", _throw_null_pointer_exception_count); | |
1367 tty->print_cr(" _throw_class_cast_exception_count: %d:", _throw_class_cast_exception_count); | |
1368 tty->print_cr(" _throw_incompatible_class_change_error_count: %d:", _throw_incompatible_class_change_error_count); | |
1369 tty->print_cr(" _throw_array_store_exception_count: %d:", _throw_array_store_exception_count); | |
1370 tty->print_cr(" _throw_count: %d:", _throw_count); | |
1371 | |
1372 SharedRuntime::print_ic_miss_histogram(); | |
1373 tty->cr(); | |
1374 } | |
1375 #endif // PRODUCT |