Mercurial > hg > truffle
annotate src/cpu/x86/vm/templateInterpreter_x86_64.cpp @ 15388:769fc3629f59
Add phase FlowSensitiveReductionPhase.
It is possible to remove GuardingPiNodes, CheckCastNodes, and FixedGuards during
HighTier under certain conditions (control-flow sensitive conditions).
The phase added in this commit (FlowSensitiveReductionPhase) does that,
and in addition replaces usages with "downcasting" PiNodes when possible
thus resulting in more precise object stamps (e.g., non-null).
Finally, usages of floating, side-effects free, expressions are also simplified
(as per control-flow sensitive conditions).
The newly added phase runs only during HighTier and can be deactivated
using Graal option FlowSensitiveReduction (it is active by default).
author | Miguel Garcia <miguel.m.garcia@oracle.com> |
---|---|
date | Fri, 25 Apr 2014 16:50:52 +0200 |
parents | 4062efea018b |
children | 52b4284cb496 |
rev | line source |
---|---|
0 | 1 /* |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
2 * Copyright (c) 2003, 2013, 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:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
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:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6725
diff
changeset
|
26 #include "asm/macroAssembler.hpp" |
1972 | 27 #include "interpreter/bytecodeHistogram.hpp" |
28 #include "interpreter/interpreter.hpp" | |
29 #include "interpreter/interpreterGenerator.hpp" | |
30 #include "interpreter/interpreterRuntime.hpp" | |
31 #include "interpreter/templateTable.hpp" | |
32 #include "oops/arrayOop.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
33 #include "oops/methodData.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
34 #include "oops/method.hpp" |
1972 | 35 #include "oops/oop.inline.hpp" |
36 #include "prims/jvmtiExport.hpp" | |
37 #include "prims/jvmtiThreadState.hpp" | |
38 #include "runtime/arguments.hpp" | |
39 #include "runtime/deoptimization.hpp" | |
40 #include "runtime/frame.inline.hpp" | |
41 #include "runtime/sharedRuntime.hpp" | |
42 #include "runtime/stubRoutines.hpp" | |
43 #include "runtime/synchronizer.hpp" | |
44 #include "runtime/timer.hpp" | |
45 #include "runtime/vframeArray.hpp" | |
46 #include "utilities/debug.hpp" | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7402
diff
changeset
|
47 #include "utilities/macros.hpp" |
0 | 48 |
49 #define __ _masm-> | |
50 | |
304 | 51 #ifndef CC_INTERP |
52 | |
0 | 53 const int method_offset = frame::interpreter_frame_method_offset * wordSize; |
54 const int bci_offset = frame::interpreter_frame_bcx_offset * wordSize; | |
55 const int locals_offset = frame::interpreter_frame_locals_offset * wordSize; | |
56 | |
57 //----------------------------------------------------------------------------- | |
58 | |
59 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { | |
60 address entry = __ pc(); | |
61 | |
62 #ifdef ASSERT | |
63 { | |
64 Label L; | |
304 | 65 __ lea(rax, Address(rbp, |
66 frame::interpreter_frame_monitor_block_top_offset * | |
67 wordSize)); | |
68 __ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack | |
69 // grows negative) | |
0 | 70 __ jcc(Assembler::aboveEqual, L); // check if frame is complete |
71 __ stop ("interpreter frame not set up"); | |
72 __ bind(L); | |
73 } | |
74 #endif // ASSERT | |
75 // Restore bcp under the assumption that the current frame is still | |
76 // interpreted | |
77 __ restore_bcp(); | |
78 | |
79 // expression stack must be empty before entering the VM if an | |
80 // exception happened | |
81 __ empty_expression_stack(); | |
82 // throw exception | |
83 __ call_VM(noreg, | |
84 CAST_FROM_FN_PTR(address, | |
85 InterpreterRuntime::throw_StackOverflowError)); | |
86 return entry; | |
87 } | |
88 | |
89 address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler( | |
90 const char* name) { | |
91 address entry = __ pc(); | |
92 // expression stack must be empty before entering the VM if an | |
93 // exception happened | |
94 __ empty_expression_stack(); | |
95 // setup parameters | |
96 // ??? convention: expect aberrant index in register ebx | |
97 __ lea(c_rarg1, ExternalAddress((address)name)); | |
98 __ call_VM(noreg, | |
99 CAST_FROM_FN_PTR(address, | |
100 InterpreterRuntime:: | |
101 throw_ArrayIndexOutOfBoundsException), | |
102 c_rarg1, rbx); | |
103 return entry; | |
104 } | |
105 | |
106 address TemplateInterpreterGenerator::generate_ClassCastException_handler() { | |
107 address entry = __ pc(); | |
108 | |
109 // object is at TOS | |
304 | 110 __ pop(c_rarg1); |
0 | 111 |
112 // expression stack must be empty before entering the VM if an | |
113 // exception happened | |
114 __ empty_expression_stack(); | |
115 | |
116 __ call_VM(noreg, | |
117 CAST_FROM_FN_PTR(address, | |
118 InterpreterRuntime:: | |
119 throw_ClassCastException), | |
120 c_rarg1); | |
121 return entry; | |
122 } | |
123 | |
124 address TemplateInterpreterGenerator::generate_exception_handler_common( | |
125 const char* name, const char* message, bool pass_oop) { | |
126 assert(!pass_oop || message == NULL, "either oop or message but not both"); | |
127 address entry = __ pc(); | |
128 if (pass_oop) { | |
129 // object is at TOS | |
304 | 130 __ pop(c_rarg2); |
0 | 131 } |
132 // expression stack must be empty before entering the VM if an | |
133 // exception happened | |
134 __ empty_expression_stack(); | |
135 // setup parameters | |
136 __ lea(c_rarg1, ExternalAddress((address)name)); | |
137 if (pass_oop) { | |
138 __ call_VM(rax, CAST_FROM_FN_PTR(address, | |
139 InterpreterRuntime:: | |
140 create_klass_exception), | |
141 c_rarg1, c_rarg2); | |
142 } else { | |
143 // kind of lame ExternalAddress can't take NULL because | |
144 // external_word_Relocation will assert. | |
145 if (message != NULL) { | |
146 __ lea(c_rarg2, ExternalAddress((address)message)); | |
147 } else { | |
148 __ movptr(c_rarg2, NULL_WORD); | |
149 } | |
150 __ call_VM(rax, | |
151 CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), | |
152 c_rarg1, c_rarg2); | |
153 } | |
154 // throw exception | |
155 __ jump(ExternalAddress(Interpreter::throw_exception_entry())); | |
156 return entry; | |
157 } | |
158 | |
159 | |
160 address TemplateInterpreterGenerator::generate_continuation_for(TosState state) { | |
161 address entry = __ pc(); | |
162 // NULL last_sp until next java call | |
304 | 163 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
0 | 164 __ dispatch_next(state); |
165 return entry; | |
166 } | |
167 | |
168 | |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
169 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) { |
0 | 170 address entry = __ pc(); |
171 | |
172 // Restore stack bottom in case i2c adjusted stack | |
304 | 173 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
0 | 174 // and NULL it as marker that esp is now tos until next java call |
304 | 175 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
0 | 176 |
177 __ restore_bcp(); | |
178 __ restore_locals(); | |
304 | 179 |
12882
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
180 if (state == atos) { |
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
181 Register mdp = rbx; |
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
182 Register tmp = rcx; |
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
183 __ profile_return_type(mdp, rax, tmp); |
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
184 } |
ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
roland
parents:
12076
diff
changeset
|
185 |
13010
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
186 const Register cache = rbx; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
187 const Register index = rcx; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
188 __ get_cache_and_index_at_bcp(cache, index, 1, index_size); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
189 |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
190 const Register flags = cache; |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
191 __ movl(flags, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
192 __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask); |
bd3237e0e18d
8026328: Setting a breakpoint on invokedynamic crashes the JVM
twisti
parents:
12962
diff
changeset
|
193 __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale())); |
0 | 194 __ dispatch_next(state, step); |
1108 | 195 |
0 | 196 return entry; |
197 } | |
198 | |
199 | |
8328
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
200 address InterpreterGenerator::generate_deopt_entry_for(TosState state, |
0 | 201 int step) { |
202 address entry = __ pc(); | |
203 // NULL last_sp until next java call | |
304 | 204 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
0 | 205 __ restore_bcp(); |
206 __ restore_locals(); | |
13220
2b43fcc68add
Put _pending_deoptimization and _pending_monitorenter under ifdef GRAAL
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
13086
diff
changeset
|
207 #ifdef GRAAL |
8328
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
208 // Check if we need to take lock at entry of synchronized method. |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
209 { |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
210 Label L; |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
211 __ cmpb(Address(r15_thread, Thread::pending_monitorenter_offset()), 0); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
212 __ jcc(Assembler::zero, L); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
213 // Clear flag. |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
214 __ movb(Address(r15_thread, Thread::pending_monitorenter_offset()), 0); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
215 // Satisfy calling convention for lock_method(). |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
216 __ get_method(rbx); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
217 // Take lock. |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
218 lock_method(); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
219 __ bind(L); |
6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
8124
diff
changeset
|
220 } |
13220
2b43fcc68add
Put _pending_deoptimization and _pending_monitorenter under ifdef GRAAL
Gilles Duboscq <duboscq@ssw.jku.at>
parents:
13086
diff
changeset
|
221 #endif |
0 | 222 // handle exceptions |
223 { | |
224 Label L; | |
304 | 225 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); |
0 | 226 __ jcc(Assembler::zero, L); |
227 __ call_VM(noreg, | |
228 CAST_FROM_FN_PTR(address, | |
229 InterpreterRuntime::throw_pending_exception)); | |
230 __ should_not_reach_here(); | |
231 __ bind(L); | |
232 } | |
233 __ dispatch_next(state, step); | |
234 return entry; | |
235 } | |
236 | |
237 int AbstractInterpreter::BasicType_as_index(BasicType type) { | |
238 int i = 0; | |
239 switch (type) { | |
240 case T_BOOLEAN: i = 0; break; | |
241 case T_CHAR : i = 1; break; | |
242 case T_BYTE : i = 2; break; | |
243 case T_SHORT : i = 3; break; | |
244 case T_INT : i = 4; break; | |
245 case T_LONG : i = 5; break; | |
246 case T_VOID : i = 6; break; | |
247 case T_FLOAT : i = 7; break; | |
248 case T_DOUBLE : i = 8; break; | |
249 case T_OBJECT : i = 9; break; | |
250 case T_ARRAY : i = 9; break; | |
251 default : ShouldNotReachHere(); | |
252 } | |
253 assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, | |
254 "index out of bounds"); | |
255 return i; | |
256 } | |
257 | |
258 | |
259 address TemplateInterpreterGenerator::generate_result_handler_for( | |
260 BasicType type) { | |
261 address entry = __ pc(); | |
262 switch (type) { | |
263 case T_BOOLEAN: __ c2bool(rax); break; | |
264 case T_CHAR : __ movzwl(rax, rax); break; | |
265 case T_BYTE : __ sign_extend_byte(rax); break; | |
266 case T_SHORT : __ sign_extend_short(rax); break; | |
267 case T_INT : /* nothing to do */ break; | |
268 case T_LONG : /* nothing to do */ break; | |
269 case T_VOID : /* nothing to do */ break; | |
270 case T_FLOAT : /* nothing to do */ break; | |
271 case T_DOUBLE : /* nothing to do */ break; | |
272 case T_OBJECT : | |
273 // retrieve result from frame | |
304 | 274 __ movptr(rax, Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize)); |
0 | 275 // and verify it |
276 __ verify_oop(rax); | |
277 break; | |
278 default : ShouldNotReachHere(); | |
279 } | |
280 __ ret(0); // return from result handler | |
281 return entry; | |
282 } | |
283 | |
284 address TemplateInterpreterGenerator::generate_safept_entry_for( | |
285 TosState state, | |
286 address runtime_entry) { | |
287 address entry = __ pc(); | |
288 __ push(state); | |
289 __ call_VM(noreg, runtime_entry); | |
290 __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos)); | |
291 return entry; | |
292 } | |
293 | |
294 | |
295 | |
296 // Helpers for commoning out cases in the various type of method entries. | |
297 // | |
298 | |
299 | |
300 // increment invocation count & check for overflow | |
301 // | |
302 // Note: checking for negative value instead of overflow | |
303 // so we have a 'sticky' overflow test | |
304 // | |
305 // rbx: method | |
306 // ecx: invocation counter | |
307 // | |
308 void InterpreterGenerator::generate_counter_incr( | |
309 Label* overflow, | |
310 Label* profile_method, | |
311 Label* profile_method_continue) { | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
312 Label done; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
313 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
1783 | 314 if (TieredCompilation) { |
315 int increment = InvocationCounter::count_increment; | |
316 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
317 Label no_mdo; |
1783 | 318 if (ProfileInterpreter) { |
319 // Are we profiling? | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
320 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
1783 | 321 __ testptr(rax, rax); |
322 __ jccb(Assembler::zero, no_mdo); | |
323 // Increment counter in the MDO | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
324 const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) + |
1783 | 325 in_bytes(InvocationCounter::counter_offset())); |
326 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); | |
10141
47766e2d2527
8013041: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset.
jiangli
parents:
10105
diff
changeset
|
327 __ jmp(done); |
1783 | 328 } |
329 __ bind(no_mdo); | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
330 // Increment counter in MethodCounters |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
331 const Address invocation_counter(rax, |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
332 MethodCounters::invocation_counter_offset() + |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
333 InvocationCounter::counter_offset()); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
334 __ get_method_counters(rbx, rax, done); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
335 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
336 false, Assembler::zero, overflow); |
1783 | 337 __ bind(done); |
338 } else { | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
339 const Address backedge_counter(rax, |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
340 MethodCounters::backedge_counter_offset() + |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
341 InvocationCounter::counter_offset()); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
342 const Address invocation_counter(rax, |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
343 MethodCounters::invocation_counter_offset() + |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
344 InvocationCounter::counter_offset()); |
0 | 345 |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
346 __ get_method_counters(rbx, rax, done); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
347 |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
348 if (ProfileInterpreter) { |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
349 __ incrementl(Address(rax, |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
350 MethodCounters::interpreter_invocation_counter_offset())); |
1783 | 351 } |
352 // Update standard invocation counters | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
353 __ movl(rcx, invocation_counter); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
354 __ incrementl(rcx, InvocationCounter::count_increment); |
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
355 __ movl(invocation_counter, rcx); // save invocation count |
0 | 356 |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
357 __ movl(rax, backedge_counter); // load backedge counter |
1783 | 358 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
0 | 359 |
1783 | 360 __ addl(rcx, rax); // add both counters |
0 | 361 |
1783 | 362 // profile_method is non-null only for interpreted method so |
363 // profile_method != NULL == !native_call | |
364 | |
365 if (ProfileInterpreter && profile_method != NULL) { | |
366 // Test to see if we should create a method data oop | |
367 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit)); | |
368 __ jcc(Assembler::less, *profile_method_continue); | |
0 | 369 |
1783 | 370 // if no method data exists, go to profile_method |
371 __ test_method_data_pointer(rax, *profile_method); | |
372 } | |
373 | |
374 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); | |
375 __ jcc(Assembler::aboveEqual, *overflow); | |
10105
aeaca88565e6
8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents:
8873
diff
changeset
|
376 __ bind(done); |
0 | 377 } |
378 } | |
379 | |
380 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { | |
381 | |
382 // Asm interpreter on entry | |
383 // r14 - locals | |
384 // r13 - bcp | |
385 // rbx - method | |
386 // edx - cpool --- DOES NOT APPEAR TO BE TRUE | |
387 // rbp - interpreter frame | |
388 | |
389 // On return (i.e. jump to entry_point) [ back to invocation of interpreter ] | |
390 // Everything as it was on entry | |
391 // rdx is not restored. Doesn't appear to really be set. | |
392 | |
393 // InterpreterRuntime::frequency_counter_overflow takes two | |
394 // arguments, the first (thread) is passed by call_VM, the second | |
395 // indicates if the counter overflow occurs at a backwards branch | |
396 // (NULL bcp). We pass zero for it. The call returns the address | |
397 // of the verified entry point for the method or NULL if the | |
398 // compilation did not complete (either went background or bailed | |
399 // out). | |
400 __ movl(c_rarg1, 0); | |
401 __ call_VM(noreg, | |
402 CAST_FROM_FN_PTR(address, | |
403 InterpreterRuntime::frequency_counter_overflow), | |
404 c_rarg1); | |
405 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
406 __ movptr(rbx, Address(rbp, method_offset)); // restore Method* |
0 | 407 // Preserve invariant that r13/r14 contain bcp/locals of sender frame |
408 // and jump to the interpreted entry. | |
409 __ jmp(*do_continue, relocInfo::none); | |
410 } | |
411 | |
412 // See if we've got enough room on the stack for locals plus overhead. | |
413 // The expression stack grows down incrementally, so the normal guard | |
414 // page mechanism will work for that. | |
415 // | |
416 // NOTE: Since the additional locals are also always pushed (wasn't | |
417 // obvious in generate_method_entry) so the guard should work for them | |
418 // too. | |
419 // | |
420 // Args: | |
421 // rdx: number of additional locals this frame needs (what we must check) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
422 // rbx: Method* |
0 | 423 // |
424 // Kills: | |
425 // rax | |
426 void InterpreterGenerator::generate_stack_overflow_check(void) { | |
427 | |
428 // monitor entry size: see picture of stack set | |
429 // (generate_method_entry) and frame_amd64.hpp | |
430 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; | |
431 | |
432 // total overhead size: entry_size + (saved rbp through expr stack | |
433 // bottom). be sure to change this if you add/subtract anything | |
434 // to/from the overhead area | |
435 const int overhead_size = | |
436 -(frame::interpreter_frame_initial_sp_offset * wordSize) + entry_size; | |
437 | |
438 const int page_size = os::vm_page_size(); | |
439 | |
440 Label after_frame_check; | |
441 | |
442 // see if the frame is greater than one page in size. If so, | |
443 // then we need to verify there is enough stack space remaining | |
444 // for the additional locals. | |
1506 | 445 __ cmpl(rdx, (page_size - overhead_size) / Interpreter::stackElementSize); |
0 | 446 __ jcc(Assembler::belowEqual, after_frame_check); |
447 | |
448 // compute rsp as if this were going to be the last frame on | |
449 // the stack before the red zone | |
450 | |
451 const Address stack_base(r15_thread, Thread::stack_base_offset()); | |
452 const Address stack_size(r15_thread, Thread::stack_size_offset()); | |
453 | |
454 // locals + overhead, in bytes | |
304 | 455 __ mov(rax, rdx); |
1506 | 456 __ shlptr(rax, Interpreter::logStackElementSize); // 2 slots per parameter. |
304 | 457 __ addptr(rax, overhead_size); |
0 | 458 |
459 #ifdef ASSERT | |
460 Label stack_base_okay, stack_size_okay; | |
461 // verify that thread stack base is non-zero | |
304 | 462 __ cmpptr(stack_base, (int32_t)NULL_WORD); |
0 | 463 __ jcc(Assembler::notEqual, stack_base_okay); |
464 __ stop("stack base is zero"); | |
465 __ bind(stack_base_okay); | |
466 // verify that thread stack size is non-zero | |
304 | 467 __ cmpptr(stack_size, 0); |
0 | 468 __ jcc(Assembler::notEqual, stack_size_okay); |
469 __ stop("stack size is zero"); | |
470 __ bind(stack_size_okay); | |
471 #endif | |
472 | |
473 // Add stack base to locals and subtract stack size | |
304 | 474 __ addptr(rax, stack_base); |
475 __ subptr(rax, stack_size); | |
0 | 476 |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
477 // Use the maximum number of pages we might bang. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
478 const int max_pages = StackShadowPages > (StackRedPages+StackYellowPages) ? StackShadowPages : |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
479 (StackRedPages+StackYellowPages); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
480 |
0 | 481 // add in the red and yellow zone sizes |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
482 __ addptr(rax, max_pages * page_size); |
0 | 483 |
484 // check against the current stack bottom | |
304 | 485 __ cmpptr(rsp, rax); |
0 | 486 __ jcc(Assembler::above, after_frame_check); |
487 | |
4743 | 488 // Restore sender's sp as SP. This is necessary if the sender's |
489 // frame is an extended compiled frame (see gen_c2i_adapter()) | |
490 // and safer anyway in case of JSR292 adaptations. | |
491 | |
492 __ pop(rax); // return address must be moved if SP is changed | |
493 __ mov(rsp, r13); | |
494 __ push(rax); | |
495 | |
496 // Note: the restored frame is not necessarily interpreted. | |
497 // Use the shared runtime version of the StackOverflowError. | |
498 assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "stub not yet generated"); | |
499 __ jump(ExternalAddress(StubRoutines::throw_StackOverflowError_entry())); | |
0 | 500 |
501 // all done with frame size check | |
502 __ bind(after_frame_check); | |
503 } | |
504 | |
505 // Allocate monitor and lock method (asm interpreter) | |
506 // | |
507 // Args: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
508 // rbx: Method* |
0 | 509 // r14: locals |
510 // | |
511 // Kills: | |
512 // rax | |
513 // c_rarg0, c_rarg1, c_rarg2, c_rarg3, ...(param regs) | |
514 // rscratch1, rscratch2 (scratch regs) | |
515 void InterpreterGenerator::lock_method(void) { | |
516 // synchronize method | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
517 const Address access_flags(rbx, Method::access_flags_offset()); |
0 | 518 const Address monitor_block_top( |
519 rbp, | |
520 frame::interpreter_frame_monitor_block_top_offset * wordSize); | |
521 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; | |
522 | |
523 #ifdef ASSERT | |
524 { | |
525 Label L; | |
526 __ movl(rax, access_flags); | |
527 __ testl(rax, JVM_ACC_SYNCHRONIZED); | |
528 __ jcc(Assembler::notZero, L); | |
529 __ stop("method doesn't need synchronization"); | |
530 __ bind(L); | |
531 } | |
532 #endif // ASSERT | |
533 | |
534 // get synchronization object | |
535 { | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4042
diff
changeset
|
536 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
0 | 537 Label done; |
538 __ movl(rax, access_flags); | |
539 __ testl(rax, JVM_ACC_STATIC); | |
540 // get receiver (assume this is frequent case) | |
304 | 541 __ movptr(rax, Address(r14, Interpreter::local_offset_in_bytes(0))); |
0 | 542 __ jcc(Assembler::zero, done); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
543 __ movptr(rax, Address(rbx, Method::const_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
544 __ movptr(rax, Address(rax, ConstMethod::constants_offset())); |
304 | 545 __ movptr(rax, Address(rax, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
546 ConstantPool::pool_holder_offset_in_bytes())); |
304 | 547 __ movptr(rax, Address(rax, mirror_offset)); |
0 | 548 |
549 #ifdef ASSERT | |
550 { | |
551 Label L; | |
304 | 552 __ testptr(rax, rax); |
0 | 553 __ jcc(Assembler::notZero, L); |
554 __ stop("synchronization object is NULL"); | |
555 __ bind(L); | |
556 } | |
557 #endif // ASSERT | |
558 | |
559 __ bind(done); | |
560 } | |
561 | |
562 // add space for monitor & lock | |
304 | 563 __ subptr(rsp, entry_size); // add space for a monitor entry |
564 __ movptr(monitor_block_top, rsp); // set new monitor block top | |
0 | 565 // store object |
304 | 566 __ movptr(Address(rsp, BasicObjectLock::obj_offset_in_bytes()), rax); |
567 __ movptr(c_rarg1, rsp); // object address | |
0 | 568 __ lock_object(c_rarg1); |
569 } | |
570 | |
571 // Generate a fixed interpreter frame. This is identical setup for | |
572 // interpreted methods and for native methods hence the shared code. | |
573 // | |
574 // Args: | |
575 // rax: return address | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
576 // rbx: Method* |
0 | 577 // r14: pointer to locals |
578 // r13: sender sp | |
579 // rdx: cp cache | |
580 void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { | |
581 // initialize fixed part of activation frame | |
304 | 582 __ push(rax); // save return address |
0 | 583 __ enter(); // save old & set new rbp |
304 | 584 __ push(r13); // set sender sp |
585 __ push((int)NULL_WORD); // leave last_sp as null | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
586 __ movptr(r13, Address(rbx, Method::const_offset())); // get ConstMethod* |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
587 __ lea(r13, Address(r13, ConstMethod::codes_offset())); // get codebase |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
588 __ push(rbx); // save Method* |
0 | 589 if (ProfileInterpreter) { |
590 Label method_data_continue; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
591 __ movptr(rdx, Address(rbx, in_bytes(Method::method_data_offset()))); |
304 | 592 __ testptr(rdx, rdx); |
0 | 593 __ jcc(Assembler::zero, method_data_continue); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
594 __ addptr(rdx, in_bytes(MethodData::data_offset())); |
0 | 595 __ bind(method_data_continue); |
304 | 596 __ push(rdx); // set the mdp (method data pointer) |
0 | 597 } else { |
304 | 598 __ push(0); |
0 | 599 } |
600 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
601 __ movptr(rdx, Address(rbx, Method::const_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
602 __ movptr(rdx, Address(rdx, ConstMethod::constants_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
603 __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes())); |
304 | 604 __ push(rdx); // set constant pool cache |
605 __ push(r14); // set locals pointer | |
0 | 606 if (native_call) { |
304 | 607 __ push(0); // no bcp |
0 | 608 } else { |
304 | 609 __ push(r13); // set bcp |
0 | 610 } |
304 | 611 __ push(0); // reserve word for pointer to expression stack bottom |
612 __ movptr(Address(rsp, 0), rsp); // set expression stack bottom | |
0 | 613 } |
614 | |
615 // End of helpers | |
616 | |
304 | 617 // Various method entries |
618 //------------------------------------------------------------------------------------------------------------------------ | |
619 // | |
620 // | |
621 | |
622 // Call an accessor method (assuming it is resolved, otherwise drop | |
623 // into vanilla (slow path) entry | |
624 address InterpreterGenerator::generate_accessor_entry(void) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
625 // rbx: Method* |
304 | 626 |
627 // r13: senderSP must preserver for slow path, set SP to it on fast path | |
628 | |
629 address entry_point = __ pc(); | |
630 Label xreturn_path; | |
631 | |
632 // do fastpath for resolved accessor methods | |
633 if (UseFastAccessorMethods) { | |
634 // Code: _aload_0, _(i|a)getfield, _(i|a)return or any rewrites | |
635 // thereof; parameter size = 1 | |
636 // Note: We can only use this code if the getfield has been resolved | |
637 // and if we don't have a null-pointer exception => check for | |
638 // these conditions first and use slow path if necessary. | |
639 Label slow_path; | |
640 // If we need a safepoint check, generate full interpreter entry. | |
641 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), | |
642 SafepointSynchronize::_not_synchronized); | |
643 | |
644 __ jcc(Assembler::notEqual, slow_path); | |
645 // rbx: method | |
646 __ movptr(rax, Address(rsp, wordSize)); | |
647 | |
648 // check if local 0 != NULL and read field | |
649 __ testptr(rax, rax); | |
650 __ jcc(Assembler::zero, slow_path); | |
651 | |
652 // read first instruction word and extract bytecode @ 1 and index @ 2 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
653 __ movptr(rdx, Address(rbx, Method::const_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
654 __ movptr(rdi, Address(rdx, ConstMethod::constants_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
655 __ movl(rdx, Address(rdx, ConstMethod::codes_offset())); |
304 | 656 // Shift codes right to get the index on the right. |
657 // The bytecode fetched looks like <index><0xb4><0x2a> | |
658 __ shrl(rdx, 2 * BitsPerByte); | |
659 __ shll(rdx, exact_log2(in_words(ConstantPoolCacheEntry::size()))); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
660 __ movptr(rdi, Address(rdi, ConstantPool::cache_offset_in_bytes())); |
304 | 661 |
662 // rax: local 0 | |
663 // rbx: method | |
664 // rdx: constant pool cache index | |
665 // rdi: constant pool cache | |
666 | |
667 // check if getfield has been resolved and read constant pool cache entry | |
668 // check the validity of the cache entry by testing whether _indices field | |
669 // contains Bytecode::_getfield in b1 byte. | |
670 assert(in_words(ConstantPoolCacheEntry::size()) == 4, | |
671 "adjust shift below"); | |
672 __ movl(rcx, | |
673 Address(rdi, | |
674 rdx, | |
675 Address::times_8, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
676 ConstantPoolCache::base_offset() + |
304 | 677 ConstantPoolCacheEntry::indices_offset())); |
678 __ shrl(rcx, 2 * BitsPerByte); | |
679 __ andl(rcx, 0xFF); | |
680 __ cmpl(rcx, Bytecodes::_getfield); | |
681 __ jcc(Assembler::notEqual, slow_path); | |
682 | |
683 // Note: constant pool entry is not valid before bytecode is resolved | |
684 __ movptr(rcx, | |
685 Address(rdi, | |
686 rdx, | |
687 Address::times_8, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
688 ConstantPoolCache::base_offset() + |
304 | 689 ConstantPoolCacheEntry::f2_offset())); |
690 // edx: flags | |
691 __ movl(rdx, | |
692 Address(rdi, | |
693 rdx, | |
694 Address::times_8, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
695 ConstantPoolCache::base_offset() + |
304 | 696 ConstantPoolCacheEntry::flags_offset())); |
697 | |
698 Label notObj, notInt, notByte, notShort; | |
699 const Address field_address(rax, rcx, Address::times_1); | |
700 | |
701 // Need to differentiate between igetfield, agetfield, bgetfield etc. | |
702 // because they are different sizes. | |
703 // Use the type from the constant pool cache | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
704 __ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
705 // Make sure we don't need to mask edx after the above shift |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
706 ConstantPoolCacheEntry::verify_tos_state_shift(); |
304 | 707 |
708 __ cmpl(rdx, atos); | |
709 __ jcc(Assembler::notEqual, notObj); | |
710 // atos | |
711 __ load_heap_oop(rax, field_address); | |
712 __ jmp(xreturn_path); | |
713 | |
714 __ bind(notObj); | |
715 __ cmpl(rdx, itos); | |
716 __ jcc(Assembler::notEqual, notInt); | |
717 // itos | |
718 __ movl(rax, field_address); | |
719 __ jmp(xreturn_path); | |
720 | |
721 __ bind(notInt); | |
722 __ cmpl(rdx, btos); | |
723 __ jcc(Assembler::notEqual, notByte); | |
724 // btos | |
725 __ load_signed_byte(rax, field_address); | |
726 __ jmp(xreturn_path); | |
727 | |
728 __ bind(notByte); | |
729 __ cmpl(rdx, stos); | |
730 __ jcc(Assembler::notEqual, notShort); | |
731 // stos | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
732 __ load_signed_short(rax, field_address); |
304 | 733 __ jmp(xreturn_path); |
734 | |
735 __ bind(notShort); | |
736 #ifdef ASSERT | |
737 Label okay; | |
738 __ cmpl(rdx, ctos); | |
739 __ jcc(Assembler::equal, okay); | |
740 __ stop("what type is this?"); | |
741 __ bind(okay); | |
742 #endif | |
743 // ctos | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
744 __ load_unsigned_short(rax, field_address); |
304 | 745 |
746 __ bind(xreturn_path); | |
747 | |
748 // _ireturn/_areturn | |
749 __ pop(rdi); | |
750 __ mov(rsp, r13); | |
751 __ jmp(rdi); | |
752 __ ret(0); | |
753 | |
754 // generate a vanilla interpreter entry as the slow path | |
755 __ bind(slow_path); | |
756 (void) generate_normal_entry(false); | |
757 } else { | |
758 (void) generate_normal_entry(false); | |
759 } | |
760 | |
761 return entry_point; | |
762 } | |
763 | |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
764 // Method entry for java.lang.ref.Reference.get. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
765 address InterpreterGenerator::generate_Reference_get_entry(void) { |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7402
diff
changeset
|
766 #if INCLUDE_ALL_GCS |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
767 // Code: _aload_0, _getfield, _areturn |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
768 // parameter size = 1 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
769 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
770 // The code that gets generated by this routine is split into 2 parts: |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
771 // 1. The "intrinsified" code for G1 (or any SATB based GC), |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
772 // 2. The slow path - which is an expansion of the regular method entry. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
773 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
774 // Notes:- |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
775 // * In the G1 code we do not check whether we need to block for |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
776 // a safepoint. If G1 is enabled then we must execute the specialized |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
777 // code for Reference.get (except when the Reference object is null) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
778 // so that we can log the value in the referent field with an SATB |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
779 // update buffer. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
780 // If the code for the getfield template is modified so that the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
781 // G1 pre-barrier code is executed when the current method is |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
782 // Reference.get() then going through the normal method entry |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
783 // will be fine. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
784 // * The G1 code can, however, check the receiver object (the instance |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
785 // of java.lang.Reference) and jump to the slow path if null. If the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
786 // Reference object is null then we obviously cannot fetch the referent |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
787 // and so we don't need to call the G1 pre-barrier. Thus we can use the |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
788 // regular method entry code to generate the NPE. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
789 // |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
790 // This code is based on generate_accessor_enty. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
791 // |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
792 // rbx: Method* |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
793 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
794 // r13: senderSP must preserve for slow path, set SP to it on fast path |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
795 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
796 address entry = __ pc(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
797 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
798 const int referent_offset = java_lang_ref_Reference::referent_offset; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
799 guarantee(referent_offset > 0, "referent offset not initialized"); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
800 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
801 if (UseG1GC) { |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
802 Label slow_path; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
803 // rbx: method |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
804 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
805 // Check if local 0 != NULL |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
806 // If the receiver is null then it is OK to jump to the slow path. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
807 __ movptr(rax, Address(rsp, wordSize)); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
808 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
809 __ testptr(rax, rax); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
810 __ jcc(Assembler::zero, slow_path); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
811 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
812 // rax: local 0 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
813 // rbx: method (but can be used as scratch now) |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
814 // rdx: scratch |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
815 // rdi: scratch |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
816 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
817 // Generate the G1 pre-barrier code to log the value of |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
818 // the referent field in an SATB buffer. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
819 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
820 // Load the value of the referent field. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
821 const Address field_address(rax, referent_offset); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
822 __ load_heap_oop(rax, field_address); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
823 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
824 // Generate the G1 pre-barrier code to log the value of |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
825 // the referent field in an SATB buffer. |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
826 __ g1_write_barrier_pre(noreg /* obj */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
827 rax /* pre_val */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
828 r15_thread /* thread */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
829 rbx /* tmp */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
830 true /* tosca_live */, |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
831 true /* expand_call */); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
832 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
833 // _areturn |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
834 __ pop(rdi); // get return address |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
835 __ mov(rsp, r13); // set sp to sender sp |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
836 __ jmp(rdi); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
837 __ ret(0); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
838 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
839 // generate a vanilla interpreter entry as the slow path |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
840 __ bind(slow_path); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
841 (void) generate_normal_entry(false); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
842 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
843 return entry; |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
844 } |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7402
diff
changeset
|
845 #endif // INCLUDE_ALL_GCS |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
846 |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
847 // If G1 is not enabled then attempt to go through the accessor entry point |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
848 // Reference.get is an accessor |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
849 return generate_accessor_entry(); |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
850 } |
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
851 |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
852 /** |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
853 * Method entry for static native methods: |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
854 * int java.util.zip.CRC32.update(int crc, int b) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
855 */ |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
856 address InterpreterGenerator::generate_CRC32_update_entry() { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
857 if (UseCRC32Intrinsics) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
858 address entry = __ pc(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
859 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
860 // rbx,: Method* |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
861 // r13: senderSP must preserved for slow path, set SP to it on fast path |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
862 // c_rarg0: scratch (rdi on non-Win64, rcx on Win64) |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
863 // c_rarg1: scratch (rsi on non-Win64, rdx on Win64) |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
864 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
865 Label slow_path; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
866 // If we need a safepoint check, generate full interpreter entry. |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
867 ExternalAddress state(SafepointSynchronize::address_of_state()); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
868 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
869 SafepointSynchronize::_not_synchronized); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
870 __ jcc(Assembler::notEqual, slow_path); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
871 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
872 // We don't generate local frame and don't align stack because |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
873 // we call stub code and there is no safepoint on this path. |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
874 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
875 // Load parameters |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
876 const Register crc = rax; // crc |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
877 const Register val = c_rarg0; // source java byte value |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
878 const Register tbl = c_rarg1; // scratch |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
879 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
880 // Arguments are reversed on java expression stack |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
881 __ movl(val, Address(rsp, wordSize)); // byte value |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
882 __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
883 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
884 __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
885 __ notl(crc); // ~crc |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
886 __ update_byte_crc32(crc, val, tbl); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
887 __ notl(crc); // ~crc |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
888 // result in rax |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
889 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
890 // _areturn |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
891 __ pop(rdi); // get return address |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
892 __ mov(rsp, r13); // set sp to sender sp |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
893 __ jmp(rdi); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
894 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
895 // generate a vanilla native entry as the slow path |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
896 __ bind(slow_path); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
897 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
898 (void) generate_native_entry(false); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
899 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
900 return entry; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
901 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
902 return generate_native_entry(false); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
903 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
904 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
905 /** |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
906 * Method entry for static native methods: |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
907 * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
908 * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
909 */ |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
910 address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
911 if (UseCRC32Intrinsics) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
912 address entry = __ pc(); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
913 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
914 // rbx,: Method* |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
915 // r13: senderSP must preserved for slow path, set SP to it on fast path |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
916 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
917 Label slow_path; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
918 // If we need a safepoint check, generate full interpreter entry. |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
919 ExternalAddress state(SafepointSynchronize::address_of_state()); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
920 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
921 SafepointSynchronize::_not_synchronized); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
922 __ jcc(Assembler::notEqual, slow_path); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
923 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
924 // We don't generate local frame and don't align stack because |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
925 // we call stub code and there is no safepoint on this path. |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
926 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
927 // Load parameters |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
928 const Register crc = c_rarg0; // crc |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
929 const Register buf = c_rarg1; // source java byte array address |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
930 const Register len = c_rarg2; // length |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
931 const Register off = len; // offset (never overlaps with 'len') |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
932 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
933 // Arguments are reversed on java expression stack |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
934 // Calculate address of start element |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
935 if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
936 __ movptr(buf, Address(rsp, 3*wordSize)); // long buf |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
937 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
938 __ addq(buf, off); // + offset |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
939 __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
940 } else { |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
941 __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
942 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
943 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
944 __ addq(buf, off); // + offset |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
945 __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
946 } |
12070
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
947 // Can now load 'len' since we're finished with 'off' |
afbe18ae0905
8022441: Bad code generated for certain interpreted CRC intrinsics, 2 cases
bharadwaj
parents:
11080
diff
changeset
|
948 __ movl(len, Address(rsp, wordSize)); // Length |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
949 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
950 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
951 // result in rax |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
952 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
953 // _areturn |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
954 __ pop(rdi); // get return address |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
955 __ mov(rsp, r13); // set sp to sender sp |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
956 __ jmp(rdi); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
957 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
958 // generate a vanilla native entry as the slow path |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
959 __ bind(slow_path); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
960 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
961 (void) generate_native_entry(false); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
962 |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
963 return entry; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
964 } |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
965 return generate_native_entry(false); |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
966 } |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
967 |
0 | 968 // Interpreter stub for calling a native method. (asm interpreter) |
969 // This sets up a somewhat different looking stack for calling the | |
970 // native method than the typical interpreter frame setup. | |
971 address InterpreterGenerator::generate_native_entry(bool synchronized) { | |
972 // determine code generation flags | |
973 bool inc_counter = UseCompiler || CountCompiledCalls; | |
974 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
975 // rbx: Method* |
0 | 976 // r13: sender sp |
977 | |
978 address entry_point = __ pc(); | |
979 | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
980 const Address constMethod (rbx, Method::const_offset()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
981 const Address access_flags (rbx, Method::access_flags_offset()); |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
982 const Address size_of_parameters(rcx, ConstMethod:: |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
983 size_of_parameters_offset()); |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
984 |
0 | 985 |
986 // get parameter size (always needed) | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
987 __ movptr(rcx, constMethod); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
988 __ load_unsigned_short(rcx, size_of_parameters); |
0 | 989 |
990 // native calls don't need the stack size check since they have no | |
991 // expression stack and the arguments are already on the stack and | |
992 // we only add a handful of words to the stack | |
993 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
994 // rbx: Method* |
0 | 995 // rcx: size of parameters |
996 // r13: sender sp | |
304 | 997 __ pop(rax); // get return address |
0 | 998 |
999 // for natives the size of locals is zero | |
1000 | |
1001 // compute beginning of parameters (r14) | |
304 | 1002 __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); |
0 | 1003 |
1004 // add 2 zero-initialized slots for native calls | |
1005 // initialize result_handler slot | |
304 | 1006 __ push((int) NULL_WORD); |
0 | 1007 // slot for oop temp |
1008 // (static native method holder mirror/jni oop result) | |
304 | 1009 __ push((int) NULL_WORD); |
0 | 1010 |
1011 // initialize fixed part of activation frame | |
1012 generate_fixed_frame(true); | |
1013 | |
1014 // make sure method is native & not abstract | |
1015 #ifdef ASSERT | |
1016 __ movl(rax, access_flags); | |
1017 { | |
1018 Label L; | |
1019 __ testl(rax, JVM_ACC_NATIVE); | |
1020 __ jcc(Assembler::notZero, L); | |
1021 __ stop("tried to execute non-native method as native"); | |
1022 __ bind(L); | |
1023 } | |
1024 { | |
1025 Label L; | |
1026 __ testl(rax, JVM_ACC_ABSTRACT); | |
1027 __ jcc(Assembler::zero, L); | |
1028 __ stop("tried to execute abstract method in interpreter"); | |
1029 __ bind(L); | |
1030 } | |
1031 #endif | |
1032 | |
1033 // Since at this point in the method invocation the exception handler | |
1034 // would try to exit the monitor of synchronized methods which hasn't | |
1035 // been entered yet, we set the thread local variable | |
1036 // _do_not_unlock_if_synchronized to true. The remove_activation will | |
1037 // check this flag. | |
1038 | |
1039 const Address do_not_unlock_if_synchronized(r15_thread, | |
1040 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); | |
1041 __ movbool(do_not_unlock_if_synchronized, true); | |
1042 | |
1043 // increment invocation count & check for overflow | |
1044 Label invocation_counter_overflow; | |
1045 if (inc_counter) { | |
1046 generate_counter_incr(&invocation_counter_overflow, NULL, NULL); | |
1047 } | |
1048 | |
1049 Label continue_after_compile; | |
1050 __ bind(continue_after_compile); | |
1051 | |
1052 bang_stack_shadow_pages(true); | |
1053 | |
1054 // reset the _do_not_unlock_if_synchronized flag | |
1055 __ movbool(do_not_unlock_if_synchronized, false); | |
1056 | |
1057 // check for synchronized methods | |
1058 // Must happen AFTER invocation_counter check and stack overflow check, | |
1059 // so method is not locked if overflows. | |
1060 if (synchronized) { | |
1061 lock_method(); | |
1062 } else { | |
1063 // no synchronization necessary | |
1064 #ifdef ASSERT | |
1065 { | |
1066 Label L; | |
1067 __ movl(rax, access_flags); | |
1068 __ testl(rax, JVM_ACC_SYNCHRONIZED); | |
1069 __ jcc(Assembler::zero, L); | |
1070 __ stop("method needs synchronization"); | |
1071 __ bind(L); | |
1072 } | |
1073 #endif | |
1074 } | |
1075 | |
1076 // start execution | |
1077 #ifdef ASSERT | |
1078 { | |
1079 Label L; | |
1080 const Address monitor_block_top(rbp, | |
1081 frame::interpreter_frame_monitor_block_top_offset * wordSize); | |
304 | 1082 __ movptr(rax, monitor_block_top); |
1083 __ cmpptr(rax, rsp); | |
0 | 1084 __ jcc(Assembler::equal, L); |
1085 __ stop("broken stack frame setup in interpreter"); | |
1086 __ bind(L); | |
1087 } | |
1088 #endif | |
1089 | |
1090 // jvmti support | |
1091 __ notify_method_entry(); | |
1092 | |
1093 // work registers | |
1094 const Register method = rbx; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1095 const Register t = r11; |
0 | 1096 |
1097 // allocate space for parameters | |
1098 __ get_method(method); | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1099 __ movptr(t, Address(method, Method::const_offset())); |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1100 __ load_unsigned_short(t, Address(t, ConstMethod::size_of_parameters_offset())); |
1506 | 1101 __ shll(t, Interpreter::logStackElementSize); |
0 | 1102 |
304 | 1103 __ subptr(rsp, t); |
1104 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | |
605 | 1105 __ andptr(rsp, -16); // must be 16 byte boundary (see amd64 ABI) |
0 | 1106 |
1107 // get signature handler | |
1108 { | |
1109 Label L; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1110 __ movptr(t, Address(method, Method::signature_handler_offset())); |
304 | 1111 __ testptr(t, t); |
0 | 1112 __ jcc(Assembler::notZero, L); |
1113 __ call_VM(noreg, | |
1114 CAST_FROM_FN_PTR(address, | |
1115 InterpreterRuntime::prepare_native_call), | |
1116 method); | |
1117 __ get_method(method); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1118 __ movptr(t, Address(method, Method::signature_handler_offset())); |
0 | 1119 __ bind(L); |
1120 } | |
1121 | |
1122 // call signature handler | |
1123 assert(InterpreterRuntime::SignatureHandlerGenerator::from() == r14, | |
1124 "adjust this code"); | |
1125 assert(InterpreterRuntime::SignatureHandlerGenerator::to() == rsp, | |
1126 "adjust this code"); | |
1127 assert(InterpreterRuntime::SignatureHandlerGenerator::temp() == rscratch1, | |
1128 "adjust this code"); | |
1129 | |
1130 // The generated handlers do not touch RBX (the method oop). | |
1131 // However, large signatures cannot be cached and are generated | |
1132 // each time here. The slow-path generator can do a GC on return, | |
1133 // so we must reload it after the call. | |
1134 __ call(t); | |
1135 __ get_method(method); // slow path can do a GC, reload RBX | |
1136 | |
1137 | |
1138 // result handler is in rax | |
1139 // set result handler | |
304 | 1140 __ movptr(Address(rbp, |
1141 (frame::interpreter_frame_result_handler_offset) * wordSize), | |
1142 rax); | |
0 | 1143 |
1144 // pass mirror handle if static call | |
1145 { | |
1146 Label L; | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
4042
diff
changeset
|
1147 const int mirror_offset = in_bytes(Klass::java_mirror_offset()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1148 __ movl(t, Address(method, Method::access_flags_offset())); |
0 | 1149 __ testl(t, JVM_ACC_STATIC); |
1150 __ jcc(Assembler::zero, L); | |
1151 // get mirror | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1152 __ movptr(t, Address(method, Method::const_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1153 __ movptr(t, Address(t, ConstMethod::constants_offset())); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1154 __ movptr(t, Address(t, ConstantPool::pool_holder_offset_in_bytes())); |
304 | 1155 __ movptr(t, Address(t, mirror_offset)); |
0 | 1156 // copy mirror into activation frame |
304 | 1157 __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize), |
0 | 1158 t); |
1159 // pass handle to mirror | |
304 | 1160 __ lea(c_rarg1, |
1161 Address(rbp, frame::interpreter_frame_oop_temp_offset * wordSize)); | |
0 | 1162 __ bind(L); |
1163 } | |
1164 | |
1165 // get native function entry point | |
1166 { | |
1167 Label L; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1168 __ movptr(rax, Address(method, Method::native_function_offset())); |
0 | 1169 ExternalAddress unsatisfied(SharedRuntime::native_method_throw_unsatisfied_link_error_entry()); |
1170 __ movptr(rscratch2, unsatisfied.addr()); | |
304 | 1171 __ cmpptr(rax, rscratch2); |
0 | 1172 __ jcc(Assembler::notEqual, L); |
1173 __ call_VM(noreg, | |
1174 CAST_FROM_FN_PTR(address, | |
1175 InterpreterRuntime::prepare_native_call), | |
1176 method); | |
1177 __ get_method(method); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1178 __ movptr(rax, Address(method, Method::native_function_offset())); |
0 | 1179 __ bind(L); |
1180 } | |
1181 | |
1182 // pass JNIEnv | |
304 | 1183 __ lea(c_rarg0, Address(r15_thread, JavaThread::jni_environment_offset())); |
0 | 1184 |
1185 // It is enough that the pc() points into the right code | |
1186 // segment. It does not have to be the correct return pc. | |
1187 __ set_last_Java_frame(rsp, rbp, (address) __ pc()); | |
1188 | |
1189 // change thread state | |
1190 #ifdef ASSERT | |
1191 { | |
1192 Label L; | |
1193 __ movl(t, Address(r15_thread, JavaThread::thread_state_offset())); | |
1194 __ cmpl(t, _thread_in_Java); | |
1195 __ jcc(Assembler::equal, L); | |
1196 __ stop("Wrong thread state in native stub"); | |
1197 __ bind(L); | |
1198 } | |
1199 #endif | |
1200 | |
1201 // Change state to native | |
1202 | |
1203 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), | |
1204 _thread_in_native); | |
1205 | |
1206 // Call the native method. | |
1207 __ call(rax); | |
1208 // result potentially in rax or xmm0 | |
1209 | |
8873
e961c11b85fe
8011102: Clear AVX registers after return from JNI call
kvn
parents:
8727
diff
changeset
|
1210 // Verify or restore cpu control state after JNI call |
e961c11b85fe
8011102: Clear AVX registers after return from JNI call
kvn
parents:
8727
diff
changeset
|
1211 __ restore_cpu_control_state_after_jni(); |
0 | 1212 |
1213 // NOTE: The order of these pushes is known to frame::interpreter_frame_result | |
1214 // in order to extract the result of a method call. If the order of these | |
1215 // pushes change or anything else is added to the stack then the code in | |
1216 // interpreter_frame_result must also change. | |
1217 | |
1218 __ push(dtos); | |
1219 __ push(ltos); | |
1220 | |
1221 // change thread state | |
1222 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), | |
1223 _thread_in_native_trans); | |
1224 | |
1225 if (os::is_MP()) { | |
1226 if (UseMembar) { | |
1227 // Force this write out before the read below | |
1228 __ membar(Assembler::Membar_mask_bits( | |
1229 Assembler::LoadLoad | Assembler::LoadStore | | |
1230 Assembler::StoreLoad | Assembler::StoreStore)); | |
1231 } else { | |
1232 // Write serialization page so VM thread can do a pseudo remote membar. | |
1233 // We use the current thread pointer to calculate a thread specific | |
1234 // offset to write to within the page. This minimizes bus traffic | |
1235 // due to cache line collision. | |
1236 __ serialize_memory(r15_thread, rscratch2); | |
1237 } | |
1238 } | |
1239 | |
1240 // check for safepoint operation in progress and/or pending suspend requests | |
1241 { | |
1242 Label Continue; | |
1243 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), | |
1244 SafepointSynchronize::_not_synchronized); | |
1245 | |
1246 Label L; | |
1247 __ jcc(Assembler::notEqual, L); | |
1248 __ cmpl(Address(r15_thread, JavaThread::suspend_flags_offset()), 0); | |
1249 __ jcc(Assembler::equal, Continue); | |
1250 __ bind(L); | |
1251 | |
1252 // Don't use call_VM as it will see a possible pending exception | |
1253 // and forward it and never return here preventing us from | |
1254 // clearing _last_native_pc down below. Also can't use | |
1255 // call_VM_leaf either as it will check to see if r13 & r14 are | |
1256 // preserved and correspond to the bcp/locals pointers. So we do a | |
1257 // runtime call by hand. | |
1258 // | |
304 | 1259 __ mov(c_rarg0, r15_thread); |
1976
0fc262af204f
6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops
coleenp
parents:
1972
diff
changeset
|
1260 __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) |
304 | 1261 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
1262 __ andptr(rsp, -16); // align stack as required by ABI | |
0 | 1263 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); |
304 | 1264 __ mov(rsp, r12); // restore sp |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1265 __ reinit_heapbase(); |
0 | 1266 __ bind(Continue); |
1267 } | |
1268 | |
1269 // change thread state | |
1270 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); | |
1271 | |
1272 // reset_last_Java_frame | |
1273 __ reset_last_Java_frame(true, true); | |
1274 | |
1275 // reset handle block | |
304 | 1276 __ movptr(t, Address(r15_thread, JavaThread::active_handles_offset())); |
1277 __ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); | |
0 | 1278 |
1279 // If result is an oop unbox and store it in frame where gc will see it | |
1280 // and result handler will pick it up | |
1281 | |
1282 { | |
1283 Label no_oop, store_result; | |
1284 __ lea(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT))); | |
304 | 1285 __ cmpptr(t, Address(rbp, frame::interpreter_frame_result_handler_offset*wordSize)); |
0 | 1286 __ jcc(Assembler::notEqual, no_oop); |
1287 // retrieve result | |
1288 __ pop(ltos); | |
304 | 1289 __ testptr(rax, rax); |
0 | 1290 __ jcc(Assembler::zero, store_result); |
304 | 1291 __ movptr(rax, Address(rax, 0)); |
0 | 1292 __ bind(store_result); |
304 | 1293 __ movptr(Address(rbp, frame::interpreter_frame_oop_temp_offset*wordSize), rax); |
0 | 1294 // keep stack depth as expected by pushing oop which will eventually be discarde |
1295 __ push(ltos); | |
1296 __ bind(no_oop); | |
1297 } | |
1298 | |
1299 | |
1300 { | |
1301 Label no_reguard; | |
1302 __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), | |
1303 JavaThread::stack_guard_yellow_disabled); | |
1304 __ jcc(Assembler::notEqual, no_reguard); | |
1305 | |
304 | 1306 __ pusha(); // XXX only save smashed registers |
1976
0fc262af204f
6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops
coleenp
parents:
1972
diff
changeset
|
1307 __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) |
304 | 1308 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
1309 __ andptr(rsp, -16); // align stack as required by ABI | |
0 | 1310 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); |
304 | 1311 __ mov(rsp, r12); // restore sp |
1312 __ popa(); // XXX only restore smashed registers | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1313 __ reinit_heapbase(); |
0 | 1314 |
1315 __ bind(no_reguard); | |
1316 } | |
1317 | |
1318 | |
1319 // The method register is junk from after the thread_in_native transition | |
1320 // until here. Also can't call_VM until the bcp has been | |
1321 // restored. Need bcp for throwing exception below so get it now. | |
1322 __ get_method(method); | |
1323 | |
1324 // restore r13 to have legal interpreter frame, i.e., bci == 0 <=> | |
1325 // r13 == code_base() | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1326 __ movptr(r13, Address(method, Method::const_offset())); // get ConstMethod* |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1327 __ lea(r13, Address(r13, ConstMethod::codes_offset())); // get codebase |
0 | 1328 // handle exceptions (exception handling will handle unlocking!) |
1329 { | |
1330 Label L; | |
304 | 1331 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL_WORD); |
0 | 1332 __ jcc(Assembler::zero, L); |
1333 // Note: At some point we may want to unify this with the code | |
1334 // used in call_VM_base(); i.e., we should use the | |
1335 // StubRoutines::forward_exception code. For now this doesn't work | |
1336 // here because the rsp is not correctly set at this point. | |
1337 __ MacroAssembler::call_VM(noreg, | |
1338 CAST_FROM_FN_PTR(address, | |
1339 InterpreterRuntime::throw_pending_exception)); | |
1340 __ should_not_reach_here(); | |
1341 __ bind(L); | |
1342 } | |
1343 | |
1344 // do unlocking if necessary | |
1345 { | |
1346 Label L; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1347 __ movl(t, Address(method, Method::access_flags_offset())); |
0 | 1348 __ testl(t, JVM_ACC_SYNCHRONIZED); |
1349 __ jcc(Assembler::zero, L); | |
1350 // the code below should be shared with interpreter macro | |
1351 // assembler implementation | |
1352 { | |
1353 Label unlock; | |
1354 // BasicObjectLock will be first in list, since this is a | |
1355 // synchronized method. However, need to check that the object | |
1356 // has not been unlocked by an explicit monitorexit bytecode. | |
1357 const Address monitor(rbp, | |
1358 (intptr_t)(frame::interpreter_frame_initial_sp_offset * | |
1359 wordSize - sizeof(BasicObjectLock))); | |
1360 | |
1361 // monitor expect in c_rarg1 for slow unlock path | |
304 | 1362 __ lea(c_rarg1, monitor); // address of first monitor |
0 | 1363 |
304 | 1364 __ movptr(t, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); |
1365 __ testptr(t, t); | |
0 | 1366 __ jcc(Assembler::notZero, unlock); |
1367 | |
1368 // Entry already unlocked, need to throw exception | |
1369 __ MacroAssembler::call_VM(noreg, | |
1370 CAST_FROM_FN_PTR(address, | |
1371 InterpreterRuntime::throw_illegal_monitor_state_exception)); | |
1372 __ should_not_reach_here(); | |
1373 | |
1374 __ bind(unlock); | |
1375 __ unlock_object(c_rarg1); | |
1376 } | |
1377 __ bind(L); | |
1378 } | |
1379 | |
1380 // jvmti support | |
1381 // Note: This must happen _after_ handling/throwing any exceptions since | |
1382 // the exception handler code notifies the runtime of method exits | |
1383 // too. If this happens before, method entry/exit notifications are | |
1384 // not properly paired (was bug - gri 11/22/99). | |
1385 __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI); | |
1386 | |
1387 // restore potential result in edx:eax, call result handler to | |
1388 // restore potential result in ST0 & handle result | |
1389 | |
1390 __ pop(ltos); | |
1391 __ pop(dtos); | |
1392 | |
304 | 1393 __ movptr(t, Address(rbp, |
1394 (frame::interpreter_frame_result_handler_offset) * wordSize)); | |
0 | 1395 __ call(t); |
1396 | |
1397 // remove activation | |
304 | 1398 __ movptr(t, Address(rbp, |
1399 frame::interpreter_frame_sender_sp_offset * | |
1400 wordSize)); // get sender sp | |
0 | 1401 __ leave(); // remove frame anchor |
304 | 1402 __ pop(rdi); // get return address |
1403 __ mov(rsp, t); // set sp to sender sp | |
0 | 1404 __ jmp(rdi); |
1405 | |
1406 if (inc_counter) { | |
1407 // Handle overflow of counter and compile method | |
1408 __ bind(invocation_counter_overflow); | |
1409 generate_counter_overflow(&continue_after_compile); | |
1410 } | |
1411 | |
1412 return entry_point; | |
1413 } | |
1414 | |
1415 // | |
1416 // Generic interpreted method entry to (asm) interpreter | |
1417 // | |
1418 address InterpreterGenerator::generate_normal_entry(bool synchronized) { | |
1419 // determine code generation flags | |
1420 bool inc_counter = UseCompiler || CountCompiledCalls; | |
1421 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1422 // ebx: Method* |
0 | 1423 // r13: sender sp |
1424 address entry_point = __ pc(); | |
1425 | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1426 const Address constMethod(rbx, Method::const_offset()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1427 const Address access_flags(rbx, Method::access_flags_offset()); |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1428 const Address size_of_parameters(rdx, |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1429 ConstMethod::size_of_parameters_offset()); |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1430 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1431 |
0 | 1432 |
1433 // get parameter size (always needed) | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1434 __ movptr(rdx, constMethod); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
1435 __ load_unsigned_short(rcx, size_of_parameters); |
0 | 1436 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1437 // rbx: Method* |
0 | 1438 // rcx: size of parameters |
1439 // r13: sender_sp (could differ from sp+wordSize if we were called via c2i ) | |
1440 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
1441 __ load_unsigned_short(rdx, size_of_locals); // get size of locals in words |
0 | 1442 __ subl(rdx, rcx); // rdx = no. of additional locals |
1443 | |
1444 // YYY | |
1445 // __ incrementl(rdx); | |
1446 // __ andl(rdx, -2); | |
1447 | |
1448 // see if we've got enough room on the stack for locals plus overhead. | |
1449 generate_stack_overflow_check(); | |
1450 | |
1451 // get return address | |
304 | 1452 __ pop(rax); |
0 | 1453 |
1454 // compute beginning of parameters (r14) | |
304 | 1455 __ lea(r14, Address(rsp, rcx, Address::times_8, -wordSize)); |
0 | 1456 |
1457 // rdx - # of additional locals | |
1458 // allocate space for locals | |
1459 // explicitly initialize locals | |
1460 { | |
1461 Label exit, loop; | |
1462 __ testl(rdx, rdx); | |
1463 __ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0 | |
1464 __ bind(loop); | |
304 | 1465 __ push((int) NULL_WORD); // initialize local variables |
0 | 1466 __ decrementl(rdx); // until everything initialized |
1467 __ jcc(Assembler::greater, loop); | |
1468 __ bind(exit); | |
1469 } | |
1470 | |
1471 // initialize fixed part of activation frame | |
1472 generate_fixed_frame(false); | |
1473 | |
1474 // make sure method is not native & not abstract | |
1475 #ifdef ASSERT | |
1476 __ movl(rax, access_flags); | |
1477 { | |
1478 Label L; | |
1479 __ testl(rax, JVM_ACC_NATIVE); | |
1480 __ jcc(Assembler::zero, L); | |
1481 __ stop("tried to execute native method as non-native"); | |
1482 __ bind(L); | |
1483 } | |
1484 { | |
1485 Label L; | |
1486 __ testl(rax, JVM_ACC_ABSTRACT); | |
1487 __ jcc(Assembler::zero, L); | |
1488 __ stop("tried to execute abstract method in interpreter"); | |
1489 __ bind(L); | |
1490 } | |
1491 #endif | |
1492 | |
1493 // Since at this point in the method invocation the exception | |
1494 // handler would try to exit the monitor of synchronized methods | |
1495 // which hasn't been entered yet, we set the thread local variable | |
1496 // _do_not_unlock_if_synchronized to true. The remove_activation | |
1497 // will check this flag. | |
1498 | |
1499 const Address do_not_unlock_if_synchronized(r15_thread, | |
1500 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); | |
1501 __ movbool(do_not_unlock_if_synchronized, true); | |
1502 | |
12962
5ccbab1c69f3
8026251: New type profiling points: parameters to methods
roland
parents:
12882
diff
changeset
|
1503 __ profile_parameters_type(rax, rcx, rdx); |
0 | 1504 // increment invocation count & check for overflow |
1505 Label invocation_counter_overflow; | |
1506 Label profile_method; | |
1507 Label profile_method_continue; | |
1508 if (inc_counter) { | |
1509 generate_counter_incr(&invocation_counter_overflow, | |
1510 &profile_method, | |
1511 &profile_method_continue); | |
1512 if (ProfileInterpreter) { | |
1513 __ bind(profile_method_continue); | |
1514 } | |
1515 } | |
1516 | |
1517 Label continue_after_compile; | |
1518 __ bind(continue_after_compile); | |
1519 | |
1520 // check for synchronized interpreted methods | |
1521 bang_stack_shadow_pages(false); | |
1522 | |
1523 // reset the _do_not_unlock_if_synchronized flag | |
1524 __ movbool(do_not_unlock_if_synchronized, false); | |
1525 | |
1526 // check for synchronized methods | |
1527 // Must happen AFTER invocation_counter check and stack overflow check, | |
1528 // so method is not locked if overflows. | |
1529 if (synchronized) { | |
1530 // Allocate monitor and lock method | |
1531 lock_method(); | |
1532 } else { | |
1533 // no synchronization necessary | |
1534 #ifdef ASSERT | |
1535 { | |
1536 Label L; | |
1537 __ movl(rax, access_flags); | |
1538 __ testl(rax, JVM_ACC_SYNCHRONIZED); | |
1539 __ jcc(Assembler::zero, L); | |
1540 __ stop("method needs synchronization"); | |
1541 __ bind(L); | |
1542 } | |
1543 #endif | |
1544 } | |
1545 | |
1546 // start execution | |
1547 #ifdef ASSERT | |
1548 { | |
1549 Label L; | |
1550 const Address monitor_block_top (rbp, | |
1551 frame::interpreter_frame_monitor_block_top_offset * wordSize); | |
304 | 1552 __ movptr(rax, monitor_block_top); |
1553 __ cmpptr(rax, rsp); | |
0 | 1554 __ jcc(Assembler::equal, L); |
1555 __ stop("broken stack frame setup in interpreter"); | |
1556 __ bind(L); | |
1557 } | |
1558 #endif | |
1559 | |
1560 // jvmti support | |
1561 __ notify_method_entry(); | |
1562 | |
1563 __ dispatch_next(vtos); | |
1564 | |
1565 // invocation counter overflow | |
1566 if (inc_counter) { | |
1567 if (ProfileInterpreter) { | |
1568 // We have decided to profile this method in the interpreter | |
1569 __ bind(profile_method); | |
2118
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1976
diff
changeset
|
1570 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method)); |
dd031b2226de
4930919: race condition in MDO creation at back branch locations
iveresov
parents:
1976
diff
changeset
|
1571 __ set_method_data_pointer_for_bcp(); |
2141
b599a4c6c2df
7012766: assert(false) failed: DEBUG MESSAGE in MacroAssembler::debug32
iveresov
parents:
2118
diff
changeset
|
1572 __ get_method(rbx); |
0 | 1573 __ jmp(profile_method_continue); |
1574 } | |
1575 // Handle overflow of counter and compile method | |
1576 __ bind(invocation_counter_overflow); | |
1577 generate_counter_overflow(&continue_after_compile); | |
1578 } | |
1579 | |
1580 return entry_point; | |
1581 } | |
1582 | |
1583 // Entry points | |
1584 // | |
1585 // Here we generate the various kind of entries into the interpreter. | |
1586 // The two main entry type are generic bytecode methods and native | |
1587 // call method. These both come in synchronized and non-synchronized | |
1588 // versions but the frame layout they create is very similar. The | |
1589 // other method entry types are really just special purpose entries | |
1590 // that are really entry and interpretation all in one. These are for | |
1591 // trivial methods like accessor, empty, or special math methods. | |
1592 // | |
1593 // When control flow reaches any of the entry types for the interpreter | |
1594 // the following holds -> | |
1595 // | |
1596 // Arguments: | |
1597 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1598 // rbx: Method* |
0 | 1599 // |
1600 // Stack layout immediately at entry | |
1601 // | |
1602 // [ return address ] <--- rsp | |
1603 // [ parameter n ] | |
1604 // ... | |
1605 // [ parameter 1 ] | |
1606 // [ expression stack ] (caller's java expression stack) | |
1607 | |
1608 // Assuming that we don't go to one of the trivial specialized entries | |
1609 // the stack will look like below when we are ready to execute the | |
1610 // first bytecode (or call the native routine). The register usage | |
1611 // will be as the template based interpreter expects (see | |
1612 // interpreter_amd64.hpp). | |
1613 // | |
1614 // local variables follow incoming parameters immediately; i.e. | |
1615 // the return address is moved to the end of the locals). | |
1616 // | |
1617 // [ monitor entry ] <--- rsp | |
1618 // ... | |
1619 // [ monitor entry ] | |
1620 // [ expr. stack bottom ] | |
1621 // [ saved r13 ] | |
1622 // [ current r14 ] | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1623 // [ Method* ] |
0 | 1624 // [ saved ebp ] <--- rbp |
1625 // [ return address ] | |
1626 // [ local variable m ] | |
1627 // ... | |
1628 // [ local variable 1 ] | |
1629 // [ parameter n ] | |
1630 // ... | |
1631 // [ parameter 1 ] <--- r14 | |
1632 | |
1633 address AbstractInterpreterGenerator::generate_method_entry( | |
1634 AbstractInterpreter::MethodKind kind) { | |
1635 // determine code generation flags | |
1636 bool synchronized = false; | |
1637 address entry_point = NULL; | |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1638 InterpreterGenerator* ig_this = (InterpreterGenerator*)this; |
0 | 1639 |
1640 switch (kind) { | |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1641 case Interpreter::zerolocals : break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1642 case Interpreter::zerolocals_synchronized: synchronized = true; break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1643 case Interpreter::native : entry_point = ig_this->generate_native_entry(false); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1644 case Interpreter::native_synchronized : entry_point = ig_this->generate_native_entry(true); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1645 case Interpreter::empty : entry_point = ig_this->generate_empty_entry(); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1646 case Interpreter::accessor : entry_point = ig_this->generate_accessor_entry(); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1647 case Interpreter::abstract : entry_point = ig_this->generate_abstract_entry(); break; |
706
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1648 |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1649 case Interpreter::java_lang_math_sin : // fall thru |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1650 case Interpreter::java_lang_math_cos : // fall thru |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1651 case Interpreter::java_lang_math_tan : // fall thru |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1652 case Interpreter::java_lang_math_abs : // fall thru |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1653 case Interpreter::java_lang_math_log : // fall thru |
819880572f09
6539464: Math.log() produces inconsistent results between successive runs.
never
parents:
622
diff
changeset
|
1654 case Interpreter::java_lang_math_log10 : // fall thru |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4771
diff
changeset
|
1655 case Interpreter::java_lang_math_sqrt : // fall thru |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4771
diff
changeset
|
1656 case Interpreter::java_lang_math_pow : // fall thru |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1657 case Interpreter::java_lang_math_exp : entry_point = ig_this->generate_math_entry(kind); break; |
3249
e1162778c1c8
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents:
2245
diff
changeset
|
1658 case Interpreter::java_lang_ref_reference_get |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1659 : entry_point = ig_this->generate_Reference_get_entry(); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1660 case Interpreter::java_util_zip_CRC32_update |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1661 : entry_point = ig_this->generate_CRC32_update_entry(); break; |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1662 case Interpreter::java_util_zip_CRC32_updateBytes |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1663 : // fall thru |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1664 case Interpreter::java_util_zip_CRC32_updateByteBuffer |
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1665 : entry_point = ig_this->generate_CRC32_updateBytes_entry(kind); break; |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
1666 default: |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
1667 fatal(err_msg("unexpected method kind: %d", kind)); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
6123
diff
changeset
|
1668 break; |
0 | 1669 } |
1670 | |
1671 if (entry_point) { | |
1672 return entry_point; | |
1673 } | |
1674 | |
11080
b800986664f4
7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents:
10393
diff
changeset
|
1675 return ig_this->generate_normal_entry(synchronized); |
0 | 1676 } |
1677 | |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1678 // These should never be compiled since the interpreter will prefer |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1679 // the compiled version to the intrinsic version. |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1680 bool AbstractInterpreter::can_be_compiled(methodHandle m) { |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1681 switch (method_kind(m)) { |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1682 case Interpreter::java_lang_math_sin : // fall thru |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1683 case Interpreter::java_lang_math_cos : // fall thru |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1684 case Interpreter::java_lang_math_tan : // fall thru |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1685 case Interpreter::java_lang_math_abs : // fall thru |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1686 case Interpreter::java_lang_math_log : // fall thru |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1687 case Interpreter::java_lang_math_log10 : // fall thru |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4771
diff
changeset
|
1688 case Interpreter::java_lang_math_sqrt : // fall thru |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4771
diff
changeset
|
1689 case Interpreter::java_lang_math_pow : // fall thru |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
4771
diff
changeset
|
1690 case Interpreter::java_lang_math_exp : |
1174
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1691 return false; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1692 default: |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1693 return true; |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1694 } |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1695 } |
ddb7834449d0
6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents:
1135
diff
changeset
|
1696 |
0 | 1697 // How much stack a method activation needs in words. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1698 int AbstractInterpreter::size_top_interpreter_activation(Method* method) { |
0 | 1699 const int entry_size = frame::interpreter_frame_monitor_size(); |
1700 | |
1701 // total overhead size: entry_size + (saved rbp thru expr stack | |
1702 // bottom). be sure to change this if you add/subtract anything | |
1703 // to/from the overhead area | |
1704 const int overhead_size = | |
1705 -(frame::interpreter_frame_initial_sp_offset) + entry_size; | |
1706 | |
1707 const int stub_code = frame::entry_frame_after_call_words; | |
10393
603ca7e51354
8010460: Interpreter on some platforms loads ConstMethod::_max_stack and misses extra stack slots for JSR 292
roland
parents:
10141
diff
changeset
|
1708 const int method_stack = (method->max_locals() + method->max_stack()) * |
1506 | 1709 Interpreter::stackElementWords; |
0 | 1710 return (overhead_size + method_stack + stub_code); |
1711 } | |
1712 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1713 int AbstractInterpreter::layout_activation(Method* method, |
0 | 1714 int tempcount, |
1715 int popframe_extra_args, | |
1716 int moncount, | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3252
diff
changeset
|
1717 int caller_actual_parameters, |
0 | 1718 int callee_param_count, |
1719 int callee_locals, | |
1720 frame* caller, | |
1721 frame* interpreter_frame, | |
8727
0094485b46c7
8009761: Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
roland
parents:
8001
diff
changeset
|
1722 bool is_top_frame, |
0094485b46c7
8009761: Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates
roland
parents:
8001
diff
changeset
|
1723 bool is_bottom_frame) { |
0 | 1724 // Note: This calculation must exactly parallel the frame setup |
1725 // in AbstractInterpreterGenerator::generate_method_entry. | |
1726 // If interpreter_frame!=NULL, set up the method, locals, and monitors. | |
1727 // The frame interpreter_frame, if not NULL, is guaranteed to be the | |
1728 // right size, as determined by a previous call to this method. | |
1729 // It is also guaranteed to be walkable even though it is in a skeletal state | |
1730 | |
1731 // fixed size of an interpreter frame: | |
1506 | 1732 int max_locals = method->max_locals() * Interpreter::stackElementWords; |
0 | 1733 int extra_locals = (method->max_locals() - method->size_of_parameters()) * |
1506 | 1734 Interpreter::stackElementWords; |
0 | 1735 |
1736 int overhead = frame::sender_sp_offset - | |
1737 frame::interpreter_frame_initial_sp_offset; | |
1738 // Our locals were accounted for by the caller (or last_frame_adjust | |
1739 // on the transistion) Since the callee parameters already account | |
1740 // for the callee's params we only need to account for the extra | |
1741 // locals. | |
1742 int size = overhead + | |
1506 | 1743 (callee_locals - callee_param_count)*Interpreter::stackElementWords + |
0 | 1744 moncount * frame::interpreter_frame_monitor_size() + |
1506 | 1745 tempcount* Interpreter::stackElementWords + popframe_extra_args; |
0 | 1746 if (interpreter_frame != NULL) { |
1747 #ifdef ASSERT | |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2245
diff
changeset
|
1748 if (!EnableInvokeDynamic) |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
1749 // @@@ FIXME: Should we correct interpreter_frame_sender_sp in the calling sequences? |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
1750 // Probably, since deoptimization doesn't work yet. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1108
diff
changeset
|
1751 assert(caller->unextended_sp() == interpreter_frame->interpreter_frame_sender_sp(), "Frame not properly walkable"); |
0 | 1752 assert(caller->sp() == interpreter_frame->sender_sp(), "Frame not properly walkable(2)"); |
1753 #endif | |
1754 | |
1755 interpreter_frame->interpreter_frame_set_method(method); | |
1756 // NOTE the difference in using sender_sp and | |
1757 // interpreter_frame_sender_sp interpreter_frame_sender_sp is | |
1758 // the original sp of the caller (the unextended_sp) and | |
1759 // sender_sp is fp+16 XXX | |
1760 intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; | |
1761 | |
4042
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1762 #ifdef ASSERT |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1763 if (caller->is_interpreted_frame()) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1764 assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1765 } |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1766 #endif |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3451
diff
changeset
|
1767 |
0 | 1768 interpreter_frame->interpreter_frame_set_locals(locals); |
1769 BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); | |
1770 BasicObjectLock* monbot = montop - moncount; | |
1771 interpreter_frame->interpreter_frame_set_monitor_end(monbot); | |
1772 | |
1773 // Set last_sp | |
1774 intptr_t* esp = (intptr_t*) monbot - | |
1506 | 1775 tempcount*Interpreter::stackElementWords - |
0 | 1776 popframe_extra_args; |
1777 interpreter_frame->interpreter_frame_set_last_sp(esp); | |
1778 | |
1779 // All frames but the initial (oldest) interpreter frame we fill in have | |
1780 // a value for sender_sp that allows walking the stack but isn't | |
1781 // truly correct. Correct the value here. | |
1782 if (extra_locals != 0 && | |
1783 interpreter_frame->sender_sp() == | |
1784 interpreter_frame->interpreter_frame_sender_sp()) { | |
1785 interpreter_frame->set_interpreter_frame_sender_sp(caller->sp() + | |
1786 extra_locals); | |
1787 } | |
1788 *interpreter_frame->interpreter_frame_cache_addr() = | |
1789 method->constants()->cache(); | |
1790 } | |
1791 return size; | |
1792 } | |
1793 | |
1794 //----------------------------------------------------------------------------- | |
1795 // Exceptions | |
1796 | |
1797 void TemplateInterpreterGenerator::generate_throw_exception() { | |
1798 // Entry point in previous activation (i.e., if the caller was | |
1799 // interpreted) | |
1800 Interpreter::_rethrow_exception_entry = __ pc(); | |
1801 // Restore sp to interpreter_frame_last_sp even though we are going | |
1802 // to empty the expression stack for the exception processing. | |
304 | 1803 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
0 | 1804 // rax: exception |
1805 // rdx: return address/pc that threw exception | |
1806 __ restore_bcp(); // r13 points to call/send | |
1807 __ restore_locals(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1808 __ reinit_heapbase(); // restore r12 as heapbase. |
0 | 1809 // Entry point for exceptions thrown within interpreter code |
1810 Interpreter::_throw_exception_entry = __ pc(); | |
1811 // expression stack is undefined here | |
1812 // rax: exception | |
1813 // r13: exception bcp | |
1814 __ verify_oop(rax); | |
304 | 1815 __ mov(c_rarg1, rax); |
0 | 1816 |
1817 // expression stack must be empty before entering the VM in case of | |
1818 // an exception | |
1819 __ empty_expression_stack(); | |
1820 // find exception handler address and preserve exception oop | |
1821 __ call_VM(rdx, | |
1822 CAST_FROM_FN_PTR(address, | |
1823 InterpreterRuntime::exception_handler_for_exception), | |
1824 c_rarg1); | |
1825 // rax: exception handler entry point | |
1826 // rdx: preserved exception oop | |
1827 // r13: bcp for exception handler | |
1828 __ push_ptr(rdx); // push exception which is now the only value on the stack | |
1829 __ jmp(rax); // jump to exception handler (may be _remove_activation_entry!) | |
1830 | |
1831 // If the exception is not handled in the current frame the frame is | |
1832 // removed and the exception is rethrown (i.e. exception | |
1833 // continuation is _rethrow_exception). | |
1834 // | |
1835 // Note: At this point the bci is still the bxi for the instruction | |
1836 // which caused the exception and the expression stack is | |
1837 // empty. Thus, for any VM calls at this point, GC will find a legal | |
1838 // oop map (with empty expression stack). | |
1839 | |
1840 // In current activation | |
1841 // tos: exception | |
1842 // esi: exception bcp | |
1843 | |
1844 // | |
1845 // JVMTI PopFrame support | |
1846 // | |
1847 | |
1848 Interpreter::_remove_activation_preserving_args_entry = __ pc(); | |
1849 __ empty_expression_stack(); | |
1850 // Set the popframe_processing bit in pending_popframe_condition | |
1851 // indicating that we are currently handling popframe, so that | |
1852 // call_VMs that may happen later do not trigger new popframe | |
1853 // handling cycles. | |
1854 __ movl(rdx, Address(r15_thread, JavaThread::popframe_condition_offset())); | |
1855 __ orl(rdx, JavaThread::popframe_processing_bit); | |
1856 __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), rdx); | |
1857 | |
1858 { | |
1859 // Check to see whether we are returning to a deoptimized frame. | |
1860 // (The PopFrame call ensures that the caller of the popped frame is | |
1861 // either interpreted or compiled and deoptimizes it if compiled.) | |
1862 // In this case, we can't call dispatch_next() after the frame is | |
1863 // popped, but instead must save the incoming arguments and restore | |
1864 // them after deoptimization has occurred. | |
1865 // | |
1866 // Note that we don't compare the return PC against the | |
1867 // deoptimization blob's unpack entry because of the presence of | |
1868 // adapter frames in C2. | |
1869 Label caller_not_deoptimized; | |
304 | 1870 __ movptr(c_rarg1, Address(rbp, frame::return_addr_offset * wordSize)); |
0 | 1871 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, |
1872 InterpreterRuntime::interpreter_contains), c_rarg1); | |
1873 __ testl(rax, rax); | |
1874 __ jcc(Assembler::notZero, caller_not_deoptimized); | |
1875 | |
1876 // Compute size of arguments for saving when returning to | |
1877 // deoptimized caller | |
1878 __ get_method(rax); | |
7402
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1879 __ movptr(rax, Address(rax, Method::const_offset())); |
fd74228fd5ca
8004076: Move _max_locals and _size_of_parameters to ConstMethod for better sharing.
jiangli
parents:
7199
diff
changeset
|
1880 __ load_unsigned_short(rax, Address(rax, in_bytes(ConstMethod:: |
0 | 1881 size_of_parameters_offset()))); |
1506 | 1882 __ shll(rax, Interpreter::logStackElementSize); |
0 | 1883 __ restore_locals(); // XXX do we need this? |
304 | 1884 __ subptr(r14, rax); |
1885 __ addptr(r14, wordSize); | |
0 | 1886 // Save these arguments |
1887 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, | |
1888 Deoptimization:: | |
1889 popframe_preserve_args), | |
1890 r15_thread, rax, r14); | |
1891 | |
1892 __ remove_activation(vtos, rdx, | |
1893 /* throw_monitor_exception */ false, | |
1894 /* install_monitor_exception */ false, | |
1895 /* notify_jvmdi */ false); | |
1896 | |
1897 // Inform deoptimization that it is responsible for restoring | |
1898 // these arguments | |
1899 __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), | |
1900 JavaThread::popframe_force_deopt_reexecution_bit); | |
1901 | |
1902 // Continue in deoptimization handler | |
1903 __ jmp(rdx); | |
1904 | |
1905 __ bind(caller_not_deoptimized); | |
1906 } | |
1907 | |
1908 __ remove_activation(vtos, rdx, /* rdx result (retaddr) is not used */ | |
1909 /* throw_monitor_exception */ false, | |
1910 /* install_monitor_exception */ false, | |
1911 /* notify_jvmdi */ false); | |
1912 | |
1913 // Finish with popframe handling | |
1914 // A previous I2C followed by a deoptimization might have moved the | |
1915 // outgoing arguments further up the stack. PopFrame expects the | |
1916 // mutations to those outgoing arguments to be preserved and other | |
1917 // constraints basically require this frame to look exactly as | |
1918 // though it had previously invoked an interpreted activation with | |
1919 // no space between the top of the expression stack (current | |
1920 // last_sp) and the top of stack. Rather than force deopt to | |
1921 // maintain this kind of invariant all the time we call a small | |
1922 // fixup routine to move the mutated arguments onto the top of our | |
1923 // expression stack if necessary. | |
304 | 1924 __ mov(c_rarg1, rsp); |
1925 __ movptr(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); | |
0 | 1926 // PC must point into interpreter here |
1927 __ set_last_Java_frame(noreg, rbp, __ pc()); | |
1928 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2); | |
1929 __ reset_last_Java_frame(true, true); | |
1930 // Restore the last_sp and null it out | |
304 | 1931 __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); |
1932 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); | |
0 | 1933 |
1934 __ restore_bcp(); // XXX do we need this? | |
1935 __ restore_locals(); // XXX do we need this? | |
1936 // The method data pointer was incremented already during | |
1937 // call profiling. We have to restore the mdp for the current bcp. | |
1938 if (ProfileInterpreter) { | |
1939 __ set_method_data_pointer_for_bcp(); | |
1940 } | |
1941 | |
1942 // Clear the popframe condition flag | |
1943 __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), | |
1944 JavaThread::popframe_inactive); | |
1945 | |
12010
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1946 #if INCLUDE_JVMTI |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1947 if (EnableInvokeDynamic) { |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1948 Label L_done; |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1949 const Register local0 = r14; |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1950 |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1951 __ cmpb(Address(r13, 0), Bytecodes::_invokestatic); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1952 __ jcc(Assembler::notEqual, L_done); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1953 |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1954 // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1955 // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1956 |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1957 __ get_method(rdx); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1958 __ movptr(rax, Address(local0, 0)); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1959 __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1960 |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1961 __ testptr(rax, rax); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1962 __ jcc(Assembler::zero, L_done); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1963 |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1964 __ movptr(Address(rbx, 0), rax); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1965 __ bind(L_done); |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1966 } |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1967 #endif // INCLUDE_JVMTI |
ca0165daa6ec
7187554: JSR 292: JVMTI PopFrame needs to handle appendix arguments
sspitsyn
parents:
11080
diff
changeset
|
1968 |
0 | 1969 __ dispatch_next(vtos); |
1970 // end of PopFrame support | |
1971 | |
1972 Interpreter::_remove_activation_entry = __ pc(); | |
1973 | |
1974 // preserve exception over this code sequence | |
1975 __ pop_ptr(rax); | |
304 | 1976 __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), rax); |
0 | 1977 // remove the activation (without doing throws on illegalMonitorExceptions) |
1978 __ remove_activation(vtos, rdx, false, true, false); | |
1979 // restore exception | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1980 __ get_vm_result(rax, r15_thread); |
0 | 1981 |
1982 // In between activations - previous activation type unknown yet | |
1983 // compute continuation point - the continuation point expects the | |
1984 // following registers set up: | |
1985 // | |
1986 // rax: exception | |
1987 // rdx: return address/pc that threw exception | |
1988 // rsp: expression stack of caller | |
1989 // rbp: ebp of caller | |
304 | 1990 __ push(rax); // save exception |
1991 __ push(rdx); // save return address | |
0 | 1992 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, |
1993 SharedRuntime::exception_handler_for_return_address), | |
1295 | 1994 r15_thread, rdx); |
304 | 1995 __ mov(rbx, rax); // save exception handler |
1996 __ pop(rdx); // restore return address | |
1997 __ pop(rax); // restore exception | |
0 | 1998 // Note that an "issuing PC" is actually the next PC after the call |
1999 __ jmp(rbx); // jump to exception | |
2000 // handler of caller | |
2001 } | |
2002 | |
2003 | |
2004 // | |
2005 // JVMTI ForceEarlyReturn support | |
2006 // | |
2007 address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) { | |
2008 address entry = __ pc(); | |
2009 | |
2010 __ restore_bcp(); | |
2011 __ restore_locals(); | |
2012 __ empty_expression_stack(); | |
2013 __ load_earlyret_value(state); | |
2014 | |
304 | 2015 __ movptr(rdx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); |
0 | 2016 Address cond_addr(rdx, JvmtiThreadState::earlyret_state_offset()); |
2017 | |
2018 // Clear the earlyret state | |
2019 __ movl(cond_addr, JvmtiThreadState::earlyret_inactive); | |
2020 | |
2021 __ remove_activation(state, rsi, | |
2022 false, /* throw_monitor_exception */ | |
2023 false, /* install_monitor_exception */ | |
2024 true); /* notify_jvmdi */ | |
2025 __ jmp(rsi); | |
2026 | |
2027 return entry; | |
2028 } // end of ForceEarlyReturn support | |
2029 | |
2030 | |
2031 //----------------------------------------------------------------------------- | |
2032 // Helper for vtos entry point generation | |
2033 | |
2034 void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t, | |
2035 address& bep, | |
2036 address& cep, | |
2037 address& sep, | |
2038 address& aep, | |
2039 address& iep, | |
2040 address& lep, | |
2041 address& fep, | |
2042 address& dep, | |
2043 address& vep) { | |
2044 assert(t->is_valid() && t->tos_in() == vtos, "illegal template"); | |
2045 Label L; | |
2046 aep = __ pc(); __ push_ptr(); __ jmp(L); | |
2047 fep = __ pc(); __ push_f(); __ jmp(L); | |
2048 dep = __ pc(); __ push_d(); __ jmp(L); | |
2049 lep = __ pc(); __ push_l(); __ jmp(L); | |
2050 bep = cep = sep = | |
2051 iep = __ pc(); __ push_i(); | |
2052 vep = __ pc(); | |
2053 __ bind(L); | |
2054 generate_and_dispatch(t); | |
2055 } | |
2056 | |
2057 | |
2058 //----------------------------------------------------------------------------- | |
2059 // Generation of individual instructions | |
2060 | |
2061 // helpers for generate_and_dispatch | |
2062 | |
2063 | |
2064 InterpreterGenerator::InterpreterGenerator(StubQueue* code) | |
2065 : TemplateInterpreterGenerator(code) { | |
2066 generate_all(); // down here so it can be "virtual" | |
2067 } | |
2068 | |
2069 //----------------------------------------------------------------------------- | |
2070 | |
2071 // Non-product code | |
2072 #ifndef PRODUCT | |
2073 address TemplateInterpreterGenerator::generate_trace_code(TosState state) { | |
2074 address entry = __ pc(); | |
2075 | |
2076 __ push(state); | |
304 | 2077 __ push(c_rarg0); |
2078 __ push(c_rarg1); | |
2079 __ push(c_rarg2); | |
2080 __ push(c_rarg3); | |
2081 __ mov(c_rarg2, rax); // Pass itos | |
0 | 2082 #ifdef _WIN64 |
2083 __ movflt(xmm3, xmm0); // Pass ftos | |
2084 #endif | |
2085 __ call_VM(noreg, | |
2086 CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), | |
2087 c_rarg1, c_rarg2, c_rarg3); | |
304 | 2088 __ pop(c_rarg3); |
2089 __ pop(c_rarg2); | |
2090 __ pop(c_rarg1); | |
2091 __ pop(c_rarg0); | |
0 | 2092 __ pop(state); |
2093 __ ret(0); // return from result handler | |
2094 | |
2095 return entry; | |
2096 } | |
2097 | |
2098 void TemplateInterpreterGenerator::count_bytecode() { | |
2099 __ incrementl(ExternalAddress((address) &BytecodeCounter::_counter_value)); | |
2100 } | |
2101 | |
2102 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) { | |
2103 __ incrementl(ExternalAddress((address) &BytecodeHistogram::_counters[t->bytecode()])); | |
2104 } | |
2105 | |
2106 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) { | |
2107 __ mov32(rbx, ExternalAddress((address) &BytecodePairHistogram::_index)); | |
2108 __ shrl(rbx, BytecodePairHistogram::log2_number_of_codes); | |
2109 __ orl(rbx, | |
2110 ((int) t->bytecode()) << | |
2111 BytecodePairHistogram::log2_number_of_codes); | |
2112 __ mov32(ExternalAddress((address) &BytecodePairHistogram::_index), rbx); | |
2113 __ lea(rscratch1, ExternalAddress((address) BytecodePairHistogram::_counters)); | |
2114 __ incrementl(Address(rscratch1, rbx, Address::times_4)); | |
2115 } | |
2116 | |
2117 | |
2118 void TemplateInterpreterGenerator::trace_bytecode(Template* t) { | |
2119 // Call a little run-time stub to avoid blow-up for each bytecode. | |
2120 // The run-time runtime saves the right registers, depending on | |
2121 // the tosca in-state for the given template. | |
2122 | |
2123 assert(Interpreter::trace_code(t->tos_in()) != NULL, | |
2124 "entry must have been generated"); | |
1976
0fc262af204f
6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops
coleenp
parents:
1972
diff
changeset
|
2125 __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) |
304 | 2126 __ andptr(rsp, -16); // align stack as required by ABI |
0 | 2127 __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in()))); |
304 | 2128 __ mov(rsp, r12); // restore sp |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
2129 __ reinit_heapbase(); |
0 | 2130 } |
2131 | |
2132 | |
2133 void TemplateInterpreterGenerator::stop_interpreter_at() { | |
2134 Label L; | |
2135 __ cmp32(ExternalAddress((address) &BytecodeCounter::_counter_value), | |
2136 StopInterpreterAt); | |
2137 __ jcc(Assembler::notEqual, L); | |
2138 __ int3(); | |
2139 __ bind(L); | |
2140 } | |
2141 #endif // !PRODUCT | |
304 | 2142 #endif // ! CC_INTERP |