annotate src/cpu/x86/vm/interp_masm_x86_64.cpp @ 20304:a22acf6d7598

8048112: G1 Full GC needs to support the case when the very first region is not available Summary: Refactor preparation for compaction during Full GC so that it lazily initializes the first compaction point. This also avoids problems later when the first region may not be committed. Also reviewed by K. Barrett. Reviewed-by: brutisso
author tschatzl
date Mon, 21 Jul 2014 10:00:31 +0200
parents ea79ab313e98
children 096c224171c4 d3f14809b051
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
25 #include "precompiled.hpp"
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12882
diff changeset
26 #include "interp_masm_x86.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
27 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
28 #include "interpreter/interpreterRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
29 #include "oops/arrayOop.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
30 #include "oops/markOop.hpp"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
31 #include "oops/methodData.hpp"
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
32 #include "oops/method.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
33 #include "prims/jvmtiExport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
34 #include "prims/jvmtiRedefineClassesTrace.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
35 #include "prims/jvmtiThreadState.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
36 #include "runtime/basicLock.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
37 #include "runtime/biasedLocking.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
38 #include "runtime/sharedRuntime.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 6725
diff changeset
39 #include "runtime/thread.inline.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Implementation of InterpreterMacroAssembler
a61af66fc99e Initial load
duke
parents:
diff changeset
43
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
44 #ifdef CC_INTERP
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
45 void InterpreterMacroAssembler::get_method(Register reg) {
520
52a431267315 6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents: 362
diff changeset
46 movptr(reg, Address(rbp, -((int)sizeof(BytecodeInterpreter) + 2 * wordSize)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
47 movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
48 }
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
49 #endif // CC_INTERP
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
50
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
51 #ifndef CC_INTERP
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
52
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53 void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 int number_of_arguments) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // interpreter specific
a61af66fc99e Initial load
duke
parents:
diff changeset
56 //
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // Note: No need to save/restore bcp & locals (r13 & r14) pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // since these are callee saved registers and no blocking/
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // GC can happen in leaf calls.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
60 // Further Note: DO NOT save/restore bcp/locals. If a caller has
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
61 // already saved them so that it can use esi/edi as temporaries
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
62 // then a save/restore here will DESTROY the copy the caller
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
63 // saved! There used to be a save_bcp() that only happened in
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
64 // the ASSERT path (no restore_bcp). Which caused bizarre failures
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
65 // when jvm built with ASSERTs.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
66 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
67 {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
69 cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
70 jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 stop("InterpreterMacroAssembler::call_VM_leaf_base:"
a61af66fc99e Initial load
duke
parents:
diff changeset
72 " last_sp != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
73 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // super call
a61af66fc99e Initial load
duke
parents:
diff changeset
77 MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // interpreter specific
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
79 // Used to ASSERT that r13/r14 were equal to frame's bcp/locals
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
80 // but since they may not have been saved (and we don't want to
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
81 // save thme here (see note above) the assert is invalid.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
82 }
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 void InterpreterMacroAssembler::call_VM_base(Register oop_result,
a61af66fc99e Initial load
duke
parents:
diff changeset
85 Register java_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 Register last_java_sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 address entry_point,
a61af66fc99e Initial load
duke
parents:
diff changeset
88 int number_of_arguments,
a61af66fc99e Initial load
duke
parents:
diff changeset
89 bool check_exceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // interpreter specific
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Note: Could avoid restoring locals ptr (callee saved) - however doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // really make a difference for these runtime calls, since they are
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // slow anyway. Btw., bcp must be saved/restored since it may change
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // due to GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // assert(java_thread == noreg , "not expecting a precomputed java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
97 save_bcp();
a61af66fc99e Initial load
duke
parents:
diff changeset
98 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
99 {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
101 cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
102 jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 stop("InterpreterMacroAssembler::call_VM_leaf_base:"
a61af66fc99e Initial load
duke
parents:
diff changeset
104 " last_sp != NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
105 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // super call
a61af66fc99e Initial load
duke
parents:
diff changeset
109 MacroAssembler::call_VM_base(oop_result, noreg, last_java_sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
110 entry_point, number_of_arguments,
a61af66fc99e Initial load
duke
parents:
diff changeset
111 check_exceptions);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // interpreter specific
a61af66fc99e Initial load
duke
parents:
diff changeset
113 restore_bcp();
a61af66fc99e Initial load
duke
parents:
diff changeset
114 restore_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 void InterpreterMacroAssembler::check_and_handle_popframe(Register java_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (JvmtiExport::can_pop_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // Initiate popframe handling only if it is not already being
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // processed. If the flag has the popframe_processing bit set, it
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // means that this code is called *during* popframe handling - we
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // don't want to reenter.
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // This method is only called just after the call into the vm in
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // call_VM_base, so the arg registers are available.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 movl(c_rarg0, Address(r15_thread, JavaThread::popframe_condition_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
128 testl(c_rarg0, JavaThread::popframe_pending_bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
130 testl(c_rarg0, JavaThread::popframe_processing_bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 jcc(Assembler::notZero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Call Interpreter::remove_activation_preserving_args_entry() to get the
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // address of the same-named entrypoint in the generated interpreter code.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_preserving_args_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
135 jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
142 movptr(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
143 const Address tos_addr(rcx, JvmtiThreadState::earlyret_tos_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
144 const Address oop_addr(rcx, JvmtiThreadState::earlyret_oop_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
145 const Address val_addr(rcx, JvmtiThreadState::earlyret_value_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
146 switch (state) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
147 case atos: movptr(rax, oop_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
148 movptr(oop_addr, (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
149 verify_oop(rax, state); break;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
150 case ltos: movptr(rax, val_addr); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
151 case btos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
152 case ctos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
153 case stos: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
154 case itos: movl(rax, val_addr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 case ftos: movflt(xmm0, val_addr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 case dtos: movdbl(xmm0, val_addr); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Clean up tos value in the thread object
a61af66fc99e Initial load
duke
parents:
diff changeset
161 movl(tos_addr, (int) ilgl);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
162 movl(val_addr, (int32_t) NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 if (JvmtiExport::can_force_early_return()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
168 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
169 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
170 testptr(c_rarg0, c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
171 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // Initiate earlyret handling only if it is not already being processed.
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // If the flag has the earlyret_processing bit set, it means that this code
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // is called *during* earlyret handling - we don't want to reenter.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_state_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
177 cmpl(c_rarg0, JvmtiThreadState::earlyret_pending);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Call Interpreter::remove_activation_early_entry() to get the address of the
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // same-named entrypoint in the generated interpreter code.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
182 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
183 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
184 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 jmp(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
a61af66fc99e Initial load
duke
parents:
diff changeset
192 Register reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
193 int bcp_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
13034
ea79ab313e98 8027252: Crash in interpreter because get_unsigned_2_byte_index_at_bcp reads 4 bytes
mgerdin
parents: 12962
diff changeset
195 load_unsigned_short(reg, Address(r13, bcp_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
196 bswapl(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 shrl(reg, 16);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
201 void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
202 int bcp_offset,
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
203 size_t index_size) {
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
204 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
205 if (index_size == sizeof(u2)) {
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
206 load_unsigned_short(index, Address(r13, bcp_offset));
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
207 } else if (index_size == sizeof(u4)) {
2416
38fea01eb669 6817525: turn on method handle functionality by default for JSR 292
twisti
parents: 2118
diff changeset
208 assert(EnableInvokeDynamic, "giant index used only for JSR 292");
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
209 movl(index, Address(r13, bcp_offset));
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
210 // Check if the secondary index definition is still ~x, otherwise
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
211 // we have to change the following assembler code to calculate the
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
212 // plain index.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
213 assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
214 notl(index); // convert to plain index
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
215 } else if (index_size == sizeof(u1)) {
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
216 load_unsigned_byte(index, Address(r13, bcp_offset));
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
217 } else {
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
218 ShouldNotReachHere();
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
219 }
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
220 }
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
221
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
222
0
a61af66fc99e Initial load
duke
parents:
diff changeset
223 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
a61af66fc99e Initial load
duke
parents:
diff changeset
224 Register index,
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
225 int bcp_offset,
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
226 size_t index_size) {
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
227 assert_different_registers(cache, index);
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
228 get_cache_index_at_bcp(index, bcp_offset, index_size);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
229 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
230 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // convert from field index to ConstantPoolCacheEntry index
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
232 assert(exact_log2(in_words(ConstantPoolCacheEntry::size())) == 2, "else change next line");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
233 shll(index, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
237 void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
238 Register index,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
239 Register bytecode,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
240 int byte_no,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
241 int bcp_offset,
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
242 size_t index_size) {
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
243 get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
244 // We use a 32-bit load here since the layout of 64-bit words on
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
245 // little-endian machines allow us that.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
246 movl(bytecode, Address(cache, index, Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()));
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
247 const int shift_count = (1 + byte_no) * BitsPerByte;
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 3960
diff changeset
248 assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 3960
diff changeset
249 (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 3960
diff changeset
250 "correct shift count");
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
251 shrl(bytecode, shift_count);
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 3960
diff changeset
252 assert(ConstantPoolCacheEntry::bytecode_1_mask == ConstantPoolCacheEntry::bytecode_2_mask, "common mask");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 3960
diff changeset
253 andl(bytecode, ConstantPoolCacheEntry::bytecode_1_mask);
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
254 }
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
255
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3808
diff changeset
256
0
a61af66fc99e Initial load
duke
parents:
diff changeset
257 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
a61af66fc99e Initial load
duke
parents:
diff changeset
258 Register tmp,
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
259 int bcp_offset,
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
260 size_t index_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
261 assert(cache != tmp, "must use different register");
1565
ab102d5d923e 6939207: refactor constant pool index processing
jrose
parents: 1506
diff changeset
262 get_cache_index_at_bcp(tmp, bcp_offset, index_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
263 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // convert from field index to ConstantPoolCacheEntry index
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // and from word offset to byte offset
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
266 assert(exact_log2(in_bytes(ConstantPoolCacheEntry::size_in_bytes())) == 2 + LogBytesPerWord, "else change next line");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
267 shll(tmp, 2 + LogBytesPerWord);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
268 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // skip past the header
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
270 addptr(cache, in_bytes(ConstantPoolCache::base_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
271 addptr(cache, tmp); // construct pointer to cache entry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
273
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
274 void InterpreterMacroAssembler::get_method_counters(Register method,
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
275 Register mcs, Label& skip) {
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
276 Label has_counters;
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
277 movptr(mcs, Address(method, Method::method_counters_offset()));
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
278 testptr(mcs, mcs);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
279 jcc(Assembler::notZero, has_counters);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
280 call_VM(noreg, CAST_FROM_FN_PTR(address,
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
281 InterpreterRuntime::build_method_counters), method);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
282 movptr(mcs, Address(method,Method::method_counters_offset()));
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
283 testptr(mcs, mcs);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
284 jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
285 bind(has_counters);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
286 }
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 7180
diff changeset
287
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
288 // Load object from cpool->resolved_references(index)
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
289 void InterpreterMacroAssembler::load_resolved_reference_at_index(
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
290 Register result, Register index) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
291 assert_different_registers(result, index);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
292 // convert from field index to resolved_references() index and from
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
293 // word index to byte offset. Since this is a java object, it can be compressed
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
294 Register tmp = index; // reuse
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
295 shll(tmp, LogBytesPerHeapOop);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
296
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
297 get_constant_pool(result);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
298 // load pointer for resolved_references[] objArray
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
299 movptr(result, Address(result, ConstantPool::resolved_references_offset_in_bytes()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
300 // JNIHandles::resolve(obj);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
301 movptr(result, Address(result, 0));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
302 // Add in the index
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
303 addptr(result, tmp);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
304 load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
305 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // subtype of super_klass.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 //
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Args:
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // rax: superklass
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Rsub_klass: subklass
a61af66fc99e Initial load
duke
parents:
diff changeset
313 //
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Kills:
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // rcx, rdi
a61af66fc99e Initial load
duke
parents:
diff changeset
316 void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
317 Label& ok_is_subtype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 assert(Rsub_klass != rax, "rax holds superklass");
a61af66fc99e Initial load
duke
parents:
diff changeset
319 assert(Rsub_klass != r14, "r14 holds locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
320 assert(Rsub_klass != r13, "r13 holds bcp");
a61af66fc99e Initial load
duke
parents:
diff changeset
321 assert(Rsub_klass != rcx, "rcx holds 2ndary super array length");
a61af66fc99e Initial load
duke
parents:
diff changeset
322 assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr");
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Profile the not-null value's klass.
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 625
diff changeset
325 profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, reloads rdi
0
a61af66fc99e Initial load
duke
parents:
diff changeset
326
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 625
diff changeset
327 // Do the check.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 625
diff changeset
328 check_klass_subtype(Rsub_klass, rax, rcx, ok_is_subtype); // blows rcx
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
329
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 625
diff changeset
330 // Profile the failure of the check.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
331 profile_typecheck_failed(rcx); // blows rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
335
0
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Java Expression Stack
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 void InterpreterMacroAssembler::pop_ptr(Register r) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
339 pop(r);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 void InterpreterMacroAssembler::pop_i(Register r) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
343 // XXX can't use pop currently, upper half non clean
0
a61af66fc99e Initial load
duke
parents:
diff changeset
344 movl(r, Address(rsp, 0));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
345 addptr(rsp, wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void InterpreterMacroAssembler::pop_l(Register r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 movq(r, Address(rsp, 0));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
350 addptr(rsp, 2 * Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 void InterpreterMacroAssembler::pop_f(XMMRegister r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 movflt(r, Address(rsp, 0));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
355 addptr(rsp, wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 void InterpreterMacroAssembler::pop_d(XMMRegister r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 movdbl(r, Address(rsp, 0));
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
360 addptr(rsp, 2 * Interpreter::stackElementSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void InterpreterMacroAssembler::push_ptr(Register r) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
364 push(r);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 void InterpreterMacroAssembler::push_i(Register r) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
368 push(r);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void InterpreterMacroAssembler::push_l(Register r) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
372 subptr(rsp, 2 * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
373 movq(Address(rsp, 0), r);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 void InterpreterMacroAssembler::push_f(XMMRegister r) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
377 subptr(rsp, wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 movflt(Address(rsp, 0), r);
a61af66fc99e Initial load
duke
parents:
diff changeset
379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 void InterpreterMacroAssembler::push_d(XMMRegister r) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
382 subptr(rsp, 2 * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
383 movdbl(Address(rsp, 0), r);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 void InterpreterMacroAssembler::pop(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 case atos: pop_ptr(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 case btos:
a61af66fc99e Initial load
duke
parents:
diff changeset
390 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
391 case stos:
a61af66fc99e Initial load
duke
parents:
diff changeset
392 case itos: pop_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 case ltos: pop_l(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 case ftos: pop_f(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 case dtos: pop_d(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399 verify_oop(rax, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 void InterpreterMacroAssembler::push(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 verify_oop(rax, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
404 switch (state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 case atos: push_ptr(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 case btos:
a61af66fc99e Initial load
duke
parents:
diff changeset
407 case ctos:
a61af66fc99e Initial load
duke
parents:
diff changeset
408 case stos:
a61af66fc99e Initial load
duke
parents:
diff changeset
409 case itos: push_i(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 case ltos: push_l(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 case ftos: push_f(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 case dtos: push_d(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 case vtos: /* nothing to do */ break;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
419 // Helpers for swap and dup
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
420 void InterpreterMacroAssembler::load_ptr(int n, Register val) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
421 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
424 void InterpreterMacroAssembler::store_ptr(int n, Register val) {
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
425 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
429 void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // set sender sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
431 lea(r13, Address(rsp, wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // record last_sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
433 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13);
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
434 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
435
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
436
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
437 // Jump to from_interpreted entry of a call unless single stepping is possible
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
438 // in this thread in which case we must call the i2i entry
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
439 void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) {
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
440 prepare_to_jump_from_interpreted();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 Label run_compiled_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // JVMTI events, such as single-stepping, are implemented partly by avoiding running
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // compiled code in threads for which the event is enabled. Check here for
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // interp_only_mode if these events CAN be enabled.
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // interp_only is an int, on little endian it is sufficient to test the byte only
1976
0fc262af204f 6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops
coleenp
parents: 1972
diff changeset
448 // Is a cmpl faster?
0fc262af204f 6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops
coleenp
parents: 1972
diff changeset
449 cmpb(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0);
3808
341a57af9b0a 6990212: JSR 292 JVMTI MethodEnter hook is not called for JSR 292 bootstrap and target methods
never
parents: 3336
diff changeset
450 jccb(Assembler::zero, run_compiled_code);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
451 jmp(Address(method, Method::interpreter_entry_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
452 bind(run_compiled_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
455 jmp(Address(method, Method::from_interpreted_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // The following two routines provide a hook so that an implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // can schedule the dispatch in two parts. amd64 does not do this.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void InterpreterMacroAssembler::dispatch_prolog(TosState state, int step) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Nothing amd64 specific to be done here
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 dispatch_next(state, step);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 void InterpreterMacroAssembler::dispatch_base(TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
471 address* table,
a61af66fc99e Initial load
duke
parents:
diff changeset
472 bool verifyoop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 verify_FPU(1, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 if (VerifyActivationFrameSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
476 mov(rcx, rbp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
477 subptr(rcx, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
478 int32_t min_frame_size =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
479 (frame::link_offset - frame::interpreter_frame_initial_sp_offset) *
a61af66fc99e Initial load
duke
parents:
diff changeset
480 wordSize;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
481 cmpptr(rcx, (int32_t)min_frame_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
482 jcc(Assembler::greaterEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 stop("broken stack frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
484 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if (verifyoop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 verify_oop(rax, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 lea(rscratch1, ExternalAddress((address)table));
a61af66fc99e Initial load
duke
parents:
diff changeset
490 jmp(Address(rscratch1, rbx, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 void InterpreterMacroAssembler::dispatch_only(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 dispatch_base(state, Interpreter::dispatch_table(state));
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 void InterpreterMacroAssembler::dispatch_only_normal(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 dispatch_base(state, Interpreter::normal_table(state));
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 void InterpreterMacroAssembler::dispatch_only_noverify(TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 dispatch_base(state, Interpreter::normal_table(state), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 void InterpreterMacroAssembler::dispatch_next(TosState state, int step) {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // load next bytecode (load before advancing r13 to prevent AGI)
a61af66fc99e Initial load
duke
parents:
diff changeset
508 load_unsigned_byte(rbx, Address(r13, step));
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // advance r13
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
510 increment(r13, step);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
511 dispatch_base(state, Interpreter::dispatch_table(state));
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // load current bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
516 load_unsigned_byte(rbx, Address(r13, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
517 dispatch_base(state, table);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
521 //
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // Unlock the receiver if this is a synchronized method.
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Unlock any Java monitors from syncronized blocks.
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // Remove the activation from the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 //
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // If there are locked Java monitors
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // If throw_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // throws IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // Else if install_monitor_exception
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // installs IllegalMonitorStateException
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // Else
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // no error processing
a61af66fc99e Initial load
duke
parents:
diff changeset
533 void InterpreterMacroAssembler::remove_activation(
a61af66fc99e Initial load
duke
parents:
diff changeset
534 TosState state,
a61af66fc99e Initial load
duke
parents:
diff changeset
535 Register ret_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
536 bool throw_monitor_exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
537 bool install_monitor_exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
538 bool notify_jvmdi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // Note: Registers rdx xmm0 may be in use for the
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // result check if synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Label unlocked, unlock, no_unlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // get the value of _do_not_unlock_if_synchronized into rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
544 const Address do_not_unlock_if_synchronized(r15_thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
545 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
546 movbool(rdx, do_not_unlock_if_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 movbool(do_not_unlock_if_synchronized, false); // reset the flag
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // get method access flags
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
550 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
551 movl(rcx, Address(rbx, Method::access_flags_offset()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
552 testl(rcx, JVM_ACC_SYNCHRONIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 jcc(Assembler::zero, unlocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // Don't unlock anything if the _do_not_unlock_if_synchronized flag
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // is set.
a61af66fc99e Initial load
duke
parents:
diff changeset
557 testbool(rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 jcc(Assembler::notZero, no_unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // unlock monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
561 push(state); // save result
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // BasicObjectLock will be first in list, since this is a
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // synchronized method. However, need to check that the object has
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // not been unlocked by an explicit monitorexit bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
566 const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset *
a61af66fc99e Initial load
duke
parents:
diff changeset
567 wordSize - (int) sizeof(BasicObjectLock));
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // We use c_rarg1 so that if we go slow path it will be the correct
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // register for unlock_object to pass to VM directly
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
570 lea(c_rarg1, monitor); // address of first monitor
0
a61af66fc99e Initial load
duke
parents:
diff changeset
571
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
572 movptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
573 testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
574 jcc(Assembler::notZero, unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 pop(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 if (throw_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // Entry already unlocked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
579 call_VM(noreg, CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
580 InterpreterRuntime::throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
581 should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
582 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // Monitor already unlocked during a stack unroll. If requested,
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // install an illegal_monitor_state_exception. Continue with
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // stack unrolling.
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if (install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 call_VM(noreg, CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
588 InterpreterRuntime::new_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 jmp(unlocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 bind(unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 unlock_object(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
595 pop(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // Check that for block-structured locking (i.e., that all locked
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // objects has been unlocked)
a61af66fc99e Initial load
duke
parents:
diff changeset
599 bind(unlocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // rax: Might contain return value
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // Check that all monitors are unlocked
a61af66fc99e Initial load
duke
parents:
diff changeset
604 {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 Label loop, exception, entry, restart;
a61af66fc99e Initial load
duke
parents:
diff changeset
606 const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
607 const Address monitor_block_top(
a61af66fc99e Initial load
duke
parents:
diff changeset
608 rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 const Address monitor_block_bot(
a61af66fc99e Initial load
duke
parents:
diff changeset
610 rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 bind(restart);
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // We use c_rarg1 so that if we go slow path it will be the correct
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // register for unlock_object to pass to VM directly
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
615 movptr(c_rarg1, monitor_block_top); // points to current entry, starting
0
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // with top-most entry
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
617 lea(rbx, monitor_block_bot); // points to word before bottom of
0
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // monitor block
a61af66fc99e Initial load
duke
parents:
diff changeset
619 jmp(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // Entry already locked, need to throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
622 bind(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 if (throw_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Throw exception
a61af66fc99e Initial load
duke
parents:
diff changeset
626 MacroAssembler::call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
627 CAST_FROM_FN_PTR(address, InterpreterRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
628 throw_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
629 should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
630 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // Stack unrolling. Unlock object and install illegal_monitor_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Unlock does not block, so don't have to worry about the frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // We don't have to preserve c_rarg1 since we are going to throw an exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 push(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 unlock_object(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 pop(state);
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 if (install_monitor_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 call_VM(noreg, CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
641 InterpreterRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
642 new_illegal_monitor_state_exception));
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 jmp(restart);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 bind(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // check if current entry is used
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
650 cmpptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 jcc(Assembler::notEqual, exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
652
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
653 addptr(c_rarg1, entry_size); // otherwise advance to next entry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 bind(entry);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
655 cmpptr(c_rarg1, rbx); // check if bottom reached
0
a61af66fc99e Initial load
duke
parents:
diff changeset
656 jcc(Assembler::notEqual, loop); // if not at bottom then check this entry
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 bind(no_unlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // jvmti support
a61af66fc99e Initial load
duke
parents:
diff changeset
662 if (notify_jvmdi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 notify_method_exit(state, NotifyJVMTI); // preserve TOSCA
a61af66fc99e Initial load
duke
parents:
diff changeset
664 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // remove activation
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // get sender sp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
670 movptr(rbx,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
671 Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
672 leave(); // remove frame anchor
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
673 pop(ret_addr); // get return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
674 mov(rsp, rbx); // set sp to sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
677 #endif // C_INTERP
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
678
0
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // Lock object
a61af66fc99e Initial load
duke
parents:
diff changeset
680 //
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Args:
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // c_rarg1: BasicObjectLock to be used for locking
a61af66fc99e Initial load
duke
parents:
diff changeset
683 //
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // Kills:
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // rax
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // rscratch1, rscratch2 (scratch regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
688 void InterpreterMacroAssembler::lock_object(Register lock_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
689 assert(lock_reg == c_rarg1, "The argument is only for looks. It must be c_rarg1");
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (UseHeavyMonitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
693 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
a61af66fc99e Initial load
duke
parents:
diff changeset
694 lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
695 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 const Register swap_reg = rax; // Must use rax for cmpxchg instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
699 const Register obj_reg = c_rarg3; // Will contain the oop
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
702 const int lock_offset = BasicObjectLock::lock_offset_in_bytes ();
a61af66fc99e Initial load
duke
parents:
diff changeset
703 const int mark_offset = lock_offset +
a61af66fc99e Initial load
duke
parents:
diff changeset
704 BasicLock::displaced_header_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 Label slow_case;
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // Load object pointer into obj_reg %c_rarg3
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
709 movptr(obj_reg, Address(lock_reg, obj_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
712 biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // Load immediate 1 into swap_reg %rax
a61af66fc99e Initial load
duke
parents:
diff changeset
716 movl(swap_reg, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // Load (object->mark() | 1) into swap_reg %rax
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
719 orptr(swap_reg, Address(obj_reg, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // Save (object->mark() | 1) into BasicLock's displaced header
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
722 movptr(Address(lock_reg, mark_offset), swap_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 assert(lock_offset == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
725 "displached header must be first word in BasicObjectLock");
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 if (os::is_MP()) lock();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
728 cmpxchgptr(lock_reg, Address(obj_reg, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if (PrintBiasedLockingStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 cond_inc32(Assembler::zero,
a61af66fc99e Initial load
duke
parents:
diff changeset
731 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 jcc(Assembler::zero, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // Test if the oopMark is an obvious stack pointer, i.e.,
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // 1) (mark & 7) == 0, and
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // 2) rsp <= mark < mark + os::pagesize()
a61af66fc99e Initial load
duke
parents:
diff changeset
738 //
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // These 3 tests can be done by evaluating the following
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // expression: ((mark - rsp) & (7 - os::vm_page_size())),
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // assuming both stack pointer and pagesize have their
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // least significant 3 bits clear.
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
744 subptr(swap_reg, rsp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
745 andptr(swap_reg, 7 - os::vm_page_size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
746
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // Save the test result, for recursive case, the result is zero
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
748 movptr(Address(lock_reg, mark_offset), swap_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 if (PrintBiasedLockingStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 cond_inc32(Assembler::zero,
a61af66fc99e Initial load
duke
parents:
diff changeset
752 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754 jcc(Assembler::zero, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 bind(slow_case);
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // Call the runtime routine for slow case
a61af66fc99e Initial load
duke
parents:
diff changeset
759 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
760 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
a61af66fc99e Initial load
duke
parents:
diff changeset
761 lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763 bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // Unlocks an object. Used in monitorexit bytecode and
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // remove_activation. Throws an IllegalMonitorException if object is
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // not locked by current thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
771 //
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Args:
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // c_rarg1: BasicObjectLock for lock
a61af66fc99e Initial load
duke
parents:
diff changeset
774 //
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // Kills:
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // rax
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // rscratch1, rscratch2 (scratch regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
779 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 if (UseHeavyMonitors) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
784 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
a61af66fc99e Initial load
duke
parents:
diff changeset
785 lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 const Register swap_reg = rax; // Must use rax for cmpxchg instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
790 const Register header_reg = c_rarg2; // Will contain the old oopMark
a61af66fc99e Initial load
duke
parents:
diff changeset
791 const Register obj_reg = c_rarg3; // Will contain the oop
a61af66fc99e Initial load
duke
parents:
diff changeset
792
a61af66fc99e Initial load
duke
parents:
diff changeset
793 save_bcp(); // Save in case of exception
a61af66fc99e Initial load
duke
parents:
diff changeset
794
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // Convert from BasicObjectLock structure to object and BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // structure Store the BasicLock address into %rax
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
797 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Load oop into obj_reg(%c_rarg3)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
800 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
801
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // Free entry
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
803 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 biased_locking_exit(obj_reg, header_reg, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // Load the old header from BasicLock structure
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
810 movptr(header_reg, Address(swap_reg,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
811 BasicLock::displaced_header_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // Test for recursion
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
814 testptr(header_reg, header_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // zero for recursive case
a61af66fc99e Initial load
duke
parents:
diff changeset
817 jcc(Assembler::zero, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // Atomic swap back the old header
a61af66fc99e Initial load
duke
parents:
diff changeset
820 if (os::is_MP()) lock();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
821 cmpxchgptr(header_reg, Address(obj_reg, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // zero for recursive case
a61af66fc99e Initial load
duke
parents:
diff changeset
824 jcc(Assembler::zero, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Call the runtime routine for slow case.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
827 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
828 obj_reg); // restore obj
a61af66fc99e Initial load
duke
parents:
diff changeset
829 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
830 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
a61af66fc99e Initial load
duke
parents:
diff changeset
831 lock_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 restore_bcp();
a61af66fc99e Initial load
duke
parents:
diff changeset
836 }
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
839 #ifndef CC_INTERP
0
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
842 Label& zero_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 assert(ProfileInterpreter, "must be profiling interpreter");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
844 movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
845 testptr(mdp, mdp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
846 jcc(Assembler::zero, zero_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Set the method data pointer for the current bcp.
a61af66fc99e Initial load
duke
parents:
diff changeset
851 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 assert(ProfileInterpreter, "must be profiling interpreter");
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
853 Label set_mdp;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
854 push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
855 push(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 get_method(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // Test MDO to avoid the call if it is NULL.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
859 movptr(rax, Address(rbx, in_bytes(Method::method_data_offset())));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
860 testptr(rax, rax);
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
861 jcc(Assembler::zero, set_mdp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // rbx: method
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // r13: bcp
a61af66fc99e Initial load
duke
parents:
diff changeset
864 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13);
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // rax: mdi
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
866 // mdo is guaranteed to be non-zero here, we checked for it before the call.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
867 movptr(rbx, Address(rbx, in_bytes(Method::method_data_offset())));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
868 addptr(rbx, in_bytes(MethodData::data_offset()));
2118
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
869 addptr(rax, rbx);
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
870 bind(set_mdp);
dd031b2226de 4930919: race condition in MDO creation at back branch locations
iveresov
parents: 1976
diff changeset
871 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
872 pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
873 pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 void InterpreterMacroAssembler::verify_method_data_pointer() {
a61af66fc99e Initial load
duke
parents:
diff changeset
877 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
878 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
879 Label verify_continue;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
880 push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
881 push(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
882 push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
883 push(c_rarg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
884 test_method_data_pointer(c_rarg3, verify_continue); // If mdp is zero, continue
a61af66fc99e Initial load
duke
parents:
diff changeset
885 get_method(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
886
a61af66fc99e Initial load
duke
parents:
diff changeset
887 // If the mdp is valid, it will point to a DataLayout header which is
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // consistent with the bcp. The converse is highly probable also.
622
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 520
diff changeset
889 load_unsigned_short(c_rarg2,
56aae7be60d4 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 520
diff changeset
890 Address(c_rarg3, in_bytes(DataLayout::bci_offset())));
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
891 addptr(c_rarg2, Address(rbx, Method::const_offset()));
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
892 lea(c_rarg2, Address(c_rarg2, ConstMethod::codes_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
893 cmpptr(c_rarg2, r13);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
894 jcc(Assembler::equal, verify_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // rbx: method
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // r13: bcp
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // c_rarg3: mdp
a61af66fc99e Initial load
duke
parents:
diff changeset
898 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp),
a61af66fc99e Initial load
duke
parents:
diff changeset
899 rbx, r13, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 bind(verify_continue);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
901 pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
902 pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
903 pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
904 pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
910 int constant,
a61af66fc99e Initial load
duke
parents:
diff changeset
911 Register value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
912 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
913 Address data(mdp_in, constant);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
914 movptr(data, value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
919 int constant,
a61af66fc99e Initial load
duke
parents:
diff changeset
920 bool decrement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // Counter address
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Address data(mdp_in, constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
923
a61af66fc99e Initial load
duke
parents:
diff changeset
924 increment_mdp_data_at(data, decrement);
a61af66fc99e Initial load
duke
parents:
diff changeset
925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927 void InterpreterMacroAssembler::increment_mdp_data_at(Address data,
a61af66fc99e Initial load
duke
parents:
diff changeset
928 bool decrement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 assert(ProfileInterpreter, "must be profiling interpreter");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
930 // %%% this does 64bit counters at best it is wasting space
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
931 // at worst it is a rare bug when counters overflow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
932
a61af66fc99e Initial load
duke
parents:
diff changeset
933 if (decrement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // Decrement the register. Set condition codes.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
935 addptr(data, (int32_t) -DataLayout::counter_increment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // If the decrement causes the counter to overflow, stay negative
a61af66fc99e Initial load
duke
parents:
diff changeset
937 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 jcc(Assembler::negative, L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
939 addptr(data, (int32_t) DataLayout::counter_increment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
940 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 assert(DataLayout::counter_increment == 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
943 "flow-free idiom only works with 1");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // Increment the register. Set carry flag.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
945 addptr(data, DataLayout::counter_increment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // If the increment causes the counter to overflow, pull back by 1.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
947 sbbptr(data, (int32_t)0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
953 Register reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
954 int constant,
a61af66fc99e Initial load
duke
parents:
diff changeset
955 bool decrement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
956 Address data(mdp_in, reg, Address::times_1, constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 increment_mdp_data_at(data, decrement);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 void InterpreterMacroAssembler::set_mdp_flag_at(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
962 int flag_byte_constant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
964 int header_offset = in_bytes(DataLayout::header_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
965 int header_bits = DataLayout::flag_mask_to_header_mask(flag_byte_constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // Set the flag
a61af66fc99e Initial load
duke
parents:
diff changeset
967 orl(Address(mdp_in, header_offset), header_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 void InterpreterMacroAssembler::test_mdp_data_at(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
973 int offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
974 Register value,
a61af66fc99e Initial load
duke
parents:
diff changeset
975 Register test_value_out,
a61af66fc99e Initial load
duke
parents:
diff changeset
976 Label& not_equal_continue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
978 if (test_value_out == noreg) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
979 cmpptr(value, Address(mdp_in, offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
980 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // Put the test value into a register, so caller can use it:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
982 movptr(test_value_out, Address(mdp_in, offset));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
983 cmpptr(test_value_out, value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 jcc(Assembler::notEqual, not_equal_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
990 int offset_of_disp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
991 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
992 Address disp_address(mdp_in, offset_of_disp);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
993 addptr(mdp_in, disp_address);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
994 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
999 Register reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 int offset_of_disp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1003 addptr(mdp_in, disp_address);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1004 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in,
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 int constant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 assert(ProfileInterpreter, "must be profiling interpreter");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1011 addptr(mdp_in, constant);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1012 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1014
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 assert(ProfileInterpreter, "must be profiling interpreter");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1018 push(return_bci); // save/restore across call_VM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret),
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 return_bci);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1022 pop(return_bci);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 void InterpreterMacroAssembler::profile_taken_branch(Register mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 Register bumped_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // Otherwise, assign to mdp
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // We are taking a branch. Increment the taken count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // We inline increment_mdp_data_at to return bumped_count in a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 Address data(mdp, in_bytes(JumpData::taken_offset()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1039 movptr(bumped_count, data);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 assert(DataLayout::counter_increment == 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 "flow-free idiom only works with 1");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1042 addptr(bumped_count, DataLayout::counter_increment);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1043 sbbptr(bumped_count, 0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1044 movptr(data, bumped_count); // Store back out
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1051
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 void InterpreterMacroAssembler::profile_not_taken_branch(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // We are taking a branch. Increment the not taken count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 increment_mdp_data_at(mdp, in_bytes(BranchData::not_taken_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // The method data pointer needs to be updated to correspond to
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 // the next bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 update_mdp_by_constant(mdp, in_bytes(BranchData::branch_data_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1069
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 void InterpreterMacroAssembler::profile_call(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // We are making a call. Increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1085
a61af66fc99e Initial load
duke
parents:
diff changeset
1086
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 void InterpreterMacroAssembler::profile_final_call(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // We are making a call. Increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 update_mdp_by_constant(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 in_bytes(VirtualCallData::
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 virtual_call_data_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 Register mdp,
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1108 Register reg2,
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1109 bool receiver_can_be_null) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1116 Label skip_receiver_profile;
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1117 if (receiver_can_be_null) {
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1118 Label not_null;
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1119 testptr(receiver, receiver);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1120 jccb(Assembler::notZero, not_null);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1121 // We are making a call. Increment the count for null receiver.
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1122 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1123 jmp(skip_receiver_profile);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1124 bind(not_null);
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1125 }
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1126
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // Record the receiver type.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1128 record_klass_in_profile(receiver, mdp, reg2, true);
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 967
diff changeset
1129 bind(skip_receiver_profile);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 update_mdp_by_constant(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 in_bytes(VirtualCallData::
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 virtual_call_data_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // This routine creates a state machine for updating the multi-row
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // type profile at a virtual call site (or other type-sensitive bytecode).
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // The machine visits each row (of receiver/count) until the receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // is found, or until it runs out of rows. At the same time, it remembers
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // the location of the first empty row. (An empty row records null for its
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // receiver, and can be allocated for a newly-observed receiver type.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // Because there are two degrees of freedom in the state, a simple linear
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // search will not work; it must be a decision tree. Hence this helper
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // function is recursive, to generate the required tree structured code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // It's the interpreter, so we are trading off code space for speed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // See below for example code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 void InterpreterMacroAssembler::record_klass_in_profile_helper(
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 Register receiver, Register mdp,
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1152 Register reg2, int start_row,
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1153 Label& done, bool is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1154 if (TypeProfileWidth == 0) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1155 if (is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1156 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1157 }
967
6918603297f7 6858208: jvm crash when specifying TypeProfileWidth=0 on jdk 6.0
poonam
parents: 826
diff changeset
1158 return;
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1159 }
967
6918603297f7 6858208: jvm crash when specifying TypeProfileWidth=0 on jdk 6.0
poonam
parents: 826
diff changeset
1160
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 int last_row = VirtualCallData::row_limit() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 assert(start_row <= last_row, "must be work left to do");
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // Test this row for both the receiver and for null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // Take any of three different outcomes:
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // 1. found receiver => increment count and goto done
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // 2. found null => keep looking for case 1, maybe allocate this cell
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // 3. found something else => keep looking for cases 1 and 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // Case 3 is handled by a recursive call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 for (int row = start_row; row <= last_row; row++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 Label next_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 bool test_for_null_also = (row == start_row);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // See if the receiver is receiver[n].
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 test_mdp_data_at(mdp, recvr_offset, receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 (test_for_null_also ? reg2 : noreg),
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // (Reg2 now contains the receiver from the CallData.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1179
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // The receiver is receiver[n]. Increment count[n].
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 increment_mdp_data_at(mdp, count_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 jmp(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 bind(next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (test_for_null_also) {
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1187 Label found_null;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // Failed the equality check on receiver[n]... Test for null.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1189 testptr(reg2, reg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 if (start_row == last_row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // The only thing left to do is handle the null case.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1192 if (is_virtual_call) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1193 jccb(Assembler::zero, found_null);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1194 // Receiver did not match any saved receiver and there is no empty row for it.
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1206
diff changeset
1195 // Increment total counter to indicate polymorphic case.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1196 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1197 jmp(done);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1198 bind(found_null);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1199 } else {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1200 jcc(Assembler::notZero, done);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1201 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // Since null is rare, make it be the branch-taken case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 jcc(Assembler::zero, found_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // Put all the "Case 3" tests here.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1208 record_klass_in_profile_helper(receiver, mdp, reg2, start_row + 1, done, is_virtual_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1209
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // Found a null. Keep searching for a matching receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // but remember that this is an empty (unused) slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 bind(found_null);
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // In the fall-through case, we found no matching receiver, but we
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // observed the receiver[start_row] is NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Fill in the receiver field and increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 set_mdp_data_at(mdp, recvr_offset, receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 movl(reg2, DataLayout::counter_increment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 set_mdp_data_at(mdp, count_offset, reg2);
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1225 if (start_row > 0) {
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1226 jmp(done);
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1227 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // Example state machine code for three profile rows:
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // // main copy of decision tree, rooted at row[1]
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // if (row[0].rec == rec) { row[0].incr(); goto done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // if (row[0].rec != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // // inner copy of decision tree, rooted at row[1]
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // if (row[1].rec == rec) { row[1].incr(); goto done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // if (row[1].rec != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // // degenerate decision tree, rooted at row[2]
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 // if (row[2].rec == rec) { row[2].incr(); goto done; }
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1239 // if (row[2].rec != NULL) { count.incr(); goto done; } // overflow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // row[2].init(rec); goto done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // // remember row[1] is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 // if (row[2].rec == rec) { row[2].incr(); goto done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 // row[1].init(rec); goto done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // // remember row[0] is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 // if (row[1].rec == rec) { row[1].incr(); goto done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // if (row[2].rec == rec) { row[2].incr(); goto done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // row[0].init(rec); goto done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // }
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1252 // done:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1255 Register mdp, Register reg2,
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1256 bool is_virtual_call) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 assert(ProfileInterpreter, "must be profiling");
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1260 record_klass_in_profile_helper(receiver, mdp, reg2, 0, done, is_virtual_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1261
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 bind (done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 void InterpreterMacroAssembler::profile_ret(Register return_bci,
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 uint row;
a61af66fc99e Initial load
duke
parents:
diff changeset
1270
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Update the total ret count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 for (row = 0; row < RetData::row_limit(); row++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 Label next_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1279
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // See if return_bci is equal to bci[n]:
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 test_mdp_data_at(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 in_bytes(RetData::bci_offset(row)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 return_bci, noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // return_bci is equal to bci[n]. Increment the count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 increment_mdp_data_at(mdp, in_bytes(RetData::bci_count_offset(row)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1288
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // The method data pointer needs to be updated to reflect the new target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 update_mdp_by_offset(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 in_bytes(RetData::bci_displacement_offset(row)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 jmp(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 bind(next_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 update_mdp_for_ret(return_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1301
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 void InterpreterMacroAssembler::profile_null_seen(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309
826
3f06f139ef53 6851908: interpreter null check profiling broken causing extra compilation invalidation
never
parents: 710
diff changeset
1310 set_mdp_flag_at(mdp, BitData::null_seen_byte_constant());
3f06f139ef53 6851908: interpreter null check profiling broken causing extra compilation invalidation
never
parents: 710
diff changeset
1311
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 int mdp_delta = in_bytes(BitData::bit_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 if (TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 update_mdp_by_constant(mdp, mdp_delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 void InterpreterMacroAssembler::profile_typecheck_failed(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 if (ProfileInterpreter && TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1327
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 int count_offset = in_bytes(CounterData::count_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // Back up the address, since we have already bumped the mdp.
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1334
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // *Decrement* the counter. We expect to see zero or small negatives.
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 increment_mdp_data_at(mdp, count_offset, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 bind (profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 int mdp_delta = in_bytes(BitData::bit_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 if (TypeProfileCasts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // Record the object type.
1206
87684f1a88b5 6614597: Performance variability in jvm2008 xml.validation
kvn
parents: 1108
diff changeset
1356 record_klass_in_profile(klass, mdp, reg2, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 update_mdp_by_constant(mdp, mdp_delta);
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 void InterpreterMacroAssembler::profile_switch_default(Register mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // Update the default case count
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 increment_mdp_data_at(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 in_bytes(MultiBranchData::default_count_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 update_mdp_by_offset(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 in_bytes(MultiBranchData::
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 default_displacement_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 void InterpreterMacroAssembler::profile_switch_case(Register index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 Register mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 Register reg2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 Label profile_continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1391
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 // If no method data exists, go to profile_continue.
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 test_method_data_pointer(mdp, profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // Build the base (index * per_case_size_in_bytes()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // case_array_offset_in_bytes()
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 movl(reg2, in_bytes(MultiBranchData::per_case_size()));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1398 imulptr(index, reg2); // XXX l ?
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1399 addptr(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // Update the case count
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 increment_mdp_data_at(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 in_bytes(MultiBranchData::relative_count_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 // The method data pointer needs to be updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 update_mdp_by_offset(mdp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 in_bytes(MultiBranchData::
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 relative_displacement_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 bind(profile_continue);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1417
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 if (state == atos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 MacroAssembler::verify_oop(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1423
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1426 #endif // !CC_INTERP
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 void InterpreterMacroAssembler::notify_method_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // track stack depth. If it is possible to enter interp_only_mode we add
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 // the code to check if the event should be sent.
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 testl(rdx, rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 call_VM(noreg, CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 InterpreterRuntime::post_method_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 SkipIfEqual skip(this, &DTraceMethodProbes, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 get_method(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 r15_thread, c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 }
610
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1449
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1450 // RedefineClasses() tracing support for obsolete method entry
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1451 if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1452 get_method(c_rarg1);
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1453 call_VM_leaf(
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1454 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1455 r15_thread, c_rarg1);
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
1456 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 void InterpreterMacroAssembler::notify_method_exit(
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 TosState state, NotifyMethodExitMode mode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 // track stack depth. If it is possible to enter interp_only_mode we add
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // the code to check if the event should be sent.
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // Note: frame::interpreter_frame_result has a dependency on how the
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // method result is saved across the call to post_method_exit. If this
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // is changed then the interpreter_frame_result implementation will
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // need to be updated too.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1471
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1472 // For c++ interpreter the result is always stored at a known location in the frame
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1473 // template interpreter will leave it on the top of the stack.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1474 NOT_CC_INTERP(push(state);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 testl(rdx, rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 jcc(Assembler::zero, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 call_VM(noreg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit));
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1481 NOT_CC_INTERP(pop(state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1483
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 SkipIfEqual skip(this, &DTraceMethodProbes, false);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1486 NOT_CC_INTERP(push(state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 get_method(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 r15_thread, c_rarg1);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1490 NOT_CC_INTERP(pop(state));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 }
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1493
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1494 // Jump if ((*counter_addr += increment) & mask) satisfies the condition.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1495 void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1496 int increment, int mask,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1497 Register scratch, bool preloaded,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1498 Condition cond, Label* where) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1499 if (!preloaded) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1500 movl(scratch, counter_addr);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1501 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1502 incrementl(scratch, increment);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1503 movl(counter_addr, scratch);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1504 andl(scratch, mask);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1505 jcc(cond, *where);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
1506 }