annotate src/cpu/x86/vm/stubGenerator_x86_32.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 0ac769a57c64
children 38fa55e5e792
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2245
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
2 * Copyright (c) 1999, 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->
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
59 #define a__ ((Assembler*)_masm)->
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
62 #define BLOCK_COMMENT(str) /* nothing */
a61af66fc99e Initial load
duke
parents:
diff changeset
63 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
64 #define BLOCK_COMMENT(str) __ block_comment(str)
a61af66fc99e Initial load
duke
parents:
diff changeset
65 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
a61af66fc99e Initial load
duke
parents:
diff changeset
68
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 const int FPU_CNTRL_WRD_MASK = 0xFFFF;
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // -------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Stub Code definitions
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75 static address handle_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 JavaThread* thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 address pc = thread->saved_exception_pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // pc is the instruction which we must emulate
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // doing a no-op is fine: return garbage from the load
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // therefore, compute npc
a61af66fc99e Initial load
duke
parents:
diff changeset
81 address npc = Assembler::locate_next_instruction(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // request an async exception
a61af66fc99e Initial load
duke
parents:
diff changeset
84 thread->set_pending_unsafe_access_error();
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // return address of next instruction to execute
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return npc;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 class StubGenerator: public StubCodeGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #ifdef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #define inc_counter_np(counter) (0)
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
96 void inc_counter_np_(int& counter) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
97 __ incrementl(ExternalAddress((address)&counter));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 #define inc_counter_np(counter) \
a61af66fc99e Initial load
duke
parents:
diff changeset
100 BLOCK_COMMENT("inc_counter " #counter); \
a61af66fc99e Initial load
duke
parents:
diff changeset
101 inc_counter_np_(counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 void inc_copy_counter_np(BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
106 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 case T_BYTE: inc_counter_np(SharedRuntime::_jbyte_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 case T_SHORT: inc_counter_np(SharedRuntime::_jshort_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 case T_INT: inc_counter_np(SharedRuntime::_jint_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 case T_LONG: inc_counter_np(SharedRuntime::_jlong_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 case T_OBJECT: inc_counter_np(SharedRuntime::_oop_array_copy_ctr); return;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
114 #endif //PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Call stubs are used to call Java from C
a61af66fc99e Initial load
duke
parents:
diff changeset
119 //
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // [ return_from_Java ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // [ argument word n ]
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // -N [ argument word 1 ]
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // -7 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // -6 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // -5 [ Possible padding for stack alignment ]
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // -4 [ mxcsr save ] <--- rsp_after_call
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // -3 [ saved rbx, ]
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // -2 [ saved rsi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // -1 [ saved rdi ]
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // 0 [ saved rbp, ] <--- rbp,
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // 1 [ return address ]
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // 2 [ ptr. to call wrapper ]
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // 3 [ result ]
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // 4 [ result_type ]
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // 5 [ method ]
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // 6 [ entry_point ]
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // 7 [ parameters ]
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // 8 [ parameter_size ]
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // 9 [ thread ]
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 address generate_call_stub(address& return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 StubCodeMark mark(this, "StubRoutines", "call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
145 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // stub code parameters / addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
148 assert(frame::entry_frame_call_wrapper_offset == 2, "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
149 bool sse_save = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
151 const int locals_count_in_bytes (4*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 const Address mxcsr_save (rbp, -4 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 const Address saved_rbx (rbp, -3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 const Address saved_rsi (rbp, -2 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 const Address saved_rdi (rbp, -1 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 const Address result (rbp, 3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 const Address result_type (rbp, 4 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 const Address method (rbp, 5 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 const Address entry_point (rbp, 6 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 const Address parameters (rbp, 7 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 const Address parameter_size(rbp, 8 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 const Address thread (rbp, 9 * wordSize); // same as in generate_catch_exception()!
a61af66fc99e Initial load
duke
parents:
diff changeset
163 sse_save = UseSSE > 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // stub code
a61af66fc99e Initial load
duke
parents:
diff changeset
166 __ enter();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
167 __ movptr(rcx, parameter_size); // parameter counter
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1368
diff changeset
168 __ shlptr(rcx, Interpreter::logStackElementSize); // convert parameter count to bytes
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
169 __ addptr(rcx, locals_count_in_bytes); // reserve space for register saves
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
170 __ subptr(rsp, rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
171 __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
0
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // save rdi, rsi, & rbx, according to C calling conventions
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
174 __ movptr(saved_rdi, rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
175 __ movptr(saved_rsi, rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
176 __ movptr(saved_rbx, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // save and initialize %mxcsr
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if (sse_save) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 Label skip_ldmx;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 __ andl(rax, MXCSR_MASK); // Only check control and mask bits
a61af66fc99e Initial load
duke
parents:
diff changeset
183 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
184 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 __ jcc(Assembler::equal, skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 __ bind(skip_ldmx);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // make sure the control word is correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
191 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std()));
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // make sure we have no pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
195 { Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
196 __ movptr(rcx, thread);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
197 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
198 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 __ stop("StubRoutines::call_stub: entered with pending exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
200 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // pass parameters if any
a61af66fc99e Initial load
duke
parents:
diff changeset
205 BLOCK_COMMENT("pass parameters if any");
a61af66fc99e Initial load
duke
parents:
diff changeset
206 Label parameters_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 __ movl(rcx, parameter_size); // parameter counter
a61af66fc99e Initial load
duke
parents:
diff changeset
208 __ testl(rcx, rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 __ jcc(Assembler::zero, parameters_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // parameter passing loop
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 Label loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Copy Java parameters in reverse order (receiver last)
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Note that the argument order is inverted in the process
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // source is rdx[rcx: N-1..0]
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // dest is rsp[rbx: 0..N-1]
a61af66fc99e Initial load
duke
parents:
diff changeset
218
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
219 __ movptr(rdx, parameters); // parameter pointer
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
220 __ xorptr(rbx, rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 __ BIND(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // get parameter
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
225 __ movptr(rax, Address(rdx, rcx, Interpreter::stackElementScale(), -wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
226 __ movptr(Address(rsp, rbx, Interpreter::stackElementScale(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227 Interpreter::expr_offset_in_bytes(0)), rax); // store parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
228 __ increment(rbx);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 __ decrement(rcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 __ jcc(Assembler::notZero, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // call Java function
a61af66fc99e Initial load
duke
parents:
diff changeset
233 __ BIND(parameters_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
234 __ movptr(rbx, method); // get methodOop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
235 __ movptr(rax, entry_point); // get entry_point
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
236 __ mov(rsi, rsp); // set sender sp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
237 BLOCK_COMMENT("call Java function");
a61af66fc99e Initial load
duke
parents:
diff changeset
238 __ call(rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 BLOCK_COMMENT("call_stub_return_address:");
a61af66fc99e Initial load
duke
parents:
diff changeset
241 return_address = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
242
2245
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
243 #ifdef COMPILER2
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
244 {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
245 Label L_skip;
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
246 if (UseSSE >= 2) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
247 __ verify_FPU(0, "call_stub_return");
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
248 } else {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
249 for (int i = 1; i < 8; i++) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
250 __ ffree(i);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
251 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
252
2245
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
253 // UseSSE <= 1 so double result should be left on TOS
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
254 __ movl(rsi, result_type);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
255 __ cmpl(rsi, T_DOUBLE);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
256 __ jcc(Assembler::equal, L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
257 if (UseSSE == 0) {
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
258 // UseSSE == 0 so float result should be left on TOS
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
259 __ cmpl(rsi, T_FLOAT);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
260 __ jcc(Assembler::equal, L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
261 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
262 __ ffree(0);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
263 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
264 __ BIND(L_skip);
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
265 }
638119ce7cfd 7009309: JSR 292: compiler/6991596/Test6991596.java crashes on fastdebug JDK7/b122
twisti
parents: 1972
diff changeset
266 #endif // COMPILER2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // store result depending on type
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // (everything that is not 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
270 __ movptr(rdi, result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
271 Label is_long, is_float, is_double, exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 __ movl(rsi, result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 __ cmpl(rsi, T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 __ jcc(Assembler::equal, is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
275 __ cmpl(rsi, T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 __ jcc(Assembler::equal, is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 __ cmpl(rsi, T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 __ jcc(Assembler::equal, is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // handle T_INT case
a61af66fc99e Initial load
duke
parents:
diff changeset
281 __ movl(Address(rdi, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 __ BIND(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // check that FPU stack is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
285 __ verify_FPU(0, "generate_call_stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // pop parameters
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
288 __ lea(rsp, rsp_after_call);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // restore %mxcsr
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if (sse_save) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 __ ldmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // restore rdi, rsi and rbx,
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
296 __ movptr(rbx, saved_rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
297 __ movptr(rsi, saved_rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
298 __ movptr(rdi, saved_rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
299 __ addptr(rsp, 4*wordSize);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // return
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
302 __ pop(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
303 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // handle return types different from T_INT
a61af66fc99e Initial load
duke
parents:
diff changeset
306 __ BIND(is_long);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 __ movl(Address(rdi, 0 * wordSize), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 __ movl(Address(rdi, 1 * wordSize), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
310
a61af66fc99e Initial load
duke
parents:
diff changeset
311 __ BIND(is_float);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // interpreter uses xmm0 for return values
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (UseSSE >= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 __ movflt(Address(rdi, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 __ fstp_s(Address(rdi, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 __ BIND(is_double);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // interpreter uses xmm0 for return values
a61af66fc99e Initial load
duke
parents:
diff changeset
322 if (UseSSE >= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 __ movdbl(Address(rdi, 0), xmm0);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 __ fstp_d(Address(rdi, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 __ jmp(exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Return point for a Java call if there's an exception thrown in Java code.
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // The exception is caught and transformed into a pending exception stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // JavaThread that can be tested from within the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Note: Usually the parameters are removed by the callee. In case of an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // crossing an activation frame boundary, that is not the case if the callee
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // is compiled code => need to setup the rsp.
a61af66fc99e Initial load
duke
parents:
diff changeset
341 //
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // rax,: exception oop
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 address generate_catch_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
345 StubCodeMark mark(this, "StubRoutines", "catch_exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
346 const Address rsp_after_call(rbp, -4 * wordSize); // same as in generate_call_stub()!
a61af66fc99e Initial load
duke
parents:
diff changeset
347 const Address thread (rbp, 9 * wordSize); // same as in generate_call_stub()!
a61af66fc99e Initial load
duke
parents:
diff changeset
348 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // get thread directly
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
351 __ movptr(rcx, thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
352 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // verify that threads correspond
a61af66fc99e Initial load
duke
parents:
diff changeset
354 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 __ get_thread(rbx);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
356 __ cmpptr(rbx, rcx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357 __ jcc(Assembler::equal, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 __ stop("StubRoutines::catch_exception: threads must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
359 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // set pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
363 __ verify_oop(rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
364 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
365 __ lea(Address(rcx, Thread::exception_file_offset ()),
a61af66fc99e Initial load
duke
parents:
diff changeset
366 ExternalAddress((address)__FILE__));
a61af66fc99e Initial load
duke
parents:
diff changeset
367 __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ );
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // complete return to VM
a61af66fc99e Initial load
duke
parents:
diff changeset
369 assert(StubRoutines::_call_stub_return_address != NULL, "_call_stub_return_address must have been generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
370 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address));
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // Continuation point for runtime calls returning with a pending exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // The pending exception check happened in the runtime or native call stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // The pending exception in Thread is converted into a Java-level exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
380 //
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // Contract with Java-level exception handlers:
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
382 // rax: exception
0
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // rdx: throwing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
384 //
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // NOTE: At entry of this stub, exception-pc must be on stack !!
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 address generate_forward_exception() {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 StubCodeMark mark(this, "StubRoutines", "forward exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
389 address start = __ pc();
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
390 const Register thread = rcx;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
391
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
392 // other registers used in this stub
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
393 const Register exception_oop = rax;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
394 const Register handler_addr = rbx;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
395 const Register exception_pc = rdx;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Upon entry, the sp points to the return address returning into Java
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // (interpreted or compiled) code; i.e., the return address becomes the
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // throwing pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
400 //
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // Arguments pushed before the runtime call are still on the stack but
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // the exception handler will reset the stack pointer -> ignore them.
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // A potential result in registers can be ignored as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // make sure this code is only executed if there is a pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
407 { Label L;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
408 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
409 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
410 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
411 __ stop("StubRoutines::forward exception: no pending exception (1)");
a61af66fc99e Initial load
duke
parents:
diff changeset
412 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // compute exception handler into rbx,
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
417 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
418 __ movptr(exception_pc, Address(rsp, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
419 BLOCK_COMMENT("call exception_handler_for_return_address");
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
420 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
421 __ mov(handler_addr, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
422
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
423 // setup rax & rdx, remove return address & clear pending exception
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
424 __ get_thread(thread);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
425 __ pop(exception_pc);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
426 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
427 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // make sure exception is set
a61af66fc99e Initial load
duke
parents:
diff changeset
431 { Label L;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
432 __ testptr(exception_oop, exception_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
433 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 __ stop("StubRoutines::forward exception: no pending exception (2)");
a61af66fc99e Initial load
duke
parents:
diff changeset
435 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
437 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
438
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
439 // Verify that there is really a valid exception in RAX.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
440 __ verify_oop(exception_oop);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
441
0
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // continue at exception handler (return address removed)
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
443 // rax: exception
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
444 // rbx: exception handler
0
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // rdx: throwing pc
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1192
diff changeset
446 __ jmp(handler_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
454 //
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // xchg exists as far back as 8086, lock needed for MP only
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Stack layout immediately after call:
a61af66fc99e Initial load
duke
parents:
diff changeset
457 //
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // 0 [ret addr ] <--- rsp
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // 1 [ ex ]
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // 2 [ dest ]
a61af66fc99e Initial load
duke
parents:
diff changeset
461 //
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // Result: *dest <- ex, return (old *dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
463 //
a61af66fc99e Initial load
duke
parents:
diff changeset
464 // Note: win32 does not currently use this code
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 address generate_atomic_xchg() {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 StubCodeMark mark(this, "StubRoutines", "atomic_xchg");
a61af66fc99e Initial load
duke
parents:
diff changeset
468 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
469
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
470 __ push(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
471 Address exchange(rsp, 2 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 Address dest_addr(rsp, 3 * wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 __ movl(rax, exchange);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
474 __ movptr(rdx, dest_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
475 __ xchgl(rax, Address(rdx, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
476 __ pop(rdx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
477 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // Support for void verify_mxcsr()
a61af66fc99e Initial load
duke
parents:
diff changeset
484 //
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // MXCSR register to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
488
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 address generate_verify_mxcsr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 StubCodeMark mark(this, "StubRoutines", "verify_mxcsr");
a61af66fc99e Initial load
duke
parents:
diff changeset
492 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 const Address mxcsr_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (CheckJNICalls && UseSSE > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 Label ok_ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 ExternalAddress mxcsr_std(StubRoutines::addr_mxcsr_std());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
499 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
500 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 __ stmxcsr(mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 __ movl(rax, mxcsr_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
503 __ andl(rax, MXCSR_MASK);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 __ cmp32(rax, mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 __ warn("MXCSR changed by native JNI code.");
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 __ ldmxcsr(mxcsr_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
512 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
513 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521
a61af66fc99e Initial load
duke
parents:
diff changeset
522 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Support for void verify_fpu_cntrl_wrd()
a61af66fc99e Initial load
duke
parents:
diff changeset
524 //
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // This routine is used with -Xcheck:jni to verify that native
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // JNI code does not return to Java code without restoring the
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // FP control word to our expected state.
a61af66fc99e Initial load
duke
parents:
diff changeset
528
a61af66fc99e Initial load
duke
parents:
diff changeset
529 address generate_verify_fpu_cntrl_wrd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 StubCodeMark mark(this, "StubRoutines", "verify_spcw");
a61af66fc99e Initial load
duke
parents:
diff changeset
531 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 const Address fpu_cntrl_wrd_save(rsp, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
534
a61af66fc99e Initial load
duke
parents:
diff changeset
535 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 Label ok_ret;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
537 __ push(rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
538 __ subptr(rsp, wordSize); // allocate a temp location
0
a61af66fc99e Initial load
duke
parents:
diff changeset
539 __ fnstcw(fpu_cntrl_wrd_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 __ movl(rax, fpu_cntrl_wrd_save);
a61af66fc99e Initial load
duke
parents:
diff changeset
541 __ andl(rax, FPU_CNTRL_WRD_MASK);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 ExternalAddress fpu_std(StubRoutines::addr_fpu_cntrl_wrd_std());
a61af66fc99e Initial load
duke
parents:
diff changeset
543 __ cmp32(rax, fpu_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 __ jcc(Assembler::equal, ok_ret);
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 __ warn("Floating point control word changed by native JNI code.");
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 __ fldcw(fpu_std);
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 __ bind(ok_ret);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
551 __ addptr(rsp, wordSize);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
552 __ pop(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // Wrapper for slow-case handling of double-to-integer conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // d2i or f2i fast case failed either because it is nan or because
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // of under/overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // Input: FPU TOS: float value
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // Output: rax, (rdx): integer (long) result
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 address generate_d2i_wrapper(BasicType t, address fcn) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 StubCodeMark mark(this, "StubRoutines", "d2i_wrapper");
a61af66fc99e Initial load
duke
parents:
diff changeset
569 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Capture info about frame layout
a61af66fc99e Initial load
duke
parents:
diff changeset
572 enum layout { FPUState_off = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
573 rbp_off = FPUStateSizeInWords,
a61af66fc99e Initial load
duke
parents:
diff changeset
574 rdi_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
575 rsi_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
576 rcx_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
577 rbx_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
578 saved_argument_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
579 saved_argument_off2, // 2nd half of double
a61af66fc99e Initial load
duke
parents:
diff changeset
580 framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
581 };
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 assert(FPUStateSizeInWords == 27, "update stack layout");
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Save outgoing argument to stack across push_FPU_state()
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
586 __ subptr(rsp, wordSize * 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
587 __ fstp_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 // Save CPU & FPU state
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
590 __ push(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
591 __ push(rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
592 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
593 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
594 __ push(rbp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
595 __ push_FPU_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 // push_FPU_state() resets the FP top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
598 // Load original double into FP top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
599 __ fld_d(Address(rsp, saved_argument_off * wordSize));
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // Store double into stack as outgoing argument
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
601 __ subptr(rsp, wordSize*2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
602 __ fst_d(Address(rsp, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Prepare FPU for doing math in C-land
a61af66fc99e Initial load
duke
parents:
diff changeset
605 __ empty_FPU_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // Call the C code to massage the double. Result in EAX
a61af66fc99e Initial load
duke
parents:
diff changeset
607 if (t == T_INT)
a61af66fc99e Initial load
duke
parents:
diff changeset
608 { BLOCK_COMMENT("SharedRuntime::d2i"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
609 else if (t == T_LONG)
a61af66fc99e Initial load
duke
parents:
diff changeset
610 { BLOCK_COMMENT("SharedRuntime::d2l"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
611 __ call_VM_leaf( fcn, 2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // Restore CPU & FPU state
a61af66fc99e Initial load
duke
parents:
diff changeset
614 __ pop_FPU_state();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
615 __ pop(rbp);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
616 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
617 __ pop(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
618 __ pop(rcx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
619 __ pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
620 __ addptr(rsp, wordSize * 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // The following routine generates a subroutine to throw an asynchronous
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // UnknownError when an unsafe access gets a fault that could not be
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // reasonably prevented by the programmer. (Example: SIGBUS/OBJERR.)
a61af66fc99e Initial load
duke
parents:
diff changeset
632 address generate_handler_for_unsafe_access() {
a61af66fc99e Initial load
duke
parents:
diff changeset
633 StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
634 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
635
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
636 __ push(0); // hole for return address-to-be
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
637 __ pusha(); // push registers
0
a61af66fc99e Initial load
duke
parents:
diff changeset
638 Address next_pc(rsp, RegisterImpl::number_of_registers * BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 BLOCK_COMMENT("call handle_unsafe_access");
a61af66fc99e Initial load
duke
parents:
diff changeset
640 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, handle_unsafe_access)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
641 __ movptr(next_pc, rax); // stuff next address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
642 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
643 __ ret(0); // jump to next address
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 //----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // Non-destructive plausibility checks for oops
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 address generate_verify_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 StubCodeMark mark(this, "StubRoutines", "verify_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
654 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // Incoming arguments on stack after saving rax,:
a61af66fc99e Initial load
duke
parents:
diff changeset
657 //
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // [tos ]: saved rdx
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // [tos + 1]: saved EFLAGS
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // [tos + 2]: return address
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // [tos + 3]: char* error message
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // [tos + 4]: oop object to verify
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // [tos + 5]: saved rax, - saved by caller and bashed
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 Label exit, error;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
666 __ pushf();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
667 __ incrementl(ExternalAddress((address) StubRoutines::verify_oop_count_addr()));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
668 __ push(rdx); // save rdx
0
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // make sure object is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
670 __ movptr(rax, Address(rsp, 4 * wordSize)); // get object
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
671 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
672 __ jcc(Assembler::zero, exit); // if obj is NULL it is ok
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // Check if the oop is in the right area of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
675 const int oop_mask = Universe::verify_oop_mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
676 const int oop_bits = Universe::verify_oop_bits();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
677 __ mov(rdx, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
678 __ andptr(rdx, oop_mask);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
679 __ cmpptr(rdx, oop_bits);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
680 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // make sure klass is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
683 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
684 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
685 __ jcc(Assembler::zero, error); // if klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // Check if the klass is in the right area of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
688 const int klass_mask = Universe::verify_klass_mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
689 const int klass_bits = Universe::verify_klass_bits();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
690 __ mov(rdx, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
691 __ andptr(rdx, klass_mask);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
692 __ cmpptr(rdx, klass_bits);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
693 __ jcc(Assembler::notZero, error);
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // make sure klass' klass is 'reasonable'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
696 __ movptr(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass' klass
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
697 __ testptr(rax, rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
698 __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
a61af66fc99e Initial load
duke
parents:
diff changeset
699
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
700 __ mov(rdx, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
701 __ andptr(rdx, klass_mask);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
702 __ cmpptr(rdx, klass_bits);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
703 __ jcc(Assembler::notZero, error); // if klass not in right area
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // of memory it is broken too.
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // return if everything seems ok
a61af66fc99e Initial load
duke
parents:
diff changeset
707 __ bind(exit);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
708 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
709 __ pop(rdx); // restore rdx
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
710 __ popf(); // restore EFLAGS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
711 __ ret(3 * wordSize); // pop arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // handle errors
a61af66fc99e Initial load
duke
parents:
diff changeset
714 __ bind(error);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
715 __ movptr(rax, Address(rsp, 5 * wordSize)); // get saved rax, back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
716 __ pop(rdx); // get saved rdx back
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
717 __ popf(); // get saved EFLAGS off stack -- will be ignored
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
718 __ pusha(); // push registers (eip = return address & msg are already pushed)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
719 BLOCK_COMMENT("call MacroAssembler::debug");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
720 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
721 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
722 __ ret(3 * wordSize); // pop arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
723 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 //
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Generate pre-barrier for array stores
a61af66fc99e Initial load
duke
parents:
diff changeset
728 //
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // start - starting address
845
df6caf649ff7 6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents: 710
diff changeset
731 // count - element count
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
732 void gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
733 assert_different_registers(start, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
735 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
736 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
737 case BarrierSet::G1SATBCTLogging:
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
738 // 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: 2321
diff changeset
739 if (!uninitialized_target) {
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
740 __ pusha(); // push registers
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
741 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
742 start, count);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
743 __ popa();
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
744 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
745 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
746 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
747 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
748 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
749 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
750 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
751 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 //
a61af66fc99e Initial load
duke
parents:
diff changeset
758 // Generate a post-barrier for an array store
a61af66fc99e Initial load
duke
parents:
diff changeset
759 //
a61af66fc99e Initial load
duke
parents:
diff changeset
760 // start - starting address
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // count - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
762 //
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // The two input registers are overwritten.
a61af66fc99e Initial load
duke
parents:
diff changeset
764 //
a61af66fc99e Initial load
duke
parents:
diff changeset
765 void gen_write_ref_array_post_barrier(Register start, Register count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 BarrierSet* bs = Universe::heap()->barrier_set();
a61af66fc99e Initial load
duke
parents:
diff changeset
767 assert_different_registers(start, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
768 switch (bs->kind()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
769 case BarrierSet::G1SATBCT:
a61af66fc99e Initial load
duke
parents:
diff changeset
770 case BarrierSet::G1SATBCTLogging:
a61af66fc99e Initial load
duke
parents:
diff changeset
771 {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
772 __ pusha(); // push registers
1192
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
773 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post),
776fb94f33cc 6918006: G1: spill space must be reserved on the stack for barrier calls on Windows x64
apetrusenko
parents: 1174
diff changeset
774 start, count);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
775 __ popa();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
780 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
781 {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 Label L_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
786 const Register end = count; // elements count; end == start+count-1
a61af66fc99e Initial load
duke
parents:
diff changeset
787 assert_different_registers(start, end);
a61af66fc99e Initial load
duke
parents:
diff changeset
788
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
789 __ lea(end, Address(start, count, Address::times_ptr, -wordSize));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
790 __ shrptr(start, CardTableModRefBS::card_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
791 __ shrptr(end, CardTableModRefBS::card_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
792 __ subptr(end, start); // end --> count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
793 __ BIND(L_loop);
249
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
794 intptr_t disp = (intptr_t) ct->byte_map_base;
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
795 Address cardtable(start, count, Address::times_1, disp);
910a4cb98e9e 6717457: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
never
parents: 19
diff changeset
796 __ movb(cardtable, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
797 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 __ jcc(Assembler::greaterEqual, L_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
801 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
802 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
804 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
808
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
809
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
810 // Copy 64 bytes chunks
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
811 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
812 // Inputs:
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
813 // from - source array address
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
814 // to_from - destination array address - from
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
815 // qword_count - 8-bytes element count, negative
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
816 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
817 void xmm_copy_forward(Register from, Register to_from, Register qword_count) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
818 assert( UseSSE >= 2, "supported cpu only" );
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
819 Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
820 // Copy 64-byte chunks
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
821 __ jmpb(L_copy_64_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
822 __ align(OptoLoopAlignment);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
823 __ BIND(L_copy_64_bytes_loop);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
824
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
825 if(UseUnalignedLoadStores) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
826 __ movdqu(xmm0, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
827 __ movdqu(Address(from, to_from, Address::times_1, 0), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
828 __ movdqu(xmm1, Address(from, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
829 __ movdqu(Address(from, to_from, Address::times_1, 16), xmm1);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
830 __ movdqu(xmm2, Address(from, 32));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
831 __ movdqu(Address(from, to_from, Address::times_1, 32), xmm2);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
832 __ movdqu(xmm3, Address(from, 48));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
833 __ movdqu(Address(from, to_from, Address::times_1, 48), xmm3);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
834
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
835 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
836 __ movq(xmm0, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
837 __ movq(Address(from, to_from, Address::times_1, 0), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
838 __ movq(xmm1, Address(from, 8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
839 __ movq(Address(from, to_from, Address::times_1, 8), xmm1);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
840 __ movq(xmm2, Address(from, 16));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
841 __ movq(Address(from, to_from, Address::times_1, 16), xmm2);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
842 __ movq(xmm3, Address(from, 24));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
843 __ movq(Address(from, to_from, Address::times_1, 24), xmm3);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
844 __ movq(xmm4, Address(from, 32));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
845 __ movq(Address(from, to_from, Address::times_1, 32), xmm4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
846 __ movq(xmm5, Address(from, 40));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
847 __ movq(Address(from, to_from, Address::times_1, 40), xmm5);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
848 __ movq(xmm6, Address(from, 48));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
849 __ movq(Address(from, to_from, Address::times_1, 48), xmm6);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
850 __ movq(xmm7, Address(from, 56));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
851 __ movq(Address(from, to_from, Address::times_1, 56), xmm7);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
852 }
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
853
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
854 __ addl(from, 64);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
855 __ BIND(L_copy_64_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
856 __ subl(qword_count, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
857 __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
858 __ addl(qword_count, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
859 __ jccb(Assembler::zero, L_exit);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
860 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
861 // length is too short, just copy qwords
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
862 //
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
863 __ BIND(L_copy_8_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
864 __ movq(xmm0, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
865 __ movq(Address(from, to_from, Address::times_1), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
866 __ addl(from, 8);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
867 __ decrement(qword_count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
868 __ jcc(Assembler::greater, L_copy_8_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
869 __ BIND(L_exit);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
870 }
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
871
0
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Copy 64 bytes chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
873 //
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // from - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // to_from - destination array address - from
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // qword_count - 8-bytes element count, negative
a61af66fc99e Initial load
duke
parents:
diff changeset
878 //
a61af66fc99e Initial load
duke
parents:
diff changeset
879 void mmx_copy_forward(Register from, Register to_from, Register qword_count) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
880 assert( VM_Version::supports_mmx(), "supported cpu only" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
881 Label L_copy_64_bytes_loop, L_copy_64_bytes, L_copy_8_bytes, L_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Copy 64-byte chunks
a61af66fc99e Initial load
duke
parents:
diff changeset
883 __ jmpb(L_copy_64_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
884 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
885 __ BIND(L_copy_64_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
886 __ movq(mmx0, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
887 __ movq(mmx1, Address(from, 8));
a61af66fc99e Initial load
duke
parents:
diff changeset
888 __ movq(mmx2, Address(from, 16));
a61af66fc99e Initial load
duke
parents:
diff changeset
889 __ movq(Address(from, to_from, Address::times_1, 0), mmx0);
a61af66fc99e Initial load
duke
parents:
diff changeset
890 __ movq(mmx3, Address(from, 24));
a61af66fc99e Initial load
duke
parents:
diff changeset
891 __ movq(Address(from, to_from, Address::times_1, 8), mmx1);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 __ movq(mmx4, Address(from, 32));
a61af66fc99e Initial load
duke
parents:
diff changeset
893 __ movq(Address(from, to_from, Address::times_1, 16), mmx2);
a61af66fc99e Initial load
duke
parents:
diff changeset
894 __ movq(mmx5, Address(from, 40));
a61af66fc99e Initial load
duke
parents:
diff changeset
895 __ movq(Address(from, to_from, Address::times_1, 24), mmx3);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 __ movq(mmx6, Address(from, 48));
a61af66fc99e Initial load
duke
parents:
diff changeset
897 __ movq(Address(from, to_from, Address::times_1, 32), mmx4);
a61af66fc99e Initial load
duke
parents:
diff changeset
898 __ movq(mmx7, Address(from, 56));
a61af66fc99e Initial load
duke
parents:
diff changeset
899 __ movq(Address(from, to_from, Address::times_1, 40), mmx5);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 __ movq(Address(from, to_from, Address::times_1, 48), mmx6);
a61af66fc99e Initial load
duke
parents:
diff changeset
901 __ movq(Address(from, to_from, Address::times_1, 56), mmx7);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
902 __ addptr(from, 64);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
903 __ BIND(L_copy_64_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 __ subl(qword_count, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 __ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
906 __ addl(qword_count, 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
907 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 //
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // length is too short, just copy qwords
a61af66fc99e Initial load
duke
parents:
diff changeset
910 //
a61af66fc99e Initial load
duke
parents:
diff changeset
911 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 __ movq(mmx0, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
913 __ movq(Address(from, to_from, Address::times_1), mmx0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
914 __ addptr(from, 8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
915 __ decrement(qword_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 __ jcc(Assembler::greater, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 __ emms();
a61af66fc99e Initial load
duke
parents:
diff changeset
919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
920
a61af66fc99e Initial load
duke
parents:
diff changeset
921 address generate_disjoint_copy(BasicType t, bool aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Address::ScaleFactor sf,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
923 address* entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
924 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
925 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
927 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 Label L_copy_2_bytes, L_copy_4_bytes, L_copy_64_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
931
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
932 int shift = Address::times_ptr - sf;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 const Register from = rsi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
935 const Register to = rdi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
936 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
937 const Register to_from = to; // (to - from)
a61af66fc99e Initial load
duke
parents:
diff changeset
938 const Register saved_to = rdx; // saved destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
941 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
942 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
943 __ movptr(from , Address(rsp, 12+ 4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
944 __ movptr(to , Address(rsp, 12+ 8));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 __ movl(count, Address(rsp, 12+ 12));
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
946
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
947 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
948 *entry = __ pc(); // Entry point from conjoint arraycopy stub.
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
949 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
950 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
951
0
a61af66fc99e Initial load
duke
parents:
diff changeset
952 if (t == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 __ testl(count, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 __ jcc(Assembler::zero, L_0_count);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
955 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
956 __ mov(saved_to, to); // save 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
958
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
959 __ subptr(to, from); // to --> to_from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
960 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
961 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
962 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // align source address at 4 bytes address boundary
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // One byte misalignment happens only for byte arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
966 __ testl(from, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 __ jccb(Assembler::zero, L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
968 __ movb(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
969 __ movb(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
970 __ increment(from);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
972 __ BIND(L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // Two bytes misalignment happens only for byte and short (char) arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
975 __ testl(from, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
976 __ jccb(Assembler::zero, L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
977 __ movw(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
978 __ movw(Address(from, to_from, Address::times_1, 0), rax);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
979 __ addptr(from, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
980 __ subl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
981 __ BIND(L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 if (!VM_Version::supports_mmx()) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
984 __ mov(rax, count); // save 'count'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
985 __ shrl(count, shift); // bytes count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
986 __ addptr(to_from, from);// restore 'to'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
987 __ rep_mov();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
988 __ subptr(to_from, from);// restore 'to_from'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
989 __ mov(count, rax); // restore 'count'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
990 __ jmpb(L_copy_2_bytes); // all dwords were copied
a61af66fc99e Initial load
duke
parents:
diff changeset
991 } else {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
992 if (!UseUnalignedLoadStores) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
993 // align to 8 bytes, we know we are 4 byte aligned to start
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
994 __ testptr(from, 4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
995 __ jccb(Assembler::zero, L_copy_64_bytes);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
996 __ movl(rax, Address(from, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
997 __ movl(Address(from, to_from, Address::times_1, 0), rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
998 __ addptr(from, 4);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
999 __ subl(count, 1<<shift);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1000 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 __ BIND(L_copy_64_bytes);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1002 __ mov(rax, count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 __ shrl(rax, shift+1); // 8 bytes chunk count
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // Copy 8-byte chunks through MMX registers, 8 per iteration of the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 //
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1007 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1008 xmm_copy_forward(from, to_from, rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1009 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1010 mmx_copy_forward(from, to_from, rax);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1011 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // copy tailing dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 __ BIND(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 __ testl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 __ movl(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 __ movl(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 if (t == T_BYTE || t == T_SHORT) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1020 __ addptr(from, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // copy tailing word
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 __ testl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 __ movw(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 __ movw(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if (t == T_BYTE) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1028 __ addptr(from, 2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // copy tailing byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 __ testl(count, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 __ movb(rax, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 __ movb(Address(from, to_from, Address::times_1, 0), rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 if (t == T_OBJECT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 __ movl(count, Address(rsp, 12+12)); // reread 'count'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1045 __ mov(to, saved_to); // restore 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 __ BIND(L_0_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 inc_copy_counter_np(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1050 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1051 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1053 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1059 address generate_fill(BasicType t, bool aligned, const char *name) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1060 __ align(CodeEntryAlignment);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1061 StubCodeMark mark(this, "StubRoutines", name);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1062 address start = __ pc();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1063
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1064 BLOCK_COMMENT("Entry:");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1065
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1066 const Register to = rdi; // source array address
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1067 const Register value = rdx; // value
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1068 const Register count = rsi; // elements count
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1069
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1070 __ enter(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1071 __ push(rsi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1072 __ push(rdi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1073 __ movptr(to , Address(rsp, 12+ 4));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1074 __ movl(value, Address(rsp, 12+ 8));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1075 __ movl(count, Address(rsp, 12+ 12));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1076
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1077 __ generate_fill(t, aligned, to, value, count, rax, xmm0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1078
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1079 __ pop(rdi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1080 __ pop(rsi);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1081 __ leave(); // required for proper stackwalking of RuntimeStub frame
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1082 __ ret(0);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1083 return start;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1084 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
1085
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 address generate_conjoint_copy(BasicType t, bool aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 Address::ScaleFactor sf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 address nooverlap_target,
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1089 address* entry, const char *name,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1090 bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1094
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 Label L_copy_2_bytes, L_copy_4_bytes, L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1098 int shift = Address::times_ptr - sf;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 const Register src = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 const Register dst = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 const Register from = rsi; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 const Register to = rdi; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 const Register end = rax; // array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1108 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1109 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1110 __ movptr(src , Address(rsp, 12+ 4)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1111 __ movptr(dst , Address(rsp, 12+ 8)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1112 __ movl2ptr(count, Address(rsp, 12+12)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 if (entry != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 *entry = __ pc(); // Entry point from generic arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1119 // nooverlap_target expects arguments in rsi and rdi.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1120 __ mov(from, src);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1121 __ mov(to , dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1122
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1123 // arrays overlap test: dispatch to disjoint stub if necessary.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 RuntimeAddress nooverlap(nooverlap_target);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1125 __ cmpptr(dst, src);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1126 __ lea(end, Address(src, count, sf, 0)); // src + count * elem_size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 __ jump_cc(Assembler::belowEqual, nooverlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1128 __ cmpptr(dst, end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 __ jump_cc(Assembler::aboveEqual, nooverlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1131 if (t == T_OBJECT) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1132 __ testl(count, count);
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1133 __ jcc(Assembler::zero, L_0_count);
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1134 gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1135 }
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1136
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // copy from high to low
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if (t == T_BYTE || t == T_SHORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // Align the end of destination array at 4 bytes address boundary
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1142 __ lea(end, Address(dst, count, sf, 0));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // One byte misalignment happens only for byte arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 __ testl(end, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 __ jccb(Assembler::zero, L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 __ movb(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 __ movb(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 __ BIND(L_skip_align1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // Two bytes misalignment happens only for byte and short (char) arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 __ testl(end, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 __ jccb(Assembler::zero, L_skip_align2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1155 __ subptr(count, 1<<(shift-1));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 __ movw(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 __ movw(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 __ BIND(L_skip_align2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 __ jcc(Assembler::below, L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (!VM_Version::supports_mmx()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 __ std();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1165 __ mov(rax, count); // Save 'count'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1166 __ mov(rdx, to); // Save 'to'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1167 __ lea(rsi, Address(from, count, sf, -4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1168 __ lea(rdi, Address(to , count, sf, -4));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1169 __ shrptr(count, shift); // bytes count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1170 __ rep_mov();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 __ cld();
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1172 __ mov(count, rax); // restore 'count'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 __ andl(count, (1<<shift)-1); // mask the number of rest elements
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1174 __ movptr(from, Address(rsp, 12+4)); // reread 'from'
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1175 __ mov(to, rdx); // restore 'to'
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 __ jmpb(L_copy_2_bytes); // all dword were copied
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // Align to 8 bytes the end of array. It is aligned to 4 bytes already.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1179 __ testptr(end, 4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 __ jccb(Assembler::zero, L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 __ subl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 __ movl(rdx, Address(from, count, sf, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 __ movl(Address(to, count, sf, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 __ jmpb(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1186 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // Move 8 bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 __ BIND(L_copy_8_bytes_loop);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1189 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1190 __ movq(xmm0, Address(from, count, sf, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1191 __ movq(Address(to, count, sf, 0), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1192 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1193 __ movq(mmx0, Address(from, count, sf, 0));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1194 __ movq(Address(to, count, sf, 0), mmx0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1195 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 __ subl(count, 2<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 __ addl(count, 2<<shift);
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1200 if (!UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1201 __ emms();
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1202 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 __ BIND(L_copy_4_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // copy prefix qword
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 __ testl(count, 1<<shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 __ jccb(Assembler::zero, L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 __ movl(rdx, Address(from, count, sf, -4));
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 __ movl(Address(to, count, sf, -4), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if (t == T_BYTE || t == T_SHORT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 __ subl(count, (1<<shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // copy prefix dword
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 __ testl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 __ jccb(Assembler::zero, L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 __ movw(rdx, Address(from, count, sf, -2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 __ movw(Address(to, count, sf, -2), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 if (t == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 __ subl(count, 1<<(shift-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // copy prefix byte
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 __ testl(count, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 __ jccb(Assembler::zero, L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 __ movb(rdx, Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 __ movb(Address(to, 0), rdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 __ BIND(L_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 __ BIND(L_copy_byte);
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 __ BIND(L_copy_2_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (t == T_OBJECT) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1235 __ movl2ptr(count, Address(rsp, 12+12)); // reread count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 __ BIND(L_0_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 inc_copy_counter_np(t);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1240 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1241 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1243 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 address generate_disjoint_long_copy(address* entry, const char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1253
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 Label L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 const Register to_from = rdx; // (to - from)
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1261 __ movptr(from , Address(rsp, 8+0)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1262 __ movptr(to , Address(rsp, 8+4)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1263 __ movl2ptr(count, Address(rsp, 8+8)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 *entry = __ pc(); // Entry point from conjoint arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1268 __ subptr(to, from); // to --> to_from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 if (VM_Version::supports_mmx()) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1270 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1271 xmm_copy_forward(from, to_from, count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1272 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1273 mmx_copy_forward(from, to_from, count);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1274 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 __ jmpb(L_copy_8_bytes);
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1277 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 __ BIND(L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 __ fild_d(Address(from, 0));
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 __ fistp_d(Address(from, to_from, Address::times_1));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1281 __ addptr(from, 8);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 inc_copy_counter_np(T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1288 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 address generate_conjoint_long_copy(address nooverlap_target,
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 address* entry, const char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 Label L_copy_8_bytes, L_copy_8_bytes_loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 const Register end_from = rax; // source array end address
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1306 __ movptr(from , Address(rsp, 8+0)); // from
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1307 __ movptr(to , Address(rsp, 8+4)); // to
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1308 __ movl2ptr(count, Address(rsp, 8+8)); // count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1309
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 *entry = __ pc(); // Entry point from generic arraycopy stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 BLOCK_COMMENT("Entry:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1312
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // arrays overlap test
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1314 __ cmpptr(to, from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 RuntimeAddress nooverlap(nooverlap_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 __ jump_cc(Assembler::belowEqual, nooverlap);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1317 __ lea(end_from, Address(from, count, Address::times_8, 0));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1318 __ cmpptr(to, end_from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1319 __ movptr(from, Address(rsp, 8)); // from
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 __ jump_cc(Assembler::aboveEqual, nooverlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 __ jmpb(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1324 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 __ BIND(L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 if (VM_Version::supports_mmx()) {
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1327 if (UseXMMForArrayCopy) {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1328 __ movq(xmm0, Address(from, count, Address::times_8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1329 __ movq(Address(to, count, Address::times_8), xmm0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1330 } else {
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1331 __ movq(mmx0, Address(from, count, Address::times_8));
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1332 __ movq(Address(to, count, Address::times_8), mmx0);
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1333 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 __ fild_d(Address(from, count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 __ fistp_d(Address(to, count, Address::times_8));
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 __ BIND(L_copy_8_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 __ decrement(count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 __ jcc(Assembler::greaterEqual, L_copy_8_bytes_loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
405
2649e5276dd7 6532536: Optimize arraycopy stubs for Intel cpus
kvn
parents: 362
diff changeset
1342 if (VM_Version::supports_mmx() && !UseXMMForArrayCopy) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 __ emms();
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 inc_copy_counter_np(T_LONG);
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 __ leave(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1347 __ xorptr(rax, rax); // return 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // Helper for generating a dynamic type check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // The sub_klass must be one of {rbx, rdx, rsi}.
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // The temp is killed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 void generate_type_check(Register sub_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 Address& super_check_offset_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 Address& super_klass_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 Register temp,
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1360 Label* L_success, Label* L_failure) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 BLOCK_COMMENT("type_check:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1362
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 Label L_fallthrough;
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1364 #define LOCAL_JCC(assembler_con, label_ptr) \
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1365 if (label_ptr != NULL) __ jcc(assembler_con, *(label_ptr)); \
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1366 else __ jcc(assembler_con, L_fallthrough) /*omit semi*/
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1367
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1368 // The following is a strange variation of the fast path which requires
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1369 // one less register, because needed values are on the argument stack.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1370 // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1371 // L_success, L_failure, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 assert_different_registers(sub_klass, temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 Klass::secondary_super_cache_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // if the pointers are equal, we are done (e.g., String[] elements)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1378 __ cmpptr(sub_klass, super_klass_addr);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1379 LOCAL_JCC(Assembler::equal, L_success);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1380
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // check the supertype display:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1382 __ movl2ptr(temp, super_check_offset_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 Address super_check_addr(sub_klass, temp, Address::times_1, 0);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1384 __ movptr(temp, super_check_addr); // load displayed supertype
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1385 __ cmpptr(temp, super_klass_addr); // test the super type
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1386 LOCAL_JCC(Assembler::equal, L_success);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // if it was a primary super, we can just fail immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 __ cmpl(super_check_offset_addr, sc_offset);
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1390 LOCAL_JCC(Assembler::notEqual, L_failure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1391
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1392 // The repne_scan instruction uses fixed registers, which will get spilled.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1393 // We happen to know this works best when super_klass is in rax.
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1394 Register super_klass = temp;
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1395 __ movptr(super_klass, super_klass_addr);
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1396 __ check_klass_subtype_slow_path(sub_klass, super_klass, noreg, noreg,
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1397 L_success, L_failure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1398
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1399 __ bind(L_fallthrough);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1401 if (L_success == NULL) { BLOCK_COMMENT("L_success:"); }
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1402 if (L_failure == NULL) { BLOCK_COMMENT("L_failure:"); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1403
644
c517646eef23 6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents: 533
diff changeset
1404 #undef LOCAL_JCC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1406
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // Generate checkcasting array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // 4(rsp) - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // 8(rsp) - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // 12(rsp) - element count, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // 16(rsp) - size_t ckoff (super_check_offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // 20(rsp) - oop ckval (super_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // rax, == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 //
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1421 address generate_checkcast_copy(const char *name, address* entry, bool dest_uninitialized = false) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 Label L_load_element, L_store_element, L_do_card_marks, L_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 // register use:
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 // rax, rdx, rcx -- loop control (end_from, end_to, count)
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 // rdi, rsi -- element access (oop, klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 // rbx, -- temp
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 const Register length = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 const Register elem = rdi; // each oop copied
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 const Register elem_klass = rsi; // each elem._klass (sub_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 const Register temp = rbx; // lone remaining temp
a61af66fc99e Initial load
duke
parents:
diff changeset
1438
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1440
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1441 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1442 __ push(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1443 __ push(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1444
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 Address from_arg(rsp, 16+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 Address to_arg(rsp, 16+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 Address length_arg(rsp, 16+12); // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 Address ckoff_arg(rsp, 16+16); // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 Address ckval_arg(rsp, 16+20); // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Load up:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1452 __ movptr(from, from_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1453 __ movptr(to, to_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1454 __ movl2ptr(length, length_arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1455
2313
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1456 if (entry != NULL) {
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1457 *entry = __ pc(); // Entry point from generic arraycopy stub.
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1458 BLOCK_COMMENT("Entry:");
d89a22843c62 7020521: arraycopy stubs place prebarriers incorrectly
iveresov
parents: 2245
diff changeset
1459 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1460
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 //---------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 // if the two arrays are subtypes of Object[] but the
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // destination array type is not equal to or a supertype
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // of the source type. Each element must be separately
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1467
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // Loop-invariant addresses. They are exclusive end pointers.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1469 Address end_from_addr(from, length, Address::times_ptr, 0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1470 Address end_to_addr(to, length, Address::times_ptr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1471
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 Register end_from = from; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 Register end_to = to; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 Register count = length; // re-use
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // Loop-variant addresses. They assume post-incremented count < 0.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1477 Address from_element_addr(end_from, count, Address::times_ptr, 0);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1478 Address to_element_addr(end_to, count, Address::times_ptr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1480
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // Copy from low to high addresses, indexed from the end of each array.
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
1482 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1483 __ lea(end_from, end_from_addr);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1484 __ lea(end_to, end_to_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 assert(length == count, ""); // else fix next line:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1486 __ negptr(count); // negate and test the length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 __ jccb(Assembler::notZero, L_load_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // Empty array: Nothing to do.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1490 __ xorptr(rax, rax); // return 0 on (trivial) success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 __ jmp(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // ======== begin loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 // (Loop is rotated; its entry is L_load_element.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 // Loop control:
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // for (count = -count; count != 0; count++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // Base pointers src, dst are biased by 8*count,to last element.
1365
6476042f815c 6940701: Don't align loops in stubs for Niagara sparc
kvn
parents: 1299
diff changeset
1498 __ align(OptoLoopAlignment);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1499
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 __ BIND(L_store_element);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1501 __ movptr(to_element_addr, elem); // store the oop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 __ increment(count); // increment the count toward zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 __ jccb(Assembler::zero, L_do_card_marks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // ======== loop entry is here ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 __ BIND(L_load_element);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1507 __ movptr(elem, from_element_addr); // load the oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1508 __ testptr(elem, elem);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 __ jccb(Assembler::zero, L_store_element);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // (Could do a trick here: Remember last successful non-null
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 // element stored and make a quick oop equality check on it.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1514 __ movptr(elem_klass, elem_klass_addr); // query the object klass
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 generate_type_check(elem_klass, ckoff_arg, ckval_arg, temp,
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 &L_store_element, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // (On fall-through, we have failed the element type check.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // ======== end loop ========
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // It was a real error; we must depend on the caller to finish the job.
19
a73cc31728fe 6614036: REGRESSION: Java server x86 VM intermittently crash with SIGSEGV (0xb)
rasbold
parents: 16
diff changeset
1521 // Register "count" = -1 * number of *remaining* oops, length_arg = *total* oops.
a73cc31728fe 6614036: REGRESSION: Java server x86 VM intermittently crash with SIGSEGV (0xb)
rasbold
parents: 16
diff changeset
1522 // Emit GC store barriers for the oops we have copied (length_arg + count),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // and report their number to the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 __ addl(count, length_arg); // transfers = (length - remaining)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1525 __ movl2ptr(rax, count); // save the value
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1526 __ notptr(rax); // report (-1^K) to caller
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1527 __ movptr(to, to_arg); // reload
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 assert_different_registers(to, count, rax);
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 gen_write_ref_array_post_barrier(to, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 __ jmpb(L_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1531
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // Come here on success only.
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 __ BIND(L_do_card_marks);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1534 __ movl2ptr(count, length_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1535 __ movptr(to, to_arg); // reload
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 gen_write_ref_array_post_barrier(to, count);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1537 __ xorptr(rax, rax); // return 0 on success
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1538
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // Common exit point (success or failure).
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 __ BIND(L_done);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1541 __ pop(rbx);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1542 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1543 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // Generate 'unsafe' array copy stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // Though just as safe as the other stubs, it takes an unscaled
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // size_t argument instead of an element count.
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 // 4(rsp) - source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // 8(rsp) - destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 // 12(rsp) - byte count, can be zero
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 // rax, == -1 - need to call System.arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // Examines the alignment of the operands and dispatches
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 // to a long, int, short, or byte copy loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 address generate_unsafe_copy(const char *name,
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 address byte_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 address short_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 address int_copy_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 address long_copy_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 Label L_long_aligned, L_int_aligned, L_short_aligned;
a61af66fc99e Initial load
duke
parents:
diff changeset
1575
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1579
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 const Register from = rax; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 const Register to = rdx; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1585 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1586 __ push(rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 Address from_arg(rsp, 12+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 Address to_arg(rsp, 12+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 Address count_arg(rsp, 12+12); // byte count
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 // Load up:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1592 __ movptr(from , from_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1593 __ movptr(to , to_arg);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1594 __ movl2ptr(count, count_arg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1595
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 inc_counter_np(SharedRuntime::_unsafe_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 const Register bits = rsi;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1600 __ mov(bits, from);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1601 __ orptr(bits, to);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1602 __ orptr(bits, count);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1603
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 __ testl(bits, BytesPerLong-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 __ jccb(Assembler::zero, L_long_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
1606
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 __ testl(bits, BytesPerInt-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 __ jccb(Assembler::zero, L_int_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
1609
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 __ testl(bits, BytesPerShort-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 __ jump_cc(Assembler::notZero, RuntimeAddress(byte_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1612
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 __ BIND(L_short_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1614 __ shrptr(count, LogBytesPerShort); // size => short_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 __ movl(count_arg, count); // update 'count'
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 __ jump(RuntimeAddress(short_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 __ BIND(L_int_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1619 __ shrptr(count, LogBytesPerInt); // size => int_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 __ movl(count_arg, count); // update 'count'
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 __ jump(RuntimeAddress(int_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1622
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 __ BIND(L_long_aligned);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1624 __ shrptr(count, LogBytesPerLong); // size => qword_count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 __ movl(count_arg, count); // update 'count'
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1626 __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1627 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 __ jump(RuntimeAddress(long_copy_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
1629
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // Perform range checks on the proposed arraycopy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // Smashes src_pos and dst_pos. (Uses them up for temps.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 void arraycopy_range_checks(Register src,
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 Register src_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 Register dst,
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 Register dst_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 Address& length,
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 Label& L_failed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 BLOCK_COMMENT("arraycopy_range_checks:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 const Register src_end = src_pos; // source array end position
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 const Register dst_end = dst_pos; // destination array end position
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 __ addl(src_end, length); // src_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 __ addl(dst_end, length); // dst_pos + length
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // if (src_pos + length > arrayOop(src)->length() ) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 __ cmpl(src_end, Address(src, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1651
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // if (dst_pos + length > arrayOop(dst)->length() ) FAIL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 __ cmpl(dst_end, Address(dst, arrayOopDesc::length_offset_in_bytes()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 __ jcc(Assembler::above, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1655
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 BLOCK_COMMENT("arraycopy_range_checks done");
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1658
a61af66fc99e Initial load
duke
parents:
diff changeset
1659
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 // Generate generic array copy stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 // Input:
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // 4(rsp) - src oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // 8(rsp) - src_pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // 12(rsp) - dst oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // 16(rsp) - dst_pos
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 // 20(rsp) - element count
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // Output:
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // rax, == 0 - success
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // rax, == -1^K - failure, where K is partial transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 address generate_generic_copy(const char *name,
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 address entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 address entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 address entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 address entry_oop_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 address entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 address entry_checkcast_arraycopy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 Label L_failed, L_failed_0, L_objArray;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 { int modulus = CodeEntryAlignment;
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 int target = modulus - 5; // 5 = sizeof jmp(L_failed)
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 int advance = target - (__ offset() % modulus);
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 if (advance < 0) advance += modulus;
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 if (advance > 0) __ nop(advance);
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 StubCodeMark mark(this, "StubRoutines", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // Short-hop target to L_failed. Makes for denser prologue code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 __ BIND(L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 __ jmp(L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 assert(__ offset() % CodeEntryAlignment == 0, "no further alignment needed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1695
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1698
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 __ enter(); // required for proper stackwalking of RuntimeStub frame
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1700 __ push(rsi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1701 __ push(rdi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 // bump this on entry, not on exit:
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 inc_counter_np(SharedRuntime::_generic_array_copy_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 // Input values
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 Address SRC (rsp, 12+ 4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 Address SRC_POS (rsp, 12+ 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 Address DST (rsp, 12+12);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 Address DST_POS (rsp, 12+16);
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 Address LENGTH (rsp, 12+20);
a61af66fc99e Initial load
duke
parents:
diff changeset
1712
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 //-----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // Assembler stub will be used for this call to arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 // if the following conditions are met:
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 // (1) src and dst must not be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 // (2) src_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // (3) dst_pos must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // (4) length must not be negative.
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // (5) src klass and dst klass should be the same and not NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 // (6) src and dst should be arrays.
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 // (7) src_pos + length must not exceed length of src.
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // (8) dst_pos + length must not exceed length of dst.
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 const Register src = rax; // source array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 const Register src_pos = rsi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 const Register dst = rdx; // destination array oop
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 const Register dst_pos = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 const Register length = rcx; // transfer count
a61af66fc99e Initial load
duke
parents:
diff changeset
1732
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 // if (src == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1734 __ movptr(src, SRC); // src oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1735 __ testptr(src, src);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // if (src_pos < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1739 __ movl2ptr(src_pos, SRC_POS); // src_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 __ testl(src_pos, src_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1742
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // if (dst == NULL) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1744 __ movptr(dst, DST); // dst oop
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1745 __ testptr(dst, dst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 __ jccb(Assembler::zero, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1747
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 // if (dst_pos < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1749 __ movl2ptr(dst_pos, DST_POS); // dst_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 __ testl(dst_pos, dst_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1752
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // if (length < 0) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1754 __ movl2ptr(length, LENGTH); // length
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 __ testl(length, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 __ jccb(Assembler::negative, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // if (src->klass() == NULL) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 Address src_klass_addr(src, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 Address dst_klass_addr(dst, oopDesc::klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 const Register rcx_src_klass = rcx; // array klass
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1762 __ movptr(rcx_src_klass, Address(src, oopDesc::klass_offset_in_bytes()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // assert(src->klass() != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 BLOCK_COMMENT("assert klasses not null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 { Label L1, L2;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1768 __ testptr(rcx_src_klass, rcx_src_klass);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 __ jccb(Assembler::notZero, L2); // it is broken if klass is NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 __ bind(L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 __ stop("broken null klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 __ bind(L2);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1773 __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 __ jccb(Assembler::equal, L1); // this would be broken also
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 BLOCK_COMMENT("assert done");
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // Load layout helper (32-bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 // |array_tag| | header_size | element_type | |log2_element_size|
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 // 32 30 24 16 8 2 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 int lh_offset = klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 Klass::layout_helper_offset_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 Address src_klass_lh_addr(rcx_src_klass, lh_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1790
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // Handle objArrays completely differently...
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 __ cmpl(src_klass_lh_addr, objArray_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 __ jcc(Assembler::equal, L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // if (src->klass() != dst->klass()) return -1;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1797 __ cmpptr(rcx_src_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 __ jccb(Assembler::notEqual, L_failed_0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1799
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 const Register rcx_lh = rcx; // layout helper
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 assert(rcx_lh == rcx_src_klass, "known alias");
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 __ movl(rcx_lh, src_klass_lh_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 // if (!src->is_Array()) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 __ cmpl(rcx_lh, Klass::_lh_neutral_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 __ jcc(Assembler::greaterEqual, L_failed_0); // signed cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1807
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 // At this point, it is known to be a typeArray (array_tag 0x3).
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 __ cmpl(rcx_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 __ jcc(Assembler::greaterEqual, L); // signed cmp
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 __ stop("must be a primitive array");
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1817
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 assert_different_registers(src, src_pos, dst, dst_pos, rcx_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 // typeArrayKlass
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 const Register rsi_offset = rsi; // array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 const Register src_array = src; // src array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 const Register dst_array = dst; // dst array offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 const Register rdi_elsize = rdi; // log2 element size
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1831 __ mov(rsi_offset, rcx_lh);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1832 __ shrptr(rsi_offset, Klass::_lh_header_size_shift);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1833 __ andptr(rsi_offset, Klass::_lh_header_size_mask); // array_offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1834 __ addptr(src_array, rsi_offset); // src array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1835 __ addptr(dst_array, rsi_offset); // dst array offset
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1836 __ andptr(rcx_lh, Klass::_lh_log2_element_size_mask); // log2 elsize
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1837
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // next registers should be set before the jump to corresponding stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 const Register from = src; // source array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 const Register to = dst; // destination array address
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 const Register count = rcx; // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // some of them should be duplicated on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 #define FROM Address(rsp, 12+ 4)
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 #define TO Address(rsp, 12+ 8) // Not used now
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 #define COUNT Address(rsp, 12+12) // Only for oop arraycopy
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 BLOCK_COMMENT("scale indexes to element size");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1848 __ movl2ptr(rsi, SRC_POS); // src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1849 __ shlptr(rsi); // src_pos << rcx (log2 elsize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 assert(src_array == from, "");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1851 __ addptr(from, rsi); // from = src_array + SRC_POS << log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1852 __ movl2ptr(rdi, DST_POS); // dst_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1853 __ shlptr(rdi); // dst_pos << rcx (log2 elsize)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 assert(dst_array == to, "");
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1855 __ addptr(to, rdi); // to = dst_array + DST_POS << log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1856 __ movptr(FROM, from); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1857 __ mov(rdi_elsize, rcx_lh); // log2 elsize
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1858 __ movl2ptr(count, LENGTH); // elements count
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1859
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 BLOCK_COMMENT("choose copy loop based on element size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 __ cmpl(rdi_elsize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1862
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jbyte_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 __ cmpl(rdi_elsize, LogBytesPerShort);
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jshort_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 __ cmpl(rdi_elsize, LogBytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 __ jump_cc(Assembler::equal, RuntimeAddress(entry_jint_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 __ cmpl(rdi_elsize, LogBytesPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 __ jccb(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 #endif
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1872 __ pop(rdi); // Do pops here since jlong_arraycopy stub does not do it.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1873 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 __ jump(RuntimeAddress(entry_jlong_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1875
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 __ BIND(L_failed);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1877 __ xorptr(rax, rax);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1878 __ notptr(rax); // return -1
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1879 __ pop(rdi);
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1880 __ pop(rsi);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 __ ret(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1883
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // objArrayKlass
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 __ BIND(L_objArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // live at this point: rcx_src_klass, src[_pos], dst[_pos]
a61af66fc99e Initial load
duke
parents:
diff changeset
1887
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 Label L_plain_copy, L_checkcast_copy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // test array classes for subtyping
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1890 __ cmpptr(rcx_src_klass, dst_klass_addr); // usual case is exact equality
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 __ jccb(Assembler::notEqual, L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // Identically typed arrays can be copied without element-wise checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 assert_different_registers(src, src_pos, dst, dst_pos, rcx_src_klass);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 __ BIND(L_plain_copy);
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1898 __ movl2ptr(count, LENGTH); // elements count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1899 __ movl2ptr(src_pos, SRC_POS); // reload src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1900 __ lea(from, Address(src, src_pos, Address::times_ptr,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1901 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1902 __ movl2ptr(dst_pos, DST_POS); // reload dst_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1903 __ lea(to, Address(dst, dst_pos, Address::times_ptr,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1904 arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1905 __ movptr(FROM, from); // src_addr
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1906 __ movptr(TO, to); // dst_addr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 __ movl(COUNT, count); // count
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 __ jump(RuntimeAddress(entry_oop_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1909
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 __ BIND(L_checkcast_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 // live at this point: rcx_src_klass, dst[_pos], src[_pos]
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 // Handy offsets:
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 objArrayKlass::element_klass_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 Klass::super_check_offset_offset_in_bytes());
a61af66fc99e Initial load
duke
parents:
diff changeset
1918
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 Register rsi_dst_klass = rsi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 Register rdi_temp = rdi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 assert(rsi_dst_klass == src_pos, "expected alias w/ src_pos");
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 assert(rdi_temp == dst_pos, "expected alias w/ dst_pos");
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 Address dst_klass_lh_addr(rsi_dst_klass, lh_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1924
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 // Before looking at dst.length, make sure dst is also an objArray.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1926 __ movptr(rsi_dst_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 __ cmpl(dst_klass_lh_addr, objArray_lh);
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 __ jccb(Assembler::notEqual, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1929
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 // It is safe to examine both src.length and dst.length.
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1931 __ movl2ptr(src_pos, SRC_POS); // reload rsi
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // (Now src_pos and dst_pos are killed, but not src and dst.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1934
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 // We'll need this temp (don't forget to pop it after the type check).
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1936 __ push(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 Register rbx_src_klass = rbx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1939 __ mov(rbx_src_klass, rcx_src_klass); // spill away from rcx
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1940 __ movptr(rsi_dst_klass, dst_klass_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 Address super_check_offset_addr(rsi_dst_klass, sco_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 Label L_fail_array_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 generate_type_check(rbx_src_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 super_check_offset_addr, dst_klass_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 rdi_temp, NULL, &L_fail_array_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // (On fall-through, we have passed the array type check.)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1947 __ pop(rbx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 __ jmp(L_plain_copy);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 __ BIND(L_fail_array_check);
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 // Reshuffle arguments so we can call checkcast_arraycopy:
a61af66fc99e Initial load
duke
parents:
diff changeset
1952
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // match initial saves for checkcast_arraycopy
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1954 // push(rsi); // already done; see above
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1955 // push(rdi); // already done; see above
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1956 // push(rbx); // already done; see above
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // Marshal outgoing arguments now, freeing registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 Address from_arg(rsp, 16+ 4); // from
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 Address to_arg(rsp, 16+ 8); // to
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 Address length_arg(rsp, 16+12); // elements count
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 Address ckoff_arg(rsp, 16+16); // super_check_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 Address ckval_arg(rsp, 16+20); // super_klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 Address SRC_POS_arg(rsp, 16+ 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 Address DST_POS_arg(rsp, 16+16);
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 Address LENGTH_arg(rsp, 16+20);
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // push rbx, changed the incoming offsets (why not just use rbp,??)
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // assert(SRC_POS_arg.disp() == SRC_POS.disp() + 4, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1970
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1971 __ movptr(rbx, Address(rsi_dst_klass, ek_offset));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1972 __ movl2ptr(length, LENGTH_arg); // reload elements count
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1973 __ movl2ptr(src_pos, SRC_POS_arg); // reload src_pos
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1974 __ movl2ptr(dst_pos, DST_POS_arg); // reload dst_pos
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1975
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1976 __ movptr(ckval_arg, rbx); // destination element type
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 __ movl(rbx, Address(rbx, sco_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 __ movl(ckoff_arg, rbx); // corresponding class check offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 __ movl(length_arg, length); // outgoing length argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1982 __ lea(from, Address(src, src_pos, Address::times_ptr,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1984 __ movptr(from_arg, from);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1985
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1986 __ lea(to, Address(dst, dst_pos, Address::times_ptr,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
1988 __ movptr(to_arg, to);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 __ jump(RuntimeAddress(entry_checkcast_arraycopy));
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 return start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1994
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 void generate_arraycopy_stubs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 address entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 address entry_jbyte_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 address entry_jshort_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 address entry_jint_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 address entry_oop_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 address entry_jlong_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 address entry_checkcast_arraycopy;
a61af66fc99e Initial load
duke
parents:
diff changeset
2003
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 generate_disjoint_copy(T_BYTE, true, Address::times_1, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 "arrayof_jbyte_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 StubRoutines::_arrayof_jbyte_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 generate_conjoint_copy(T_BYTE, true, Address::times_1, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 NULL, "arrayof_jbyte_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 StubRoutines::_jbyte_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 generate_disjoint_copy(T_BYTE, false, Address::times_1, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 "jbyte_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 StubRoutines::_jbyte_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 generate_conjoint_copy(T_BYTE, false, Address::times_1, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 &entry_jbyte_arraycopy, "jbyte_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2016
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 StubRoutines::_arrayof_jshort_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 generate_disjoint_copy(T_SHORT, true, Address::times_2, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 "arrayof_jshort_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 StubRoutines::_arrayof_jshort_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 generate_conjoint_copy(T_SHORT, true, Address::times_2, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 NULL, "arrayof_jshort_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 StubRoutines::_jshort_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 generate_disjoint_copy(T_SHORT, false, Address::times_2, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 "jshort_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 StubRoutines::_jshort_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 generate_conjoint_copy(T_SHORT, false, Address::times_2, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 &entry_jshort_arraycopy, "jshort_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // Next arrays are always aligned on 4 bytes at least.
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 StubRoutines::_jint_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 generate_disjoint_copy(T_INT, true, Address::times_4, &entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 "jint_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 StubRoutines::_jint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 generate_conjoint_copy(T_INT, true, Address::times_4, entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 &entry_jint_arraycopy, "jint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 StubRoutines::_oop_disjoint_arraycopy =
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2039 generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 "oop_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 StubRoutines::_oop_arraycopy =
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2042 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 &entry_oop_arraycopy, "oop_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2045 StubRoutines::_oop_disjoint_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2046 generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2047 "oop_disjoint_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2048 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2049 StubRoutines::_oop_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2050 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2051 NULL, "oop_arraycopy_uninit",
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2052 /*dest_uninitialized*/true);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2053
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 StubRoutines::_jlong_disjoint_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 StubRoutines::_jlong_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 "jlong_arraycopy");
a61af66fc99e Initial load
duke
parents:
diff changeset
2059
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2060 StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2061 StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2062 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2063 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2064 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2065 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1552
diff changeset
2066
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2067 StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2068 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2069 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2070 StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2072 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2073 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2074 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2075 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 StubRoutines::_checkcast_arraycopy =
2324
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2078 generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2079 StubRoutines::_checkcast_arraycopy_uninit =
0ac769a57c64 6627983: G1: Bad oop deference during marking
iveresov
parents: 2321
diff changeset
2080 generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, /*dest_uninitialized*/true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2081
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 StubRoutines::_unsafe_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 generate_unsafe_copy("unsafe_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 entry_jlong_arraycopy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2088
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 StubRoutines::_generic_arraycopy =
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 generate_generic_copy("generic_arraycopy",
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 entry_jbyte_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 entry_jshort_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 entry_jint_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 entry_oop_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 entry_jlong_arraycopy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 entry_checkcast_arraycopy);
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2098
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2099 void generate_math_stubs() {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2100 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2101 StubCodeMark mark(this, "StubRoutines", "log");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2102 StubRoutines::_intrinsic_log = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2103
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2104 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2105 __ flog();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2106 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2107 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2108 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2109 StubCodeMark mark(this, "StubRoutines", "log10");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2110 StubRoutines::_intrinsic_log10 = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2111
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2112 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2113 __ flog10();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2114 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2115 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2116 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2117 StubCodeMark mark(this, "StubRoutines", "sin");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2118 StubRoutines::_intrinsic_sin = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2119
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2120 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2121 __ trigfunc('s');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2122 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2123 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2124 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2125 StubCodeMark mark(this, "StubRoutines", "cos");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2126 StubRoutines::_intrinsic_cos = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2127
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2128 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2129 __ trigfunc('c');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2130 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2131 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2132 {
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2133 StubCodeMark mark(this, "StubRoutines", "tan");
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2134 StubRoutines::_intrinsic_tan = (double (*)(double)) __ pc();
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2135
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2136 __ fld_d(Address(rsp, 4));
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2137 __ trigfunc('t');
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2138 __ ret(0);
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2139 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2140
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2141 // 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: 845
diff changeset
2142 // the strict version.
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2143 StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2144 StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2145 }
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2146
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // Information about frame layout at time of blocking runtime call.
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 // Note that we only have to preserve callee-saved registers since
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 // the compilers are responsible for supplying a continuation point
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // if they expect all registers to be preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 enum layout {
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 thread_off, // last_java_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 rbp_off, // callee saved register
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 ret_pc,
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2158
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2160
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 #undef __
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 #define __ masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
2163
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // Continuation point for throwing of implicit exceptions that are not handled in
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // the current activation. Fabricates an exception oop and initiates normal
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // exception dispatching in this frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // Previously the compiler (c2) allowed for callee save registers on Java calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // This is no longer true after adapter frames were removed but could possibly
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // be brought back in the future if the interpreter code was reworked and it
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // was deemed worthwhile. The comment below was left to describe what must
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // happen here if callee saves were resurrected. As it stands now this stub
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // could actually be a vanilla BufferBlob and have now oopMap at all.
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 // Since it doesn't make much difference we've chosen to leave it the
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 // way it was in the callee save days and keep the comment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2177
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 // If we need to preserve callee-saved values we need a callee-saved oop map and
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 // therefore have to make these stubs into RuntimeStubs rather than BufferBlobs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // If the compiler needs all registers to be preserved between the fault
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // point and the exception handler then it must assume responsibility for that in
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // AbstractCompiler::continuation_for_implicit_null_exception or
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // continuation_for_implicit_division_by_zero_exception. All other implicit
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // exceptions (e.g., NullPointerException or AbstractMethodError on entry) are
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // either at call sites or otherwise assume that stack unwinding will be initiated,
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // so caller saved registers were assumed volatile in the compiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 address generate_throw_exception(const char* name, address runtime_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 bool restore_saved_exception_pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 int insts_size = 256;
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 int locs_size = 32;
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 CodeBuffer code(name, insts_size, locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 OopMapSet* oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 MacroAssembler* masm = new MacroAssembler(&code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2196
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 address start = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2198
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // This is an inlined and slightly modified version of call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // which has the ability to fetch the return PC out of
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // thread-local storage and also sets up last_Java_sp slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 // differently than the real call_VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 Register java_thread = rbx;
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 __ get_thread(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 if (restore_saved_exception_pc) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2206 __ movptr(rax, Address(java_thread, in_bytes(JavaThread::saved_exception_pc_offset())));
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2207 __ push(rax);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2209
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 __ enter(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2211
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 // pc and rbp, already pushed
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2213 __ subptr(rsp, (framesize-2) * wordSize); // prolog
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 // Frame is now completed as far as size and linkage.
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 int frame_complete = __ pc() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2218
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // push java thread (becomes first argument of C function)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2220 __ movptr(Address(rsp, thread_off * wordSize), java_thread);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2221
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // Set up last_Java_sp and last_Java_fp
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 __ set_last_Java_frame(java_thread, rsp, rbp, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2224
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 // Call runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 BLOCK_COMMENT("call runtime_entry");
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 __ call(RuntimeAddress(runtime_entry));
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 // Generate oop map
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 OopMap* map = new OopMap(framesize, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 oop_maps->add_gc_map(__ pc() - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2231
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // restore the thread (cannot use the pushed argument since arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // may be overwritten by C code generated by an optimizing compiler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // however can use the register value directly if it is callee saved.
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 __ get_thread(java_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2236
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 __ reset_last_Java_frame(java_thread, true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2238
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 __ leave(); // required for proper stackwalking of RuntimeStub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 // check for pending exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 Label L;
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2244 __ cmpptr(Address(java_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 __ jcc(Assembler::notEqual, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 __ should_not_reach_here();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2250
a61af66fc99e Initial load
duke
parents:
diff changeset
2251
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 RuntimeStub* stub = RuntimeStub::new_runtime_stub(name, &code, frame_complete, framesize, oop_maps, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 return stub->entry_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2255
a61af66fc99e Initial load
duke
parents:
diff changeset
2256
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 void create_control_words() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 // Round to nearest, 53-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 StubRoutines::_fpu_cntrl_wrd_std = 0x027F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // Round to zero, 53-bit mode, exception mased
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 StubRoutines::_fpu_cntrl_wrd_trunc = 0x0D7F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 // Round to nearest, 24-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 StubRoutines::_fpu_cntrl_wrd_24 = 0x007F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // Round to nearest, 64-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 StubRoutines::_fpu_cntrl_wrd_64 = 0x037F;
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // Round to nearest, 64-bit mode, exceptions masked
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 StubRoutines::_mxcsr_std = 0x1F80;
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 // Note: the following two constants are 80-bit values
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 // layout is critical for correct loading by FPU.
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // Bias for strict fp multiply/divide
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 StubRoutines::_fpu_subnormal_bias1[0]= 0x00000000; // 2^(-15360) == 0x03ff 8000 0000 0000 0000
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 StubRoutines::_fpu_subnormal_bias1[1]= 0x80000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 StubRoutines::_fpu_subnormal_bias1[2]= 0x03ff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 // Un-Bias for strict fp multiply/divide
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 StubRoutines::_fpu_subnormal_bias2[0]= 0x00000000; // 2^(+15360) == 0x7bff 8000 0000 0000 0000
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 StubRoutines::_fpu_subnormal_bias2[1]= 0x80000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 StubRoutines::_fpu_subnormal_bias2[2]= 0x7bff;
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2279
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 //---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 // Initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 void generate_initial() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // entry points that exist in all platforms
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // Note: This is code that could be shared among different platforms - however the benefit seems to be smaller than
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // the disadvantage of having a much more complicated generator structure. See also comment in stubRoutines.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 StubRoutines::_forward_exception_entry = generate_forward_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
2291
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 StubRoutines::_call_stub_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 generate_call_stub(StubRoutines::_call_stub_return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 // is referenced by megamorphic call
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 StubRoutines::_catch_exception_entry = generate_catch_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
2296
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 // These are currently used by Solaris/Intel
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 StubRoutines::_atomic_xchg_entry = generate_atomic_xchg();
a61af66fc99e Initial load
duke
parents:
diff changeset
2299
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 StubRoutines::_handler_for_unsafe_access_entry =
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 generate_handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
2302
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 // platform dependent
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 create_control_words();
a61af66fc99e Initial load
duke
parents:
diff changeset
2305
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2306 StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr();
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 249
diff changeset
2307 StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = generate_verify_fpu_cntrl_wrd();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 StubRoutines::_d2i_wrapper = generate_d2i_wrapper(T_INT,
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 CAST_FROM_FN_PTR(address, SharedRuntime::d2i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 StubRoutines::_d2l_wrapper = generate_d2i_wrapper(T_LONG,
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 CAST_FROM_FN_PTR(address, SharedRuntime::d2l));
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2313
a61af66fc99e Initial load
duke
parents:
diff changeset
2314
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 void generate_all() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 // Generates all stubs and initializes the entry points
a61af66fc99e Initial load
duke
parents:
diff changeset
2317
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 // These entry points require SharedInfo::stack0 to be set up in non-core builds
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 // and need to be relocatable, so they each fabricate a RuntimeStub internally.
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 StubRoutines::_throw_AbstractMethodError_entry = generate_throw_exception("AbstractMethodError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError), false);
16
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
2321 StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError), false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 StubRoutines::_throw_ArithmeticException_entry = generate_throw_exception("ArithmeticException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_ArithmeticException), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 StubRoutines::_throw_NullPointerException_entry = generate_throw_exception("NullPointerException throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 StubRoutines::_throw_StackOverflowError_entry = generate_throw_exception("StackOverflowError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // entry points that are platform specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2329
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 // support for verify_oop (must happen after universe_init)
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2332
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // arraycopy stubs used by compilers
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 generate_arraycopy_stubs();
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 647
diff changeset
2335
1174
ddb7834449d0 6849984: Value methods for platform dependent math functions constant fold incorrectly
never
parents: 845
diff changeset
2336 generate_math_stubs();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2338
a61af66fc99e Initial load
duke
parents:
diff changeset
2339
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 if (all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 generate_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 generate_initial();
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 }; // end class declaration
a61af66fc99e Initial load
duke
parents:
diff changeset
2349
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 void StubGenerator_generate(CodeBuffer* code, bool all) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 StubGenerator g(code, all);
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 }