annotate src/cpu/x86/vm/stubGenerator_x86_64.cpp @ 3096:8073f5ad1d87

IdealGraphVisualizer: Rename predecessors to "Nodes Above" and successors to "Nodes Below" and actions "Expand Predecessors" and "Expand Successors" to "Expand Above" and "Expand Below" to avoid ambiguity with the Graal concept of successors and predecessors
author Peter Hofer <peter.hofer@jku.at>
date Wed, 29 Jun 2011 18:27:14 +0200
parents 348c0df561a9
children 38fa55e5e792
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2 * Copyright (c) 2003, 2011, 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: 1763
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
26 #include "asm/assembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
27 #include "assembler_x86.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
28 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
29 #include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
30 #include "oops/instanceOop.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
31 #include "oops/methodOop.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
32 #include "oops/objArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
33 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
34 #include "prims/methodHandles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
35 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
36 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
37 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
38 #include "runtime/stubCodeGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
39 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
40 #include "utilities/top.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
41 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
42 # include "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
43 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
44 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
45 # include "thread_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
46 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
47 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
48 # include "thread_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
49 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
50 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
51 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1763
diff changeset
52 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // Declaration and definition of StubGenerator (no .hpp file).
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // For a more detailed description of the stub routine structure
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // see the comment in stubRoutines.hpp
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58 #define __ _masm->
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
59 #define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
60 #define a__ ((Assembler*)_masm)->
0
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
63 #define BLOCK_COMMENT(str) /* nothing */
a61af66fc99e Initial load
duke
parents:
diff changeset
64 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
65 #define BLOCK_COMMENT(str) __ block_comment(str)
a61af66fc99e Initial load
duke
parents:
diff changeset
66 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
a61af66fc99e Initial load
duke
parents:
diff changeset
69 const int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // Stub Code definitions
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 static address handle_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 address pc = thread->saved_exception_pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // pc is the instruction which we must emulate
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // doing a no-op is fine: return garbage from the load
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // therefore, compute npc
a61af66fc99e Initial load
duke
parents:
diff changeset
79 address npc = Assembler::locate_next_instruction(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // request an async exception
a61af66fc99e Initial load
duke
parents:
diff changeset
82 thread->set_pending_unsafe_access_error();
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // return address of next instruction to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
85 return npc;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 class StubGenerator: public StubCodeGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
92 #define inc_counter_np(counter) (0)
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
94 void inc_counter_np_(int& counter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 __ incrementl(ExternalAddress((address)&counter));
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 #define inc_counter_np(counter) \
a61af66fc99e Initial load
duke
parents:
diff changeset
98 BLOCK_COMMENT("inc_counter " #counter); \
a61af66fc99e Initial load
duke
parents:
diff changeset
99 inc_counter_np_(counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Call stubs are used to call Java from C
a61af66fc99e Initial load
duke
parents:
diff changeset
103 //
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // Linux Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // c_rarg0: call wrapper address address
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // c_rarg1: result address
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // c_rarg2: result type BasicType
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // c_rarg3: method methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // c_rarg4: (interpreter) entry point address
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // c_rarg5: parameters intptr_t*
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // 16(rbp): parameter size (in words) int
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // 24(rbp): thread Thread*
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // -12 [ argument word 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // -11 [ saved r15 ] <--- rsp_after_call
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // -10 [ saved r14 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // -9 [ saved r13 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // -8 [ saved r12 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // -7 [ saved rbx ]
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // -6 [ call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // -5 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // -4 [ result type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // -3 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // -2 [ entry point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // -1 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // 0 [ saved rbp ] <--- rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // 2 [ parameter size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // 3 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
133 //
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // Windows Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // c_rarg0: call wrapper address address
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // c_rarg1: result address
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // c_rarg2: result type BasicType
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // c_rarg3: method methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // 48(rbp): (interpreter) entry point address
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // 56(rbp): parameters intptr_t*
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // 64(rbp): parameter size (in words) int
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // 72(rbp): thread Thread*
a61af66fc99e Initial load
duke
parents:
diff changeset
143 //
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // ...
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
147 // -28 [ argument word 1 ]
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
148 // -27 [ saved xmm15 ] <--- rsp_after_call
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
149 // [ saved xmm7-xmm14 ]
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
150 // -9 [ saved xmm6 ] (each xmm register takes 2 slots)
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
151 // -7 [ saved r15 ]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // -6 [ saved r14 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // -5 [ saved r13 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // -4 [ saved r12 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // -3 [ saved rdi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // -2 [ saved rsi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // -1 [ saved rbx ]
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // 0 [ saved rbp ] <--- rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // 2 [ call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // 3 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // 4 [ result type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // 5 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // 6 [ entry point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // 7 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // 8 [ parameter size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // 9 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
168 //
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // Windows reserves the callers stack space for arguments 1-4.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // We spill c_rarg0-c_rarg3 to this space.
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Call stub stack layout word offsets from rbp
a61af66fc99e Initial load
duke
parents:
diff changeset
173 enum call_stub_layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 #ifdef _WIN64
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
175 xmm_save_first = 6, // save from xmm6
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
176 xmm_save_last = 15, // to xmm15
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
177 xmm_save_base = -9,
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
178 rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
179 r15_off = -7,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
180 r14_off = -6,
a61af66fc99e Initial load
duke
parents:
diff changeset
181 r13_off = -5,
a61af66fc99e Initial load
duke
parents:
diff changeset
182 r12_off = -4,
a61af66fc99e Initial load
duke
parents:
diff changeset
183 rdi_off = -3,
a61af66fc99e Initial load
duke
parents:
diff changeset
184 rsi_off = -2,
a61af66fc99e Initial load
duke
parents:
diff changeset
185 rbx_off = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
186 rbp_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
187 retaddr_off = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
188 call_wrapper_off = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
189 result_off = 3,
a61af66fc99e Initial load
duke
parents:
diff changeset
190 result_type_off = 4,
a61af66fc99e Initial load
duke
parents:
diff changeset
191 method_off = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
192 entry_point_off = 6,
a61af66fc99e Initial load
duke
parents:
diff changeset
193 parameters_off = 7,
a61af66fc99e Initial load
duke
parents:
diff changeset
194 parameter_size_off = 8,
a61af66fc99e Initial load
duke
parents:
diff changeset
195 thread_off = 9
a61af66fc99e Initial load
duke
parents:
diff changeset
196 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
197 rsp_after_call_off = -12,
a61af66fc99e Initial load
duke
parents:
diff changeset
198 mxcsr_off = rsp_after_call_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
199 r15_off = -11,
a61af66fc99e Initial load
duke
parents:
diff changeset
200 r14_off = -10,
a61af66fc99e Initial load
duke
parents:
diff changeset
201 r13_off = -9,
a61af66fc99e Initial load
duke
parents:
diff changeset
202 r12_off = -8,
a61af66fc99e Initial load
duke
parents:
diff changeset
203 rbx_off = -7,
a61af66fc99e Initial load
duke
parents:
diff changeset
204 call_wrapper_off = -6,
a61af66fc99e Initial load
duke
parents:
diff changeset
205 result_off = -5,
a61af66fc99e Initial load
duke
parents:
diff changeset
206 result_type_off = -4,
a61af66fc99e Initial load
duke
parents:
diff changeset
207 method_off = -3,
a61af66fc99e Initial load
duke
parents:
diff changeset
208 entry_point_off = -2,
a61af66fc99e Initial load
duke
parents:
diff changeset
209 parameters_off = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
210 rbp_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 retaddr_off = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
212 parameter_size_off = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
213 thread_off = 3
a61af66fc99e Initial load
duke
parents:
diff changeset
214 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
215 };
a61af66fc99e Initial load
duke
parents:
diff changeset
216
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
217 #ifdef _WIN64
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
218 Address xmm_save(int reg) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
219 assert(reg >= xmm_save_first && reg <= xmm_save_last, "XMM register number out of range");
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
220 return Address(rbp, (xmm_save_base - (reg - xmm_save_first) * 2) * wordSize);
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
221 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
222 #endif
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
223
0
a61af66fc99e Initial load
duke
parents:
diff changeset
224 address generate_call_stub(address& return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 assert((int)frame::entry_frame_after_call_words == -(int)rsp_after_call_off + 1 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
226 (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
227 "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
228 StubCodeMark mark(this, "StubRoutines", "call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
229 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
232 const Address rsp_after_call(rbp, rsp_after_call_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 const Address call_wrapper (rbp, call_wrapper_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 const Address result (rbp, result_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 const Address result_type (rbp, result_type_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
237 const Address method (rbp, method_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 const Address entry_point (rbp, entry_point_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 const Address parameters (rbp, parameters_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 const Address parameter_size(rbp, parameter_size_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
243 const Address thread (rbp, thread_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 const Address r15_save(rbp, r15_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 const Address r14_save(rbp, r14_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 const Address r13_save(rbp, r13_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 const Address r12_save(rbp, r12_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
249 const Address rbx_save(rbp, rbx_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // stub code
a61af66fc99e Initial load
duke
parents:
diff changeset
252 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
253 __ subptr(rsp, -rsp_after_call_off * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // save register parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
256 #ifndef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
257 __ movptr(parameters, c_rarg5); // parameters
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
258 __ movptr(entry_point, c_rarg4); // entry_point
0
a61af66fc99e Initial load
duke
parents:
diff changeset
259 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
260
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
261 __ movptr(method, c_rarg3); // method
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
262 __ movl(result_type, c_rarg2); // result type
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
263 __ movptr(result, c_rarg1); // result
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
264 __ movptr(call_wrapper, c_rarg0); // call wrapper
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // save regs belonging to calling function
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
267 __ movptr(rbx_save, rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
268 __ movptr(r12_save, r12);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
269 __ movptr(r13_save, r13);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
270 __ movptr(r14_save, r14);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
271 __ movptr(r15_save, r15);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
272 #ifdef _WIN64
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
273 for (int i = 6; i <= 15; i++) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
274 __ movdqu(xmm_save(i), as_XMMRegister(i));
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
275 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
276
0
a61af66fc99e Initial load
duke
parents:
diff changeset
277 const Address rdi_save(rbp, rdi_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 const Address rsi_save(rbp, rsi_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
279
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
280 __ movptr(rsi_save, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
281 __ movptr(rdi_save, rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
282 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
283 const Address mxcsr_save(rbp, mxcsr_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 Label skip_ldmx;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
288 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
289 ExternalAddress mxcsr_std(StubRoutines::x86::mxcsr_std());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
290 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
291 __ jcc(Assembler::equal, skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
293 __ bind(skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // Load up thread register
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
298 __ movptr(r15_thread, thread);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
299 __ reinit_heapbase();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // make sure we have no pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
303 {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
305 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 __ stop("StubRoutines::call_stub: entered with pending exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
308 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // pass parameters if any
a61af66fc99e Initial load
duke
parents:
diff changeset
313 BLOCK_COMMENT("pass parameters if any");
a61af66fc99e Initial load
duke
parents:
diff changeset
314 Label parameters_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 __ movl(c_rarg3, parameter_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 __ testl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 __ jcc(Assembler::zero, parameters_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 Label loop;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
320 __ movptr(c_rarg2, parameters); // parameter pointer
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
321 __ movl(c_rarg1, c_rarg3); // parameter counter is in c_rarg1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
322 __ BIND(loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
323 __ movptr(rax, Address(c_rarg2, 0));// get parameter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
324 __ addptr(c_rarg2, wordSize); // advance to next parameter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
325 __ decrementl(c_rarg1); // decrement counter
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
326 __ push(rax); // pass parameter
0
a61af66fc99e Initial load
duke
parents:
diff changeset
327 __ jcc(Assembler::notZero, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // call Java function
a61af66fc99e Initial load
duke
parents:
diff changeset
330 __ BIND(parameters_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
331 __ movptr(rbx, method); // get methodOop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
332 __ movptr(c_rarg1, entry_point); // get entry_point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
333 __ mov(r13, rsp); // set sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
334 BLOCK_COMMENT("call Java function");
a61af66fc99e Initial load
duke
parents:
diff changeset
335 __ call(c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 BLOCK_COMMENT("call_stub_return_address:");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 return_address = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // store result depending on type (everything that is not
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
342 __ movptr(c_rarg0, result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
343 Label is_long, is_float, is_double, exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 __ movl(c_rarg1, result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 __ cmpl(c_rarg1, T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 __ cmpl(c_rarg1, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 __ cmpl(c_rarg1, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 __ jcc(Assembler::equal, is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
351 __ cmpl(c_rarg1, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 __ jcc(Assembler::equal, is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // handle T_INT case
a61af66fc99e Initial load
duke
parents:
diff changeset
355 __ movl(Address(c_rarg0, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 __ BIND(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // pop parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
360 __ lea(rsp, rsp_after_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
363 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
364 {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 Label L, S;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
366 __ cmpptr(r15_thread, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
367 __ jcc(Assembler::notEqual, S);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
369 __ cmpptr(r15_thread, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
370 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
371 __ bind(S);
a61af66fc99e Initial load
duke
parents:
diff changeset
372 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 __ stop("StubRoutines::call_stub: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
374 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // restore regs belonging to calling function
2407
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
379 #ifdef _WIN64
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
380 for (int i = 15; i >= 6; i--) {
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
381 __ movdqu(as_XMMRegister(i), xmm_save(i));
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
382 }
b1c22848507b 6741940: Nonvolatile XMM registers not preserved across JNI calls
iveresov
parents: 2324
diff changeset
383 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
384 __ movptr(r15, r15_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
385 __ movptr(r14, r14_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
386 __ movptr(r13, r13_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
387 __ movptr(r12, r12_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
388 __ movptr(rbx, rbx_save);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 #ifdef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
391 __ movptr(rdi, rdi_save);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
392 __ movptr(rsi, rsi_save);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
393 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
394 __ ldmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // restore rsp
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
398 __ addptr(rsp, -rsp_after_call_off * wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
401 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
402 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // handle return types different from T_INT
a61af66fc99e Initial load
duke
parents:
diff changeset
405 __ BIND(is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 __ movq(Address(c_rarg0, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
407 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 __ BIND(is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 __ movflt(Address(c_rarg0, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 __ BIND(is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
414 __ movdbl(Address(c_rarg0, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Return point for a Java call if there's an exception thrown in
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Java code. The exception is caught and transformed into a
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // pending exception stored in JavaThread that can be tested from
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // within the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
424 //
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // Note: Usually the parameters are removed by the callee. In case
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // of an exception crossing an activation frame boundary, that is
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // not the case if the callee is compiled code => need to setup the
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // rsp.
a61af66fc99e Initial load
duke
parents:
diff changeset
429 //
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // rax: exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 address generate_catch_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 StubCodeMark mark(this, "StubRoutines", "catch_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
434 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // same as in generate_call_stub():
a61af66fc99e Initial load
duke
parents:
diff changeset
437 const Address rsp_after_call(rbp, rsp_after_call_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 const Address thread (rbp, thread_off * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
442 {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 Label L, S;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
444 __ cmpptr(r15_thread, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
445 __ jcc(Assembler::notEqual, S);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
447 __ cmpptr(r15_thread, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
448 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 __ bind(S);
a61af66fc99e Initial load
duke
parents:
diff changeset
450 __ stop("StubRoutines::catch_exception: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
451 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // set pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
456 __ verify_oop(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
457
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
458 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
459 __ lea(rscratch1, ExternalAddress((address)__FILE__));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
460 __ movptr(Address(r15_thread, Thread::exception_file_offset()), rscratch1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
461 __ movl(Address(r15_thread, Thread::exception_line_offset()), (int) __LINE__);
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // complete return to VM
a61af66fc99e Initial load
duke
parents:
diff changeset
464 assert(StubRoutines::_call_stub_return_address != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
465 "_call_stub_return_address must have been generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
466 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address));
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // Continuation point for runtime calls returning with a pending
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // exception. The pending exception check happened in the runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // or native call stub. The pending exception in Thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // converted into a Java-level exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
475 //
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Contract with Java-level exception handlers:
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
479 //
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // NOTE: At entry of this stub, exception-pc must be on stack !!
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 address generate_forward_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 StubCodeMark mark(this, "StubRoutines", "forward exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
484 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Upon entry, the sp points to the return address returning into
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // Java (interpreted or compiled) code; i.e., the return address
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // becomes the throwing pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
489 //
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Arguments pushed before the runtime call are still on the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // but the exception handler will reset the stack pointer ->
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // ignore them. A potential result in registers can be ignored as
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // well.
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // make sure this code is only executed if there is a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
497 {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
499 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t) NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
500 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
501 __ stop("StubRoutines::forward exception: no pending exception (1)");
a61af66fc99e Initial load
duke
parents:
diff changeset
502 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // compute exception handler into rbx
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
507 __ movptr(c_rarg0, Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
508 BLOCK_COMMENT("call exception_handler_for_return_address");
a61af66fc99e Initial load
duke
parents:
diff changeset
509 __ call_VM_leaf(CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
510 SharedRuntime::exception_handler_for_return_address),
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
511 r15_thread, c_rarg0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
512 __ mov(rbx, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // setup rax & rdx, remove return address & clear pending exception
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
515 __ pop(rdx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
516 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
517 __ movptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // make sure exception is set
a61af66fc99e Initial load
duke
parents:
diff changeset
521 {
a61af66fc99e Initial load
duke
parents:
diff changeset
522 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
523 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
524 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 __ stop("StubRoutines::forward exception: no pending exception (2)");
a61af66fc99e Initial load
duke
parents:
diff changeset
526 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
528 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // continue at exception handler (return address removed)
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // rax: exception
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // rbx: exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
534 __ verify_oop(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 __ jmp(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Support for jint atomic::xchg(jint exchange_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
541 //
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // c_rarg0: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
545 //
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // *dest <- ex, return (orig *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
548 address generate_atomic_xchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 StubCodeMark mark(this, "StubRoutines", "atomic_xchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
550 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 __ movl(rax, c_rarg0); // Copy to eax we need a return value anyhow
a61af66fc99e Initial load
duke
parents:
diff changeset
553 __ xchgl(rax, Address(c_rarg1, 0)); // automatic LOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
554 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Support for intptr_t atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
560 //
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
564 //
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // *dest <- ex, return (orig *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
567 address generate_atomic_xchg_ptr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 StubCodeMark mark(this, "StubRoutines", "atomic_xchg_ptr");
a61af66fc99e Initial load
duke
parents:
diff changeset
569 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
570
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
571 __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
572 __ xchgptr(rax, Address(c_rarg1, 0)); // automatic LOCK
0
a61af66fc99e Initial load
duke
parents:
diff changeset
573 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // Support for jint atomic::atomic_cmpxchg(jint exchange_value, volatile jint* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // jint compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
580 //
a61af66fc99e Initial load
duke
parents:
diff changeset
581 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // c_rarg2: compare_value
a61af66fc99e Initial load
duke
parents:
diff changeset
585 //
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // if ( compare_value == *dest ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // *dest = exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // return compare_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
592 address generate_atomic_cmpxchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
594 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 __ movl(rax, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
598 __ cmpxchgl(c_rarg0, Address(c_rarg1, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
599 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Support for jint atomic::atomic_cmpxchg_long(jlong exchange_value,
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // volatile jlong* dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // jlong compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // c_rarg0: exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // c_rarg2: compare_value
a61af66fc99e Initial load
duke
parents:
diff changeset
611 //
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // if ( compare_value == *dest ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // *dest = exchange_value
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // return compare_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // else
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
618 address generate_atomic_cmpxchg_long() {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long");
a61af66fc99e Initial load
duke
parents:
diff changeset
620 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 __ movq(rax, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
624 __ cmpxchgq(c_rarg0, Address(c_rarg1, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
625 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // Support for jint atomic::add(jint add_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
631 //
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // c_rarg0: add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
635 //
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // *dest += add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 address generate_atomic_add() {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 StubCodeMark mark(this, "StubRoutines", "atomic_add");
a61af66fc99e Initial load
duke
parents:
diff changeset
641 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643 __ movl(rax, c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
644 if ( os::is_MP() ) __ lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
645 __ xaddl(Address(c_rarg1, 0), c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 __ addl(rax, c_rarg0);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // Support for intptr_t atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
653 //
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // c_rarg0: add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // c_rarg1: dest
a61af66fc99e Initial load
duke
parents:
diff changeset
657 //
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // *dest += add_value
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // return *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 address generate_atomic_add_ptr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
662 StubCodeMark mark(this, "StubRoutines", "atomic_add_ptr");
a61af66fc99e Initial load
duke
parents:
diff changeset
663 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
664
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
665 __ movptr(rax, c_rarg0); // Copy to eax we need a return value anyhow
0
a61af66fc99e Initial load
duke
parents:
diff changeset
666 if ( os::is_MP() ) __ lock();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
667 __ xaddptr(Address(c_rarg1, 0), c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
668 __ addptr(rax, c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
669 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // Support for intptr_t OrderAccess::fence()
a61af66fc99e Initial load
duke
parents:
diff changeset
675 //
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // Arguments :
a61af66fc99e Initial load
duke
parents:
diff changeset
677 //
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // Result:
a61af66fc99e Initial load
duke
parents:
diff changeset
679 address generate_orderaccess_fence() {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 StubCodeMark mark(this, "StubRoutines", "orderaccess_fence");
a61af66fc99e Initial load
duke
parents:
diff changeset
681 address start = __ pc();
671
d0994e5bebce 6822204: volatile fences should prefer lock:addl to actual mfence instructions
never
parents: 647
diff changeset
682 __ membar(Assembler::StoreLoad);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
683 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // Support for intptr_t get_previous_fp()
a61af66fc99e Initial load
duke
parents:
diff changeset
689 //
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // This routine is used to find the previous frame pointer for the
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // caller (current_frame_guess). This is used as part of debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // ps() is seemingly lost trying to find frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // This code assumes that caller current_frame_guess) has a frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
694 address generate_get_previous_fp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 StubCodeMark mark(this, "StubRoutines", "get_previous_fp");
a61af66fc99e Initial load
duke
parents:
diff changeset
696 const Address old_fp(rbp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
697 const Address older_fp(rax, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
698 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
701 __ movptr(rax, old_fp); // callers fp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
702 __ movptr(rax, older_fp); // the frame for ps()
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
703 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
704 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // Support for void verify_mxcsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
711 //
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // MXCSR register to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 address generate_verify_mxcsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 StubCodeMark mark(this, "StubRoutines", "verify_mxcsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
718 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 const Address mxcsr_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 Label ok_ret;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
724 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
725 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
726 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
729 __ cmpl(rax, *(int *)(StubRoutines::x86::mxcsr_std()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
730 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 __ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");
a61af66fc99e Initial load
duke
parents:
diff changeset
733
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
734 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
737 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
738 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740
a61af66fc99e Initial load
duke
parents:
diff changeset
741 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 address generate_f2i_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 StubCodeMark mark(this, "StubRoutines", "f2i_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
748 Address inout(rsp, 5 * wordSize); // return address + 4 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
753
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
754 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
755 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
756 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
757 __ push(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 __ movl(rax, 0x7f800000);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 __ xorl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 __ movl(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 __ movl(c_rarg1, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 __ cmpl(rax, c_rarg1); // NaN? -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
765 __ jcc(Assembler::negative, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 __ testl(c_rarg2, c_rarg2); // signed ? min_jint : max_jint
a61af66fc99e Initial load
duke
parents:
diff changeset
767 __ movl(c_rarg3, 0x80000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
768 __ movl(rax, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 __ cmovl(Assembler::positive, c_rarg3, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
772 __ movptr(inout, c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
773
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
774 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
775 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
776 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
777 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 address generate_f2l_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
785 StubCodeMark mark(this, "StubRoutines", "f2l_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
786 Address inout(rsp, 5 * wordSize); // return address + 4 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
787 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
790
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
791 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
792 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
793 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
794 __ push(c_rarg1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 __ movl(rax, 0x7f800000);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 __ xorl(c_rarg3, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 __ movl(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 __ movl(c_rarg1, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
800 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 __ cmpl(rax, c_rarg1); // NaN? -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
802 __ jcc(Assembler::negative, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 __ testl(c_rarg2, c_rarg2); // signed ? min_jlong : max_jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
804 __ mov64(c_rarg3, 0x8000000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
805 __ mov64(rax, 0x7fffffffffffffff);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
806 __ cmov(Assembler::positive, c_rarg3, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
809 __ movptr(inout, c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
810
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
811 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
812 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
813 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
814 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 address generate_d2i_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 StubCodeMark mark(this, "StubRoutines", "d2i_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
823 Address inout(rsp, 6 * wordSize); // return address + 5 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
828
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
829 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
830 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
831 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
832 __ push(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
833 __ push(c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 __ movl(rax, 0x7ff00000);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 __ movq(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 __ movl(c_rarg3, c_rarg2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
838 __ mov(c_rarg1, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
839 __ mov(c_rarg0, c_rarg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
840 __ negl(c_rarg3);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
841 __ shrptr(c_rarg1, 0x20);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
842 __ orl(c_rarg3, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
843 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
844 __ xorl(c_rarg2, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
845 __ shrl(c_rarg3, 0x1f);
a61af66fc99e Initial load
duke
parents:
diff changeset
846 __ orl(c_rarg1, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 __ cmpl(rax, c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 __ jcc(Assembler::negative, L); // NaN -> 0
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
849 __ testptr(c_rarg0, c_rarg0); // signed ? min_jint : max_jint
0
a61af66fc99e Initial load
duke
parents:
diff changeset
850 __ movl(c_rarg2, 0x80000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 __ movl(rax, 0x7fffffff);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
852 __ cmov(Assembler::positive, c_rarg2, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 __ bind(L);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
855 __ movptr(inout, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
856
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
857 __ pop(c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
858 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
859 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
860 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
861 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 address generate_d2l_fixup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 StubCodeMark mark(this, "StubRoutines", "d2l_fixup");
a61af66fc99e Initial load
duke
parents:
diff changeset
870 Address inout(rsp, 6 * wordSize); // return address + 5 saves
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
873
a61af66fc99e Initial load
duke
parents:
diff changeset
874 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
875
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
876 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
877 __ push(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
878 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
879 __ push(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
880 __ push(c_rarg0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 __ movl(rax, 0x7ff00000);
a61af66fc99e Initial load
duke
parents:
diff changeset
883 __ movq(c_rarg2, inout);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 __ movl(c_rarg3, c_rarg2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
885 __ mov(c_rarg1, c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
886 __ mov(c_rarg0, c_rarg2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
887 __ negl(c_rarg3);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
888 __ shrptr(c_rarg1, 0x20);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
889 __ orl(c_rarg3, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
890 __ andl(c_rarg1, 0x7fffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
891 __ xorl(c_rarg2, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 __ shrl(c_rarg3, 0x1f);
a61af66fc99e Initial load
duke
parents:
diff changeset
893 __ orl(c_rarg1, c_rarg3);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 __ cmpl(rax, c_rarg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 __ jcc(Assembler::negative, L); // NaN -> 0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 __ testq(c_rarg0, c_rarg0); // signed ? min_jlong : max_jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
897 __ mov64(c_rarg2, 0x8000000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 __ mov64(rax, 0x7fffffffffffffff);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 __ cmovq(Assembler::positive, c_rarg2, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 __ movq(inout, c_rarg2);
a61af66fc99e Initial load
duke
parents:
diff changeset
903
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
904 __ pop(c_rarg0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
905 __ pop(c_rarg1);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
906 __ pop(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
907 __ pop(c_rarg3);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
908 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914
a61af66fc99e Initial load
duke
parents:
diff changeset
915 address generate_fp_mask(const char *stub_name, int64_t mask) {
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
916 __ align(CodeEntryAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
917 StubCodeMark mark(this, "StubRoutines", stub_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 __ emit_data64( mask, relocInfo::none );
a61af66fc99e Initial load
duke
parents:
diff changeset
921 __ emit_data64( mask, relocInfo::none );
a61af66fc99e Initial load
duke
parents:
diff changeset
922
a61af66fc99e Initial load
duke
parents:
diff changeset
923 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
925
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // The following routine generates a subroutine to throw an
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // asynchronous UnknownError when an unsafe access gets a fault that
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // could not be reasonably prevented by the programmer. (Example:
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // SIGBUS/OBJERR.)
a61af66fc99e Initial load
duke
parents:
diff changeset
930 address generate_handler_for_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
932 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
933
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
934 __ push(0); // hole for return address-to-be
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
935 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
936 Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
937
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
938 __ subptr(rsp, frame::arg_reg_save_area_bytes);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
939 BLOCK_COMMENT("call handle_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
940 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
941 __ addptr(rsp, frame::arg_reg_save_area_bytes);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
942
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
943 __ movptr(next_pc, rax); // stuff next address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
944 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 __ ret(0); // jump to next address
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Non-destructive plausibility checks for oops
a61af66fc99e Initial load
duke
parents:
diff changeset
951 //
a61af66fc99e Initial load
duke
parents:
diff changeset
952 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // all args on stack!
a61af66fc99e Initial load
duke
parents:
diff changeset
954 //
a61af66fc99e Initial load
duke
parents:
diff changeset
955 // Stack after saving c_rarg3:
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // [tos + 0]: saved c_rarg3
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // [tos + 1]: saved c_rarg2
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
958 // [tos + 2]: saved r12 (several TemplateTable methods use it)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
959 // [tos + 3]: saved flags
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
960 // [tos + 4]: return address
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
961 // * [tos + 5]: error message (char*)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
962 // * [tos + 6]: object to verify (oop)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
963 // * [tos + 7]: saved rax - saved by caller and bashed
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
964 // * [tos + 8]: saved r10 (rscratch1) - saved by caller
0
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // * = popped on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
966 address generate_verify_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 StubCodeMark mark(this, "StubRoutines", "verify_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
968 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970 Label exit, error;
a61af66fc99e Initial load
duke
parents:
diff changeset
971
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
972 __ pushf();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
974
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
975 __ push(r12);
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
976
0
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // save c_rarg2 and c_rarg3
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
978 __ push(c_rarg2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
979 __ push(c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
980
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
981 enum {
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
982 // After previous pushes.
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
983 oop_to_verify = 6 * wordSize,
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
984 saved_rax = 7 * wordSize,
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
985 saved_r10 = 8 * wordSize,
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
986
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
987 // Before the call to MacroAssembler::debug(), see below.
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
988 return_addr = 16 * wordSize,
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
989 error_msg = 17 * wordSize
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
990 };
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
991
0
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // get object
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
993 __ movptr(rax, Address(rsp, oop_to_verify));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // make sure object is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
996 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
997 __ jcc(Assembler::zero, exit); // if obj is NULL it is OK
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // Check if the oop is in the right area of memory
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
999 __ movptr(c_rarg2, rax);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1000 __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1001 __ andptr(c_rarg2, c_rarg3);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1002 __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1003 __ cmpptr(c_rarg2, c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1006 // set r12 to heapbase for load_klass()
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1007 __ reinit_heapbase();
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1008
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // make sure klass is 'reasonable'
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1010 __ load_klass(rax, rax); // get klass
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1011 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 __ jcc(Assembler::zero, error); // if klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // Check if the klass is in the right area of memory
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1014 __ mov(c_rarg2, rax);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1015 __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1016 __ andptr(c_rarg2, c_rarg3);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1017 __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1018 __ cmpptr(c_rarg2, c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // make sure klass' klass is 'reasonable'
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1022 __ load_klass(rax, rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1023 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // Check if the klass' klass is in the right area of memory
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1026 __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1027 __ andptr(rax, c_rarg3);
512
db4caa99ef11 6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents: 405
diff changeset
1028 __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1029 __ cmpptr(rax, c_rarg3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // return if everything seems ok
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 __ bind(exit);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1034 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1035 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1036 __ pop(c_rarg3); // restore c_rarg3
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1037 __ pop(c_rarg2); // restore c_rarg2
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1038 __ pop(r12); // restore r12
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1039 __ popf(); // restore flags
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1040 __ ret(4 * wordSize); // pop caller saved stuff
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // handle errors
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 __ bind(error);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1044 __ movptr(rax, Address(rsp, saved_rax)); // get saved rax back
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1045 __ movptr(rscratch1, Address(rsp, saved_r10)); // get saved r10 back
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1046 __ pop(c_rarg3); // get saved c_rarg3 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1047 __ pop(c_rarg2); // get saved c_rarg2 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1048 __ pop(r12); // get saved r12 back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1049 __ popf(); // get saved flags off stack --
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // will be ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1051
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1052 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // (rip is already
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 // already pushed)
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1055 // debug(char* msg, int64_t pc, int64_t regs[])
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // We've popped the registers we'd saved (c_rarg3, c_rarg2 and flags), and
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // pushed all the registers, so now the stack looks like:
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // [tos + 0] 16 saved registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // [tos + 16] return address
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1060 // * [tos + 17] error message (char*)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1061 // * [tos + 18] object to verify (oop)
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1062 // * [tos + 19] saved rax - saved by caller and bashed
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1063 // * [tos + 20] saved r10 (rscratch1) - saved by caller
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1064 // * = popped on exit
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1065
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1066 __ movptr(c_rarg0, Address(rsp, error_msg)); // pass address of error message
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1067 __ movptr(c_rarg1, Address(rsp, return_addr)); // pass return address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1068 __ movq(c_rarg2, rsp); // pass address of regs on stack
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1069 __ mov(r12, rsp); // remember rsp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1070 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1071 __ andptr(rsp, -16); // align stack as required by ABI
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 BLOCK_COMMENT("call MacroAssembler::debug");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1073 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1074 __ mov(rsp, r12); // restore rsp
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1075 __ popa(); // pop registers (includes r12)
1583
02e771df338e 6958254: -XX:+VerifyOops is broken on x86
kvn
parents: 1552
diff changeset
1076 __ ret(4 * wordSize); // pop caller saved stuff
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // Verify that a register contains clean 32-bits positive value
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // (high 32-bits are 0) so it could be used in 64-bits shifts.
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // Rint - 32-bits value
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // Rtmp - scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 void assert_clean_int(Register Rint, Register Rtmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 assert_different_registers(Rtmp, Rint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 __ movslq(Rtmp, Rint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 __ cmpq(Rtmp, Rint);
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 113
diff changeset
1095 __ jcc(Assembler::equal, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 __ stop("high 32-bits of int value are not 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // Generate overlap test for array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // c_rarg0 - from
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // c_rarg1 - to
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // c_rarg2 - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // rax - &from[element count - 1]
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 void array_overlap_test(address no_overlap_target, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 assert(no_overlap_target != NULL, "must be generated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 array_overlap_test(no_overlap_target, NULL, sf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 void array_overlap_test(Label& L_no_overlap, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 array_overlap_test(NULL, &L_no_overlap, sf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 void array_overlap_test(address no_overlap_target, Label* NOLp, Address::ScaleFactor sf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 const Register from = c_rarg0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 const Register to = c_rarg1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 const Register count = c_rarg2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 const Register end_from = rax;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1124 __ cmpptr(to, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1125 __ lea(end_from, Address(from, count, sf, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 if (NOLp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 ExternalAddress no_overlap(no_overlap_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 __ jump_cc(Assembler::belowEqual, no_overlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1129 __ cmpptr(to, end_from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 __ jump_cc(Assembler::aboveEqual, no_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 __ jcc(Assembler::belowEqual, (*NOLp));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1133 __ cmpptr(to, end_from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 __ jcc(Assembler::aboveEqual, (*NOLp));
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1137
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // Shuffle first three arg regs on Windows into Linux/Solaris locations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // Outputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // rdi - rcx
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // rsi - rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // rdx - r8
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // rcx - r9
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // Registers r9 and r10 are used to save rdi and rsi on Windows, which latter
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // are non-volatile. r9 and r10 should not be used by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 void setup_arg_regs(int nargs = 3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 const Register saved_rdi = r9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 const Register saved_rsi = r10;
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 assert(nargs == 3 || nargs == 4, "else fix");
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 assert(c_rarg0 == rcx && c_rarg1 == rdx && c_rarg2 == r8 && c_rarg3 == r9,
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 "unexpected argument registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 if (nargs >= 4)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1157 __ mov(rax, r9); // r9 is also saved_rdi
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1158 __ movptr(saved_rdi, rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1159 __ movptr(saved_rsi, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1160 __ mov(rdi, rcx); // c_rarg0
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1161 __ mov(rsi, rdx); // c_rarg1
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1162 __ mov(rdx, r8); // c_rarg2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (nargs >= 4)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1164 __ mov(rcx, rax); // c_rarg3 (via rax)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 assert(c_rarg0 == rdi && c_rarg1 == rsi && c_rarg2 == rdx && c_rarg3 == rcx,
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 "unexpected argument registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 void restore_arg_regs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 const Register saved_rdi = r9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 const Register saved_rsi = r10;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 #ifdef _WIN64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1175 __ movptr(rdi, saved_rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1176 __ movptr(rsi, saved_rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1179
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // Generate code for an array write pre barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // addr - starting address
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1183 // count - element count
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1184 // tmp - scratch register
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // Destroy no registers!
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1188 void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 case BarrierSet::G1SATBCTLogging:
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1193 // With G1, don't generate the call if we statically know that the target in uninitialized
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1194 if (!dest_uninitialized) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1195 __ pusha(); // push registers
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1196 if (count == c_rarg0) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1197 if (addr == c_rarg1) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1198 // exactly backwards!!
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1199 __ xchgptr(c_rarg1, c_rarg0);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1200 } else {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1201 __ movptr(c_rarg1, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1202 __ movptr(c_rarg0, addr);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1203 }
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1204 } else {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1205 __ movptr(c_rarg0, addr);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1206 __ movptr(c_rarg1, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1207 }
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1208 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1209 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1211 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 break;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1216 default:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1221
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // Generate code for an array write post barrier
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // start - register containing starting address of destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // end - register containing ending address of destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // scratch - scratch register
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // The input registers are overwritten.
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // The ending address is inclusive.
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 assert_different_registers(start, end, scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 case BarrierSet::G1SATBCTLogging:
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1240 __ pusha(); // push registers (overkill)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 // must compute element count unless barrier set interface is changed (other platforms supply count)
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 assert_different_registers(start, end, scratch);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
1243 __ lea(scratch, Address(end, BytesPerHeapOop));
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
1244 __ subptr(scratch, start); // subtract start to get #bytes
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
1245 __ shrptr(scratch, LogBytesPerHeapOop); // convert to element count
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1246 __ mov(c_rarg0, start);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1247 __ mov(c_rarg1, scratch);
1192
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
1248 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1249 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 Label L_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1260 __ shrptr(start, CardTableModRefBS::card_shift);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
1261 __ addptr(end, BytesPerHeapOop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1262 __ shrptr(end, CardTableModRefBS::card_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1263 __ subptr(end, start); // number of bytes to copy
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
249
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1265 intptr_t disp = (intptr_t) ct->byte_map_base;
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1266 if (__ is_simm32(disp)) {
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1267 Address cardtable(noreg, noreg, Address::no_scale, disp);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1268 __ lea(scratch, cardtable);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1269 } else {
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1270 ExternalAddress cardtable((address)disp);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1271 __ lea(scratch, cardtable);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1272 }
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 196
diff changeset
1273
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 const Register count = end; // 'end' register contains bytes count now
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1275 __ addptr(start, scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 __ BIND(L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 __ movb(Address(start, count, Address::times_1), 0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1278 __ decrement(count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 __ jcc(Assembler::greaterEqual, L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1281 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1282 default:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1283 ShouldNotReachHere();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1284
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1285 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 124
diff changeset
1286 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1287
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1288
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // Copy big chunks forward
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // end_from - source arrays end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // end_to - destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // qword_count - 64-bits element count, negative
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // to - scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // L_copy_32_bytes - entry label
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 // L_copy_8_bytes - exit label
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 void copy_32_bytes_forward(Register end_from, Register end_to,
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 Register qword_count, Register to,
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 DEBUG_ONLY(__ stop("enter at entry label, not here"));
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 Label L_loop;
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1304 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 __ BIND(L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1306 if(UseUnalignedLoadStores) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1307 __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1308 __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1309 __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, - 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1310 __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm1);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1311
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1312 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1313 __ movq(to, Address(end_from, qword_count, Address::times_8, -24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1314 __ movq(Address(end_to, qword_count, Address::times_8, -24), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1315 __ movq(to, Address(end_from, qword_count, Address::times_8, -16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1316 __ movq(Address(end_to, qword_count, Address::times_8, -16), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1317 __ movq(to, Address(end_from, qword_count, Address::times_8, - 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1318 __ movq(Address(end_to, qword_count, Address::times_8, - 8), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1319 __ movq(to, Address(end_from, qword_count, Address::times_8, - 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1320 __ movq(Address(end_to, qword_count, Address::times_8, - 0), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1321 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 __ BIND(L_copy_32_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1323 __ addptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 __ jcc(Assembler::lessEqual, L_loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1325 __ subptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 __ jcc(Assembler::less, L_copy_8_bytes); // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // Copy big chunks backward
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // from - source arrays address
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 // dest - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // qword_count - 64-bits element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // to - scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 // L_copy_32_bytes - entry label
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // L_copy_8_bytes - exit label
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 void copy_32_bytes_backward(Register from, Register dest,
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 Register qword_count, Register to,
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 Label& L_copy_32_bytes, Label& L_copy_8_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 DEBUG_ONLY(__ stop("enter at entry label, not here"));
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 Label L_loop;
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1345 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 __ BIND(L_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1347 if(UseUnalignedLoadStores) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1348 __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1349 __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1350 __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1351 __ movdqu(Address(dest, qword_count, Address::times_8, 0), xmm1);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1352
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1353 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1354 __ movq(to, Address(from, qword_count, Address::times_8, 24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1355 __ movq(Address(dest, qword_count, Address::times_8, 24), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1356 __ movq(to, Address(from, qword_count, Address::times_8, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1357 __ movq(Address(dest, qword_count, Address::times_8, 16), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1358 __ movq(to, Address(from, qword_count, Address::times_8, 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1359 __ movq(Address(dest, qword_count, Address::times_8, 8), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1360 __ movq(to, Address(from, qword_count, Address::times_8, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1361 __ movq(Address(dest, qword_count, Address::times_8, 0), to);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1362 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 __ BIND(L_copy_32_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1364 __ subptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 __ jcc(Assembler::greaterEqual, L_loop);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1366 __ addptr(qword_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 __ jcc(Assembler::greater, L_copy_8_bytes); // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
a61af66fc99e Initial load
duke
parents:
diff changeset
1370
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // we let the hardware handle it. The one to eight bytes within words,
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // dwords or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // disjoint_byte_copy_entry is set to the no-overlap entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // used by generate_conjoint_byte_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1390 address generate_disjoint_byte_copy(bool aligned, address* entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 Label L_copy_byte, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 const Register byte_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 const Register end_to = to; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1406
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1409
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1410 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1411 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1412 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1413 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1414 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1418
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1420 __ movptr(byte_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1421 __ shrptr(count, 3); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1422
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1424 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1425 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1426 __ negptr(qword_count); // make the count negative
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1428
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1433 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1438 __ testl(byte_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1443 __ addptr(end_from, 4);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1444 __ addptr(end_to, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1448 __ testl(byte_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 __ movw(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 __ movw(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1452
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1453 __ addptr(end_from, 2);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1454 __ addptr(end_to, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // Check for and copy trailing byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 __ BIND(L_copy_byte);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1458 __ testl(byte_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 __ movb(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 __ movb(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1466 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1469
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 // If 'from' and/or 'to' are aligned on 4-, 2-, or 1-byte boundaries,
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // we let the hardware handle it. The one to eight bytes within words,
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // dwords or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1492 address generate_conjoint_byte_copy(bool aligned, address nooverlap_target,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1493 address* entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1497
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 const Register byte_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1508 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1509 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1510 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1511 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1512 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1513
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1514 array_overlap_test(nooverlap_target, Address::times_1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1517
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1519 __ movptr(byte_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1520 __ shrptr(count, 3); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // Copy from high to low addresses.
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // Check for and copy trailing byte
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1525 __ testl(byte_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 __ jcc(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 __ movb(rax, Address(from, byte_count, Address::times_1, -1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 __ movb(Address(to, byte_count, Address::times_1, -1), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1529 __ decrement(byte_count); // Adjust for possible trailing word
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1530
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1533 __ testl(byte_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 __ jcc(Assembler::zero, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 __ movw(rax, Address(from, byte_count, Address::times_1, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 __ movw(Address(to, byte_count, Address::times_1, -2), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1540 __ testl(byte_count, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 __ jcc(Assembler::zero, L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 __ movl(rax, Address(from, qword_count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 __ movl(Address(to, qword_count, Address::times_8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1545
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1550 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1552
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1555 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1558
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1561
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1564 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1570
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // let the hardware handle it. The two or four words within dwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // disjoint_short_copy_entry is set to the no-overlap entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // used by generate_conjoint_short_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1590 address generate_disjoint_short_copy(bool aligned, address *entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 const Register word_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 const Register end_to = to; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1608
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1609 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1610 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1611 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1612 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1613 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1614
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1619 __ movptr(word_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1620 __ shrptr(count, 2); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1623 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1624 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1625 __ negptr(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1632 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1634
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // Original 'dest' is trashed, so we can't use it as a
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 // base register for a possible trailing word copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1637
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1640 __ testl(word_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1645 __ addptr(end_from, 4);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1646 __ addptr(end_to, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // Check for and copy trailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 __ BIND(L_copy_2_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1650 __ testl(word_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 __ movw(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 __ movw(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1654
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1658 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1661
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1669 address generate_fill(BasicType t, bool aligned, const char *name) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1670 __ align(CodeEntryAlignment);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1671 StubCodeMark mark(this, "StubRoutines", name);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1672 address start = __ pc();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1673
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1674 BLOCK_COMMENT("Entry:");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1675
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1676 const Register to = c_rarg0; // source array address
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1677 const Register value = c_rarg1; // value
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1678 const Register count = c_rarg2; // elements count
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1679
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1680 __ enter(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1681
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1682 __ generate_fill(t, aligned, to, value, count, rax, xmm0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1683
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1684 __ leave(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1685 __ ret(0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1686 return start;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1687 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
1688
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 // let the hardware handle it. The two or four words within dwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 // or qwords that span cache line boundaries will still be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 // and stored atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1704 address generate_conjoint_short_copy(bool aligned, address nooverlap_target,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1705 address *entry, const char *name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 const Register word_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1720 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1721 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1722 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1723 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1724 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1725
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1726 array_overlap_test(nooverlap_target, Address::times_2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1729
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1731 __ movptr(word_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1732 __ shrptr(count, 2); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // Copy from high to low addresses. Use 'to' as scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1735
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 // Check for and copy trailing word
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1737 __ testl(word_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 __ jccb(Assembler::zero, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 __ movw(rax, Address(from, word_count, Address::times_2, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 __ movw(Address(to, word_count, Address::times_2, -2), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1744 __ testl(word_count, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 __ jcc(Assembler::zero, L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 __ movl(rax, Address(from, qword_count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 __ movl(Address(to, qword_count, Address::times_8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1754 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1759 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1762
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 inc_counter_np(SharedRuntime::_jshort_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1768 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1771
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1774
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 // ignored
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1778 // is_oop - true => oop array, so generate store check code
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // the hardware handle it. The two dwords within qwords that span
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 // cache line boundaries will still be loaded and stored atomicly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // Side Effects:
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // disjoint_int_copy_entry is set to the no-overlap entry point
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1792 // used by generate_conjoint_int_oop_copy().
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1794 address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, address* entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1795 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1799
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 const Register dword_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 const Register end_to = to; // destination array end address
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1808 const Register saved_to = r11; // saved destination array address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1811
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1814
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1815 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1816 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1817 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1818 BLOCK_COMMENT("Entry:");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1819 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1820
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // r9 and r10 may be used to save non-volatile registers
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1823 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1824 __ movq(saved_to, to);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1825 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1826 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1827
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1829 __ movptr(dword_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1830 __ shrptr(count, 1); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1833 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1834 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1835 __ negptr(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1837
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1842 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 // Check for and copy trailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 __ BIND(L_copy_4_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1847 __ testl(dword_count, 1); // Only byte test since the value is 0 or 1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 __ movl(rax, Address(end_from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 __ movl(Address(end_to, 8), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 __ BIND(L_exit);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1853 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1854 __ leaq(end_to, Address(saved_to, dword_count, Address::times_4, -4));
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1855 gen_write_ref_array_post_barrier(saved_to, end_to, rax);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1856 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 inc_counter_np(SharedRuntime::_jint_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1859 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1862
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // Copy 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 __ jmp(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1866
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 // aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 // ignored
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1873 // is_oop - true => oop array, so generate store check code
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // the hardware handle it. The two dwords within qwords that span
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // cache line boundaries will still be loaded and stored atomicly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1885 address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, address nooverlap_target,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1886 address *entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1887 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1891
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1892 Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 const Register count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 const Register dword_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 const Register qword_count = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1898
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1901
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1902 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1903 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1904 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1905 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1906 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1907
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1908 array_overlap_test(nooverlap_target, Address::times_4);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1909 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1910 // r9 and r10 may be used to save non-volatile registers
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
1911
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1912 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1913 // no registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1914 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1915 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1916
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1917 assert_clean_int(count, rax); // Make sure 'count' is clean int.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // 'from', 'to' and 'count' are now valid
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1919 __ movptr(dword_count, count);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1920 __ shrptr(count, 1); // count => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1921
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // Copy from high to low addresses. Use 'to' as scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1923
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 // Check for and copy trailing dword
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1925 __ testl(dword_count, 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 __ jcc(Assembler::zero, L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 __ movl(rax, Address(from, dword_count, Address::times_4, -4));
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 __ movl(Address(to, dword_count, Address::times_4, -4), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1930
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1935 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1937
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 inc_counter_np(SharedRuntime::_jint_array_copy_ctr);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1939 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1940 __ jmp(L_exit);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1941 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1943 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1946
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1950 inc_counter_np(SharedRuntime::_jint_array_copy_ctr);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1951 __ bind(L_exit);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1952 if (is_oop) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1953 Register end_to = rdx;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1954 __ leaq(end_to, Address(to, dword_count, Address::times_4, -4));
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1955 gen_write_ref_array_post_barrier(to, end_to, rax);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1956 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1958 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // is_oop - true => oop array, so generate store check code
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 //
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
1976 // Side Effects:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 // disjoint_oop_copy_entry or disjoint_long_copy_entry is set to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 // no-overlap entry point used by generate_conjoint_long_oop_copy().
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1980 address generate_disjoint_long_oop_copy(bool aligned, bool is_oop, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
1981 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1985
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 const Register qword_count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 const Register end_to = rcx; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 const Register saved_to = to;
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // End pointers are inclusive, and if count is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
1995
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // Save no-overlap entry point for generate_conjoint_long_oop_copy()
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1999
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2000 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2001 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2002 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2003 BLOCK_COMMENT("Entry:");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 // 'from', 'to' and 'qword_count' are now valid
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2009 if (is_oop) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2010 // no registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2011 gen_write_ref_array_pre_barrier(to, qword_count, dest_uninitialized);
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2012 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2013
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 // Copy from low to high addresses. Use 'to' as scratch.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2015 __ lea(end_from, Address(from, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2016 __ lea(end_to, Address(to, qword_count, Address::times_8, -8));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2017 __ negptr(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2019
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 __ movq(rax, Address(end_from, qword_count, Address::times_8, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 __ movq(Address(end_to, qword_count, Address::times_8, 8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2024 __ increment(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 __ jmp(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2032 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2036
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // Copy 64-byte chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 copy_32_bytes_forward(end_from, end_to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2039
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 gen_write_ref_array_post_barrier(saved_to, end_to, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 inc_counter_np(SharedRuntime::_oop_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2048 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2051
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2054
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 // Arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 // aligned - true => Input and output aligned on a HeapWord boundary == 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 // ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 // is_oop - true => oop array, so generate store check code
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 // name - stub name string
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2066 address generate_conjoint_long_oop_copy(bool aligned, bool is_oop,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2067 address nooverlap_target, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2068 const char *name, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2072
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 Label L_copy_32_bytes, L_copy_8_bytes, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 const Register qword_count = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 const Register saved_count = rcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
2078
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2082 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2083 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2084 // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2085 BLOCK_COMMENT("Entry:");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2087
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2088 array_overlap_test(nooverlap_target, Address::times_8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 setup_arg_regs(); // from => rdi, to => rsi, count => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 // 'from', 'to' and 'qword_count' are now valid
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // Save to and count for store barrier
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2094 __ movptr(saved_count, qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // No registers are destroyed by this call
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2096 gen_write_ref_array_pre_barrier(to, saved_count, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2098
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 __ jmp(L_copy_32_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 // Copy trailing qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 __ movq(rax, Address(from, qword_count, Address::times_8, -8));
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 __ movq(Address(to, qword_count, Address::times_8, -8), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2105 __ decrement(qword_count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 __ jcc(Assembler::notZero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2107
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 __ jmp(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2113 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2117
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 // Copy in 32-bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 copy_32_bytes_backward(from, to, qword_count, rax, L_copy_32_bytes, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 if (is_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 __ BIND(L_exit);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2123 __ lea(rcx, Address(to, saved_count, Address::times_8, -8));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 gen_write_ref_array_post_barrier(to, rcx, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 inc_counter_np(SharedRuntime::_oop_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 inc_counter_np(SharedRuntime::_jlong_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 restore_arg_regs();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2130 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2133
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 // Helper for generating a dynamic type check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 // Smashes no registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 void generate_type_check(Register sub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 Register super_check_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 Register super_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 Label& L_success) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 assert_different_registers(sub_klass, super_check_offset, super_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2145
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 BLOCK_COMMENT("type_check:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2147
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 Label L_miss;
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2150 __ check_klass_subtype_fast_path(sub_klass, super_klass, noreg, &L_success, &L_miss, NULL,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2151 super_check_offset);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 512
diff changeset
2152 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg, &L_success, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2153
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 // Fall through on failure!
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 __ BIND(L_miss);
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2157
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // Generate checkcasting array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // c_rarg2 - element count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // c_rarg3 - size_t ckoff (super_check_offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // not Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // c_rarg4 - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // rsp+40 - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // rax == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // rax == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2175 address generate_checkcast_copy(const char *name, address *entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2176 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2177
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 Label L_load_element, L_store_element, L_do_card_marks, L_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
2179
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // Input registers (after setup_arg_regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 const Register from = rdi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 const Register to = rsi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 const Register length = rdx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 const Register ckoff = rcx; // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 const Register ckval = r8; // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2186
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 // Registers used as temps (r13, r14 are save-on-entry)
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 const Register end_from = from; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 const Register end_to = r13; // destination array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 const Register count = rdx; // -(count_remaining)
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 const Register r14_length = r14; // saved copy of length
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // End pointers are inclusive, and if length is not zero they point
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // to the last unit copied: end_to[0] := end_from[0]
a61af66fc99e Initial load
duke
parents:
diff changeset
2194
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 const Register rax_oop = rax; // actual oop copied
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 const Register r11_klass = r11; // oop._klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2197
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 //---------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // if the two arrays are subtypes of Object[] but the
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // destination array type is not equal to or a supertype
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // of the source type. Each element must be separately
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 // checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
2204
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2208
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2210
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 // caller guarantees that the arrays really are different
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 // otherwise, we would have to make conjoint checks
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 { Label L;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2215 array_overlap_test(L, TIMES_OOP);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 __ stop("checkcast_copy within a single array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2220
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 setup_arg_regs(4); // from => rdi, to => rsi, length => rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // ckoff => rcx, ckval => r8
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 // r9 and r10 may be used to save non-volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 // last argument (#4) is on stack on Win64
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2226 __ movptr(ckval, Address(rsp, 6 * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2228
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2229 // Caller of this entry point must set up the argument registers.
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2230 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2231 *entry = __ pc();
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2232 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2233 }
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2234
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2235 // allocate spill slots for r13, r14
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2236 enum {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2237 saved_r13_offset,
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2238 saved_r14_offset,
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2239 saved_rbp_offset
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2240 };
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2241 __ subptr(rsp, saved_rbp_offset * wordSize);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2242 __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2243 __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2244
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 // check that int operands are properly extended to size_t
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 assert_clean_int(length, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 assert_clean_int(ckoff, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2248
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 BLOCK_COMMENT("assert consistent ckoff/ckval");
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // The ckoff and ckval must be mutually consistent,
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 // even though caller generates both.
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 Klass::super_check_offset_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 __ cmpl(ckoff, Address(ckval, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 __ stop("super_check_offset inconsistent");
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2262
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // Loop-invariant addresses. They are exclusive end pointers.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2264 Address end_from_addr(from, length, TIMES_OOP, 0);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2265 Address end_to_addr(to, length, TIMES_OOP, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // Loop-variant addresses. They assume post-incremented count < 0.
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2267 Address from_element_addr(end_from, count, TIMES_OOP, 0);
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2268 Address to_element_addr(end_to, count, TIMES_OOP, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2270 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2271
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 // Copy from low to high addresses, indexed from the end of each array.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2273 __ lea(end_from, end_from_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2274 __ lea(end_to, end_to_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2275 __ movptr(r14_length, length); // save a copy of the length
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2276 assert(length == count, ""); // else fix next line:
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2277 __ negptr(count); // negate and test the length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 __ jcc(Assembler::notZero, L_load_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2279
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 // Empty array: Nothing to do.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2281 __ xorptr(rax, rax); // return 0 on (trivial) success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 __ jmp(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 // ======== begin loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // (Loop is rotated; its entry is L_load_element.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 // Loop control:
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // for (count = -count; count != 0; count++)
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // Base pointers src, dst are biased by 8*(count-1),to last element.
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
2289 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2290
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 __ BIND(L_store_element);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2292 __ store_heap_oop(to_element_addr, rax_oop); // store the oop
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2293 __ increment(count); // increment the count toward zero
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 __ jcc(Assembler::zero, L_do_card_marks);
a61af66fc99e Initial load
duke
parents:
diff changeset
2295
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // ======== loop entry is here ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 __ BIND(L_load_element);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2298 __ load_heap_oop(rax_oop, from_element_addr); // load the oop
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2299 __ testptr(rax_oop, rax_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 __ jcc(Assembler::zero, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2301
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2302 __ load_klass(r11_klass, rax_oop);// query the object klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 generate_type_check(r11_klass, ckoff, ckval, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 // ======== end loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
2305
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 // It was a real error; we must depend on the caller to finish the job.
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // Register rdx = -1 * number of *remaining* oops, r14 = *total* oops.
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 // Emit GC store barriers for the oops we have copied (r14 + rdx),
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 // and report their number to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 assert_different_registers(rax, r14_length, count, to, end_to, rcx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2311 __ lea(end_to, to_element_addr);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
2312 __ addptr(end_to, -heapOopSize); // make an inclusive end pointer
362
apetrusenko
parents: 304 356
diff changeset
2313 gen_write_ref_array_post_barrier(to, end_to, rscratch1);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2314 __ movptr(rax, r14_length); // original oops
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2315 __ addptr(rax, count); // K = (original - remaining) oops
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2316 __ notptr(rax); // report (-1^K) to caller
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 __ jmp(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 // Come here on success only.
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 __ BIND(L_do_card_marks);
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 671
diff changeset
2321 __ addptr(end_to, -heapOopSize); // make an inclusive end pointer
362
apetrusenko
parents: 304 356
diff changeset
2322 gen_write_ref_array_post_barrier(to, end_to, rscratch1);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2323 __ xorptr(rax, rax); // return 0 on success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 // Common exit point (success or failure).
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 __ BIND(L_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2327 __ movptr(r13, Address(rsp, saved_r13_offset * wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2328 __ movptr(r14, Address(rsp, saved_r14_offset * wordSize));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 restore_arg_regs();
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2336
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 // Generate 'unsafe' array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // Though just as safe as the other stubs, it takes an unscaled
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 // size_t argument instead of an element count.
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 // c_rarg0 - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 // c_rarg1 - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 // c_rarg2 - byte count, treated as ssize_t, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 // Examines the alignment of the operands and dispatches
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // to a long, int, short, or byte copy loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2350 address generate_unsafe_copy(const char *name,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2351 address byte_copy_entry, address short_copy_entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2352 address int_copy_entry, address long_copy_entry) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2353
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 Label L_long_aligned, L_int_aligned, L_short_aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
2355
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 // Input registers (before setup_arg_regs)
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 const Register from = c_rarg0; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 const Register to = c_rarg1; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 const Register size = c_rarg2; // byte count (size_t)
a61af66fc99e Initial load
duke
parents:
diff changeset
2360
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 // Register used as a temp
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 const Register bits = rax; // test copy of low bits
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2367
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2369
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2373 __ mov(bits, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2374 __ orptr(bits, to);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2375 __ orptr(bits, size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 __ testb(bits, BytesPerLong-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 __ jccb(Assembler::zero, L_long_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
2379
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 __ testb(bits, BytesPerInt-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 __ jccb(Assembler::zero, L_int_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
2382
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 __ testb(bits, BytesPerShort-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2385
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 __ BIND(L_short_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2387 __ shrptr(size, LogBytesPerShort); // size => short_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2389
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 __ BIND(L_int_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2391 __ shrptr(size, LogBytesPerInt); // size => int_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2393
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 __ BIND(L_long_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2395 __ shrptr(size, LogBytesPerLong); // size => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2400
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // Perform range checks on the proposed arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // Kills temp, but nothing else.
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 // Also, clean the sign bits of src_pos and dst_pos.
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 void arraycopy_range_checks(Register src, // source array oop (c_rarg0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 Register src_pos, // source position (c_rarg1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 Register dst, // destination array oo (c_rarg2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 Register dst_pos, // destination position (c_rarg3)
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 Register length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 Register temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 Label& L_failed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 BLOCK_COMMENT("arraycopy_range_checks:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2412
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 // if (src_pos + length > arrayOop(src)->length()) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 __ movl(temp, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 __ addl(temp, src_pos); // src_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 __ cmpl(temp, Address(src, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2418
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 // if (dst_pos + length > arrayOop(dst)->length()) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 __ movl(temp, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 __ addl(temp, dst_pos); // dst_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 __ cmpl(temp, Address(dst, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2424
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 // Have to clean up high 32-bits of 'src_pos' and 'dst_pos'.
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 // Move with sign extension can be used since they are positive.
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 __ movslq(src_pos, src_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 __ movslq(dst_pos, dst_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
2429
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 BLOCK_COMMENT("arraycopy_range_checks done");
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2432
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 // Generate generic array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 // c_rarg0 - src oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 // c_rarg1 - src_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 // c_rarg2 - dst oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 // c_rarg3 - dst_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 // not Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 // c_rarg4 - element count (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 // Win64
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 // rsp+40 - element count (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 // rax == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 // rax == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 //
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2450 address generate_generic_copy(const char *name,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2451 address byte_copy_entry, address short_copy_entry,
2409
348c0df561a9 7026307: DEBUG MESSAGE: broken null klass on amd64
iveresov
parents: 2407
diff changeset
2452 address int_copy_entry, address oop_copy_entry,
348c0df561a9 7026307: DEBUG MESSAGE: broken null klass on amd64
iveresov
parents: 2407
diff changeset
2453 address long_copy_entry, address checkcast_copy_entry) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2454
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 Label L_failed, L_failed_0, L_objArray;
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2457
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 // Input registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 const Register src = c_rarg0; // source array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 const Register src_pos = c_rarg1; // source position
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 const Register dst = c_rarg2; // destination array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 const Register dst_pos = c_rarg3; // destination position
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2463 #ifndef _WIN64
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2464 const Register length = c_rarg4;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 #else
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2466 const Address length(rsp, 6 * wordSize); // elements count is on stack on Win64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2468
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 { int modulus = CodeEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 int target = modulus - 5; // 5 = sizeof jmp(L_failed)
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 int advance = target - (__ offset() % modulus);
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 if (advance < 0) advance += modulus;
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 if (advance > 0) __ nop(advance);
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2476
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 // Short-hop target to L_failed. Makes for denser prologue code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 __ BIND(L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 __ jmp(L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 assert(__ offset() % CodeEntryAlignment == 0, "no further alignment needed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2481
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2484
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2486
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 inc_counter_np(SharedRuntime::_generic_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2489
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 //-----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 // if the following conditions are met:
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 // (1) src and dst must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 // (2) src_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 // (3) dst_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 // (4) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 // (5) src klass and dst klass should be the same and not NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 // (6) src and dst should be arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // (7) src_pos + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 // (8) dst_pos + length must not exceed length of dst.
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2503
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 // if (src == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2505 __ testptr(src, src); // src oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 size_t j1off = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2508
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 // if (src_pos < 0) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 __ testl(src_pos, src_pos); // src_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2512
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 // if (dst == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2514 __ testptr(dst, dst); // dst oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 // if (dst_pos < 0) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 __ testl(dst_pos, dst_pos); // dst_pos (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 size_t j4off = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2521
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 // The first four tests are very dense code,
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 // but not quite dense enough to put four
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 // jumps in a 16-byte instruction fetch buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 // That's good, because some branch predicters
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 // do not like jumps so close together.
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 // Make sure of this.
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 guarantee(((j1off ^ j4off) & ~15) != 0, "I$ line of 1st & 4th jumps");
a61af66fc99e Initial load
duke
parents:
diff changeset
2529
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 // registers used as temp
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 const Register r11_length = r11; // elements count to copy
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 const Register r10_src_klass = r10; // array klass
a61af66fc99e Initial load
duke
parents:
diff changeset
2533
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 // if (length < 0) return -1;
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2535 __ movl(r11_length, length); // length (elements count, 32-bits value)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 __ testl(r11_length, r11_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2538
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2539 __ load_klass(r10_src_klass, src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 // assert(src->klass() != NULL);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2542 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2543 BLOCK_COMMENT("assert klasses not null {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2544 Label L1, L2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2545 __ testptr(r10_src_klass, r10_src_klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 __ bind(L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 __ stop("broken null klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 __ bind(L2);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2550 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2551 __ cmpq(rax, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 __ jcc(Assembler::equal, L1); // this would be broken also
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2553 BLOCK_COMMENT("} assert klasses not null done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // Load layout helper (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 // |array_tag| | header_size | element_type | |log2_element_size|
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 // 32 30 24 16 8 2 0
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2564
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2565 const int lh_offset = klassOopDesc::header_size() * HeapWordSize +
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2566 Klass::layout_helper_offset_in_bytes();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2567
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 // Handle objArrays completely differently...
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2569 const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2570 __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 __ jcc(Assembler::equal, L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
2572
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 // if (src->klass() != dst->klass()) return -1;
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2574 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2575 __ cmpq(r10_src_klass, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 __ jcc(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2577
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2578 const Register rax_lh = rax; // layout helper
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2579 __ movl(rax_lh, Address(r10_src_klass, lh_offset));
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2580
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 // if (!src->is_Array()) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 __ cmpl(rax_lh, Klass::_lh_neutral_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 __ jcc(Assembler::greaterEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2584
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 // At this point, it is known to be a typeArray (array_tag 0x3).
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 #ifdef ASSERT
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2587 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2588 BLOCK_COMMENT("assert primitive array {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2589 Label L;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 __ jcc(Assembler::greaterEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 __ stop("must be a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 __ bind(L);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2594 BLOCK_COMMENT("} assert primitive array done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2597
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 r10, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2600
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 // typeArrayKlass
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2606
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 const Register r10_offset = r10; // array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 const Register rax_elsize = rax_lh; // element size
a61af66fc99e Initial load
duke
parents:
diff changeset
2609
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 __ movl(r10_offset, rax_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 __ shrl(r10_offset, Klass::_lh_header_size_shift);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2612 __ andptr(r10_offset, Klass::_lh_header_size_mask); // array_offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2613 __ addptr(src, r10_offset); // src array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2614 __ addptr(dst, r10_offset); // dst array offset
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 BLOCK_COMMENT("choose copy loop based on element size");
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 __ andl(rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize
a61af66fc99e Initial load
duke
parents:
diff changeset
2617
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // next registers should be set before the jump to corresponding stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 const Register from = c_rarg0; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 const Register to = c_rarg1; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 const Register count = c_rarg2; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
2622
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 // 'from', 'to', 'count' registers should be set in such order
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 // since they are the same as 'src', 'src_pos', 'dst'.
a61af66fc99e Initial load
duke
parents:
diff changeset
2625
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 __ BIND(L_copy_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 __ cmpl(rax_elsize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 __ jccb(Assembler::notEqual, L_copy_shorts);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2629 __ lea(from, Address(src, src_pos, Address::times_1, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2630 __ lea(to, Address(dst, dst_pos, Address::times_1, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2631 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 __ jump(RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2633
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 __ BIND(L_copy_shorts);
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 __ cmpl(rax_elsize, LogBytesPerShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 __ jccb(Assembler::notEqual, L_copy_ints);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2637 __ lea(from, Address(src, src_pos, Address::times_2, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2638 __ lea(to, Address(dst, dst_pos, Address::times_2, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2639 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2641
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 __ BIND(L_copy_ints);
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 __ cmpl(rax_elsize, LogBytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 __ jccb(Assembler::notEqual, L_copy_longs);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2645 __ lea(from, Address(src, src_pos, Address::times_4, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2646 __ lea(to, Address(dst, dst_pos, Address::times_4, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2647 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2649
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 __ BIND(L_copy_longs);
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 #ifdef ASSERT
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2652 {
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2653 BLOCK_COMMENT("assert long copy {");
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2654 Label L;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 __ cmpl(rax_elsize, LogBytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 __ stop("must be long copy, but elsize is wrong");
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 __ bind(L);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2659 BLOCK_COMMENT("} assert long copy done");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2662 __ lea(from, Address(src, src_pos, Address::times_8, 0));// src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2663 __ lea(to, Address(dst, dst_pos, Address::times_8, 0));// dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2664 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2666
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 // objArrayKlass
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 __ BIND(L_objArray);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2669 // live at this point: r10_src_klass, r11_length, src[_pos], dst[_pos]
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2670
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 Label L_plain_copy, L_checkcast_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 // test array classes for subtyping
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2673 __ load_klass(rax, dst);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2674 __ cmpq(r10_src_klass, rax); // usual case is exact equality
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 __ jcc(Assembler::notEqual, L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2676
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 // Identically typed arrays can be copied without element-wise checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 r10, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2681 __ lea(from, Address(src, src_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2683 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2684 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2685 __ movl2ptr(count, r11_length); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 __ BIND(L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 __ jump(RuntimeAddress(oop_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2688
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 __ BIND(L_checkcast_copy);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2690 // live at this point: r10_src_klass, r11_length, rax (dst_klass)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 // Before looking at dst.length, make sure dst is also an objArray.
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2693 __ cmpl(Address(rax, lh_offset), objArray_lh);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 __ jcc(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
2695
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // It is safe to examine both src.length and dst.length.
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 rax, L_failed);
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2699
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2700 const Register r11_dst_klass = r11;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2701 __ load_klass(r11_dst_klass, dst); // reload
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2702
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 // Marshal the base address arguments now, freeing registers.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2704 __ lea(from, Address(src, src_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2706 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2708 __ movl(count, length); // length (reloaded)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 Register sco_temp = c_rarg3; // this register is free now
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 assert_different_registers(from, to, count, sco_temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 r11_dst_klass, r10_src_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 assert_clean_int(count, sco_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2713
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 // Generate the type check.
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2715 const int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2716 Klass::super_check_offset_offset_in_bytes());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 __ movl(sco_temp, Address(r11_dst_klass, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 assert_clean_int(sco_temp, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2720
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 // Fetch destination element klass from the objArrayKlass header.
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 objArrayKlass::element_klass_offset_in_bytes());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2724 __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset));
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2725 __ movl( sco_temp, Address(r11_dst_klass, sco_offset));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 assert_clean_int(sco_temp, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
2727
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 // the checkcast_copy loop needs two extra arguments:
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 assert(c_rarg3 == sco_temp, "#3 already in place");
2006
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2730 // Set up arguments for checkcast_copy_entry.
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2731 setup_arg_regs(4);
bbefa3ca1543 6998985: faulty generic arraycopy on windows x86_64: 4th arg overwritten with oop
twisti
parents: 1972
diff changeset
2732 __ movptr(r8, r11_dst_klass); // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 __ jump(RuntimeAddress(checkcast_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2735
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 __ BIND(L_failed);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2737 __ xorptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2738 __ notptr(rax); // return -1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2741
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2744
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 void generate_arraycopy_stubs() {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2746 address entry;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2747 address entry_jbyte_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2748 address entry_jshort_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2749 address entry_jint_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2750 address entry_oop_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2751 address entry_jlong_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2752 address entry_checkcast_arraycopy;
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2753
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2754 StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_byte_copy(false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2755 "jbyte_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2756 StubRoutines::_jbyte_arraycopy = generate_conjoint_byte_copy(false, entry, &entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2757 "jbyte_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2758
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2759 StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_short_copy(false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2760 "jshort_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2761 StubRoutines::_jshort_arraycopy = generate_conjoint_short_copy(false, entry, &entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2762 "jshort_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2763
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2764 StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2765 "jint_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2766 StubRoutines::_jint_arraycopy = generate_conjoint_int_oop_copy(false, false, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2767 &entry_jint_arraycopy, "jint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2768
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2769 StubRoutines::_jlong_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, false, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2770 "jlong_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2771 StubRoutines::_jlong_arraycopy = generate_conjoint_long_oop_copy(false, false, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2772 &entry_jlong_arraycopy, "jlong_arraycopy");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2773
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2774
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2775 if (UseCompressedOops) {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2776 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_int_oop_copy(false, true, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2777 "oop_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2778 StubRoutines::_oop_arraycopy = generate_conjoint_int_oop_copy(false, true, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2779 &entry_oop_arraycopy, "oop_arraycopy");
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2780 StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_int_oop_copy(false, true, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2781 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2782 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2783 StubRoutines::_oop_arraycopy_uninit = generate_conjoint_int_oop_copy(false, true, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2784 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2785 /*dest_uninitialized*/true);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2786 } else {
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2787 StubRoutines::_oop_disjoint_arraycopy = generate_disjoint_long_oop_copy(false, true, &entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2788 "oop_disjoint_arraycopy");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2789 StubRoutines::_oop_arraycopy = generate_conjoint_long_oop_copy(false, true, entry,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2790 &entry_oop_arraycopy, "oop_arraycopy");
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2791 StubRoutines::_oop_disjoint_arraycopy_uninit = generate_disjoint_long_oop_copy(false, true, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2792 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2793 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2794 StubRoutines::_oop_arraycopy_uninit = generate_conjoint_long_oop_copy(false, true, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2795 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2796 /*dest_uninitialized*/true);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 16
diff changeset
2797 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2798
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2799 StubRoutines::_checkcast_arraycopy = generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2800 StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy("checkcast_arraycopy_uninit", NULL,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2801 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2802
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2803 StubRoutines::_unsafe_arraycopy = generate_unsafe_copy("unsafe_arraycopy",
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2804 entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2805 entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2806 entry_jint_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2807 entry_jlong_arraycopy);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2808 StubRoutines::_generic_arraycopy = generate_generic_copy("generic_arraycopy",
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2809 entry_jbyte_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2810 entry_jshort_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2811 entry_jint_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2812 entry_oop_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2813 entry_jlong_arraycopy,
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2006
diff changeset
2814 entry_checkcast_arraycopy);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2816 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2817 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2818 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2819 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2820 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2821 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1583
diff changeset
2822
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 // We don't generate specialized code for HeapWord-aligned source
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // arrays, so just use the code we've already generated
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 StubRoutines::_arrayof_jbyte_disjoint_arraycopy = StubRoutines::_jbyte_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 StubRoutines::_arrayof_jbyte_arraycopy = StubRoutines::_jbyte_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2827
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 StubRoutines::_arrayof_jshort_disjoint_arraycopy = StubRoutines::_jshort_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 StubRoutines::_arrayof_jshort_arraycopy = StubRoutines::_jshort_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2830
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2836
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2839
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2840 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2313
diff changeset
2841 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2843
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2844 void generate_math_stubs() {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2845 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2846 StubCodeMark mark(this, "StubRoutines", "log");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2847 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2848
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2849 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2850 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2851 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2852 __ flog();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2853 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2854 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2855 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2856 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2857 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2858 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2859 StubCodeMark mark(this, "StubRoutines", "log10");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2860 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2861
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2862 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2863 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2864 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2865 __ flog10();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2866 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2867 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2868 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2869 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2870 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2871 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2872 StubCodeMark mark(this, "StubRoutines", "sin");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2873 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2874
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2875 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2876 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2877 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2878 __ trigfunc('s');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2879 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2880 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2881 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2882 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2883 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2884 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2885 StubCodeMark mark(this, "StubRoutines", "cos");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2886 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2887
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2888 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2889 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2890 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2891 __ trigfunc('c');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2892 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2893 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2894 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2895 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2896 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2897 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2898 StubCodeMark mark(this, "StubRoutines", "tan");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2899 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2900
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2901 __ subq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2902 __ movdbl(Address(rsp, 0), xmm0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2903 __ fld_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2904 __ trigfunc('t');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2905 __ fstp_d(Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2906 __ movdbl(xmm0, Address(rsp, 0));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2907 __ addq(rsp, 8);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2908 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2909 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2910
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2911 // The intrinsic version of these seem to return the same value as
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2912 // the strict version.
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2913 StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2914 StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2915 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
2916
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 #undef __
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 #define __ masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
2919
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 // Continuation point for throwing of implicit exceptions that are
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 // not handled in the current activation. Fabricates an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 // oop and initiates normal exception dispatching in this
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 // frame. Since we need to preserve callee-saved values (currently
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 // only for C2, but done for C1 as well) we need a callee-saved oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 // map and therefore have to make these stubs into RuntimeStubs
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 // rather than BufferBlobs. If the compiler needs all registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // be preserved between the fault point and the exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 // then it must assume responsibility for that in
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 // AbstractCompiler::continuation_for_implicit_null_exception or
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 // continuation_for_implicit_division_by_zero_exception. All other
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 // implicit exceptions (e.g., NullPointerException or
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 // AbstractMethodError on entry) are either at call sites or
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 // otherwise assume that stack unwinding will be initiated, so
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 // caller saved registers were assumed volatile in the compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 address generate_throw_exception(const char* name,
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 address runtime_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 bool restore_saved_exception_pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 // Information about frame layout at time of blocking runtime call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // Note that we only have to preserve callee-saved registers since
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // the compilers are responsible for supplying a continuation point
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 // if they expect all registers to be preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 enum layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 rbp_off = frame::arg_reg_save_area_bytes/BytesPerInt,
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 rbp_off2,
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 return_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 return_off2,
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 framesize // inclusive of return address
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 int insts_size = 512;
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 int locs_size = 64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2952
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 CodeBuffer code(name, insts_size, locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 OopMapSet* oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 MacroAssembler* masm = new MacroAssembler(&code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2956
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2958
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 // This is an inlined and slightly modified version of call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 // which has the ability to fetch the return PC out of
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 // thread-local storage and also sets up last_Java_sp slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 // differently than the real call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 if (restore_saved_exception_pc) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2964 __ movptr(rax,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2965 Address(r15_thread,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2966 in_bytes(JavaThread::saved_exception_pc_offset())));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2967 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2969
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2971
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 assert(is_even(framesize/2), "sp not 16-byte aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
2973
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 // return address and rbp are already in place
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2975 __ subptr(rsp, (framesize-4) << LogBytesPerInt); // prolog
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2976
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 int frame_complete = __ pc() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2978
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // Set up last_Java_sp and last_Java_fp
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 __ set_last_Java_frame(rsp, rbp, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2981
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 // Call runtime
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2983 __ movptr(c_rarg0, r15_thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 BLOCK_COMMENT("call runtime_entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 __ call(RuntimeAddress(runtime_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2986
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 // Generate oop map
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 OopMap* map = new OopMap(framesize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2989
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 oop_maps->add_gc_map(__ pc() - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2991
a61af66fc99e Initial load
duke
parents:
diff changeset
2992 __ reset_last_Java_frame(true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2993
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2995
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 // check for pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2999 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()),
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3000 (int32_t) NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3006
a61af66fc99e Initial load
duke
parents:
diff changeset
3007
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 // codeBlob framesize is in words (not VMRegImpl::slot_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 RuntimeStub* stub =
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 RuntimeStub::new_runtime_stub(name,
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 &code,
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 frame_complete,
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 (framesize >> (LogBytesPerWord - LogBytesPerInt)),
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 oop_maps, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 return stub->entry_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 // Initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 void generate_initial() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
3021
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // This platform-specific stub is needed by generate_call_stub()
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3023 StubRoutines::x86::_mxcsr_std = generate_fp_mask("mxcsr_std", 0x0000000000001F80);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3024
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 // entry points that exist in all platforms Note: This is code
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // that could be shared among different platforms - however the
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // benefit seems to be smaller than the disadvantage of having a
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // much more complicated generator structure. See also comment in
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 // stubRoutines.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
3030
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 StubRoutines::_forward_exception_entry = generate_forward_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
3032
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 StubRoutines::_call_stub_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 generate_call_stub(StubRoutines::_call_stub_return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
3035
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 // is referenced by megamorphic call
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 StubRoutines::_catch_exception_entry = generate_catch_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
3038
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 // atomic calls
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 StubRoutines::_atomic_xchg_ptr_entry = generate_atomic_xchg_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 StubRoutines::_atomic_cmpxchg_entry = generate_atomic_cmpxchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long();
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 StubRoutines::_atomic_add_entry = generate_atomic_add();
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 StubRoutines::_atomic_add_ptr_entry = generate_atomic_add_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 StubRoutines::_fence_entry = generate_orderaccess_fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 StubRoutines::_handler_for_unsafe_access_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 generate_handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
3050
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 // platform dependent
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3052 StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3053
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3054 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 void generate_all() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
3059
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 // These entry points require SharedInfo::stack0 to be set up in
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // non-core builds and need to be relocatable, so they each
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // fabricate a RuntimeStub internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 StubRoutines::_throw_AbstractMethodError_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 generate_throw_exception("AbstractMethodError throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 throw_AbstractMethodError),
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
16
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3070 StubRoutines::_throw_IncompatibleClassChangeError_entry =
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3071 generate_throw_exception("IncompatibleClassChangeError throw_exception",
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3072 CAST_FROM_FN_PTR(address,
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3073 SharedRuntime::
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3074 throw_IncompatibleClassChangeError),
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3075 false);
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
3076
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 StubRoutines::_throw_ArithmeticException_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 generate_throw_exception("ArithmeticException throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 throw_ArithmeticException),
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3083
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 StubRoutines::_throw_NullPointerException_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 generate_throw_exception("NullPointerException throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 throw_NullPointerException),
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3090
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 StubRoutines::_throw_NullPointerException_at_call_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 generate_throw_exception("NullPointerException at call throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 throw_NullPointerException_at_call),
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3097
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 StubRoutines::_throw_StackOverflowError_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 generate_throw_exception("StackOverflowError throw_exception",
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 CAST_FROM_FN_PTR(address,
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 throw_StackOverflowError),
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3104
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // entry points that are platform specific
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3106 StubRoutines::x86::_f2i_fixup = generate_f2i_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3107 StubRoutines::x86::_f2l_fixup = generate_f2l_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3108 StubRoutines::x86::_d2i_fixup = generate_d2i_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3109 StubRoutines::x86::_d2l_fixup = generate_d2l_fixup();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3110
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3111 StubRoutines::x86::_float_sign_mask = generate_fp_mask("float_sign_mask", 0x7FFFFFFF7FFFFFFF);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3112 StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3113 StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
3114 StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 // support for verify_oop (must happen after universe_init)
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3118
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 // arraycopy stubs used by compilers
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 generate_arraycopy_stubs();
1108
85f13cdfbc1d 6829192: JSR 292 needs to support 64-bit x86
twisti
parents: 845
diff changeset
3121
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 1108
diff changeset
3122 generate_math_stubs();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3124
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 if (all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 generate_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 generate_initial();
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 }; // end class declaration
a61af66fc99e Initial load
duke
parents:
diff changeset
3134
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 void StubGenerator_generate(CodeBuffer* code, bool all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 StubGenerator g(code, all);
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 }