annotate src/cpu/sparc/vm/sharedRuntime_sparc.cpp @ 6812:988bf00cc564

7200261: G1: Liveness counting inconsistencies during marking verification Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures. Reviewed-by: brutisso, jwilhelm, jmasa
author johnc
date Thu, 27 Sep 2012 15:44:01 -0700
parents 8a02ca5e5576
children 2cb2f30450c7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1506
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1506
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1506
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
26 #include "asm/assembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
27 #include "assembler_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
28 #include "code/debugInfoRec.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
29 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
30 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
31 #include "interpreter/interpreter.hpp"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
32 #include "oops/compiledICHolder.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
33 #include "prims/jvmtiRedefineClassesTrace.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
34 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
35 #include "runtime/vframeArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
36 #include "vmreg_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
37 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
38 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
39 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
40 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
41 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
42 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
43 #ifdef SHARK
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
44 #include "compiler/compileBroker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
45 #include "shark/sharkCompiler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
46 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 #define __ masm->
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51 class RegisterSaver {
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Used for saving volatile registers. This is Gregs, Fregs, I/L/O.
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // The Oregs are problematic. In the 32bit build the compiler can
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // have O registers live with 64 bit quantities. A window save will
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // cut the heads off of the registers. We have to do a very extensive
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // stack dance to save and restore these properly.
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // Note that the Oregs problem only exists if we block at either a polling
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // page exception a compiled code safepoint that was not originally a call
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // or deoptimize following one of these kinds of safepoints.
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Lots of registers to save. For all builds, a window save will preserve
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // the %i and %l registers. For the 32-bit longs-in-two entries and 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // builds a window-save will preserve the %o registers. In the LION build
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // we need to save the 64-bit %o registers which requires we save them
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // before the window-save (as then they become %i registers and get their
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // heads chopped off on interrupt). We have to save some %g registers here
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // as well.
a61af66fc99e Initial load
duke
parents:
diff changeset
70 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // This frame's save area. Includes extra space for the native call:
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // vararg's layout space and the like. Briefly holds the caller's
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // register save area.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 call_args_area = frame::register_save_words_sp_offset +
a61af66fc99e Initial load
duke
parents:
diff changeset
75 frame::memory_parameter_word_sp_offset*wordSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Make sure save locations are always 8 byte aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // can't use round_to because it doesn't produce compile time constant
a61af66fc99e Initial load
duke
parents:
diff changeset
78 start_of_extra_save_area = ((call_args_area + 7) & ~7),
a61af66fc99e Initial load
duke
parents:
diff changeset
79 g1_offset = start_of_extra_save_area, // g-regs needing saving
a61af66fc99e Initial load
duke
parents:
diff changeset
80 g3_offset = g1_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
81 g4_offset = g3_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
82 g5_offset = g4_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
83 o0_offset = g5_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
84 o1_offset = o0_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
85 o2_offset = o1_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 o3_offset = o2_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 o4_offset = o3_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
88 o5_offset = o4_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
89 start_of_flags_save_area = o5_offset+8,
a61af66fc99e Initial load
duke
parents:
diff changeset
90 ccr_offset = start_of_flags_save_area,
a61af66fc99e Initial load
duke
parents:
diff changeset
91 fsr_offset = ccr_offset + 8,
a61af66fc99e Initial load
duke
parents:
diff changeset
92 d00_offset = fsr_offset+8, // Start of float save area
a61af66fc99e Initial load
duke
parents:
diff changeset
93 register_save_size = d00_offset+8*32
a61af66fc99e Initial load
duke
parents:
diff changeset
94 };
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static int Oexception_offset() { return o0_offset; };
a61af66fc99e Initial load
duke
parents:
diff changeset
100 static int G3_offset() { return g3_offset; };
a61af66fc99e Initial load
duke
parents:
diff changeset
101 static int G5_offset() { return g5_offset; };
a61af66fc99e Initial load
duke
parents:
diff changeset
102 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static void restore_live_registers(MacroAssembler* masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // During deoptimization only the result register need to be restored
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // all the other values have already been extracted.
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 static void restore_result_registers(MacroAssembler* masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 };
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Record volatile registers as callee-save values in an OopMap so their save locations will be
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // deoptimization; see compiledVFrame::create_stack_value). The caller's I, L and O registers
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // (as the stub's I's) when the runtime routine called by the stub creates its frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
117 int i;
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
118 // Always make the frame size 16 byte aligned.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
119 int frame_size = round_to(additional_frame_words + register_save_size, 16);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words
a61af66fc99e Initial load
duke
parents:
diff changeset
121 int frame_size_in_slots = frame_size / sizeof(jint);
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // CodeBlob frame size is in words.
a61af66fc99e Initial load
duke
parents:
diff changeset
123 *total_frame_words = frame_size / wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // OopMap* map = new OopMap(*total_frame_words, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 OopMap* map = new OopMap(frame_size_in_slots, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Save 64-bit O registers; they will get their heads chopped off on a 'save'.
a61af66fc99e Initial load
duke
parents:
diff changeset
130 __ stx(O0, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 __ stx(O1, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
132 __ stx(O2, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+2*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 __ stx(O3, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+3*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 __ stx(O4, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+4*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 __ stx(O5, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+5*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
136 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 __ save(SP, -frame_size, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Reload the 64 bit Oregs. Although they are now Iregs we load them
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // to Oregs here to avoid interrupts cutting off their heads
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+2*8, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+3*8, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+4*8, O4);
a61af66fc99e Initial load
duke
parents:
diff changeset
149 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+5*8, O5);
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 __ stx(O0, SP, o0_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 map->set_callee_saved(VMRegImpl::stack2reg((o0_offset + 4)>>2), O0->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 __ stx(O1, SP, o1_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 map->set_callee_saved(VMRegImpl::stack2reg((o1_offset + 4)>>2), O1->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 __ stx(O2, SP, o2_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 map->set_callee_saved(VMRegImpl::stack2reg((o2_offset + 4)>>2), O2->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 __ stx(O3, SP, o3_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 map->set_callee_saved(VMRegImpl::stack2reg((o3_offset + 4)>>2), O3->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 __ stx(O4, SP, o4_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 map->set_callee_saved(VMRegImpl::stack2reg((o4_offset + 4)>>2), O4->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 __ stx(O5, SP, o5_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 map->set_callee_saved(VMRegImpl::stack2reg((o5_offset + 4)>>2), O5->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
169 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
170
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
171
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
172 #ifdef _LP64
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
173 int debug_offset = 0;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
174 #else
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
175 int debug_offset = 4;
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
176 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Save the G's
a61af66fc99e Initial load
duke
parents:
diff changeset
178 __ stx(G1, SP, g1_offset+STACK_BIAS);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
179 map->set_callee_saved(VMRegImpl::stack2reg((g1_offset + debug_offset)>>2), G1->as_VMReg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 __ stx(G3, SP, g3_offset+STACK_BIAS);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
182 map->set_callee_saved(VMRegImpl::stack2reg((g3_offset + debug_offset)>>2), G3->as_VMReg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 __ stx(G4, SP, g4_offset+STACK_BIAS);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
185 map->set_callee_saved(VMRegImpl::stack2reg((g4_offset + debug_offset)>>2), G4->as_VMReg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 __ stx(G5, SP, g5_offset+STACK_BIAS);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
188 map->set_callee_saved(VMRegImpl::stack2reg((g5_offset + debug_offset)>>2), G5->as_VMReg());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // This is really a waste but we'll keep things as they were for now
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
192 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
193 map->set_callee_saved(VMRegImpl::stack2reg((o0_offset)>>2), O0->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
194 map->set_callee_saved(VMRegImpl::stack2reg((o1_offset)>>2), O1->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
195 map->set_callee_saved(VMRegImpl::stack2reg((o2_offset)>>2), O2->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
196 map->set_callee_saved(VMRegImpl::stack2reg((o3_offset)>>2), O3->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
197 map->set_callee_saved(VMRegImpl::stack2reg((o4_offset)>>2), O4->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
198 map->set_callee_saved(VMRegImpl::stack2reg((o5_offset)>>2), O5->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
199 map->set_callee_saved(VMRegImpl::stack2reg((g1_offset)>>2), G1->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 map->set_callee_saved(VMRegImpl::stack2reg((g3_offset)>>2), G3->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
201 map->set_callee_saved(VMRegImpl::stack2reg((g4_offset)>>2), G4->as_VMReg()->next());
a61af66fc99e Initial load
duke
parents:
diff changeset
202 map->set_callee_saved(VMRegImpl::stack2reg((g5_offset)>>2), G5->as_VMReg()->next());
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
203 #endif /* _LP64 */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Save the flags
a61af66fc99e Initial load
duke
parents:
diff changeset
208 __ rdccr( G5 );
a61af66fc99e Initial load
duke
parents:
diff changeset
209 __ stx(G5, SP, ccr_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 __ stxfsr(SP, fsr_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
211
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
212 // Save all the FP registers: 32 doubles (32 floats correspond to the 2 halves of the first 16 doubles)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213 int offset = d00_offset;
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
214 for( int i=0; i<FloatRegisterImpl::number_of_registers; i+=2 ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
215 FloatRegister f = as_FloatRegister(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 __ stf(FloatRegisterImpl::D, f, SP, offset+STACK_BIAS);
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
217 // Record as callee saved both halves of double registers (2 float registers).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
218 map->set_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg());
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
219 map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 offset += sizeof(double);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // And we're done.
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return map;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Pop the current frame and restore all the registers that we
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // saved.
a61af66fc99e Initial load
duke
parents:
diff changeset
231 void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Restore all the FP registers
1007
1ce3281a8e93 6880034: SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
kvn
parents: 1006
diff changeset
234 for( int i=0; i<FloatRegisterImpl::number_of_registers; i+=2 ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 __ ldf(FloatRegisterImpl::D, SP, d00_offset+i*sizeof(float)+STACK_BIAS, as_FloatRegister(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 __ ldx(SP, ccr_offset+STACK_BIAS, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 __ wrccr (G1) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Restore the G's
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // Note that G2 (AKA GThread) must be saved and restored separately.
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // TODO-FIXME: save and restore some of the other ASRs, viz., %asi and %gsr.
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 __ ldx(SP, g1_offset+STACK_BIAS, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 __ ldx(SP, g3_offset+STACK_BIAS, G3);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 __ ldx(SP, g4_offset+STACK_BIAS, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
248 __ ldx(SP, g5_offset+STACK_BIAS, G5);
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Restore the 64-bit O's.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 __ ldx(SP, o0_offset+STACK_BIAS, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 __ ldx(SP, o1_offset+STACK_BIAS, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 __ ldx(SP, o2_offset+STACK_BIAS, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 __ ldx(SP, o3_offset+STACK_BIAS, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
257 __ ldx(SP, o4_offset+STACK_BIAS, O4);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 __ ldx(SP, o5_offset+STACK_BIAS, O5);
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // And temporarily place them in TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 __ stx(O0, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 __ stx(O1, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
264 __ stx(O2, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+2*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 __ stx(O3, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+3*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
266 __ stx(O4, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+4*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 __ stx(O5, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+5*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
268 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Restore flags
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 __ ldxfsr(SP, fsr_offset+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // Now reload the 64bit Oregs after we've restore the window.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+2*8, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+3*8, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+4*8, O4);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+5*8, O5);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Pop the current frame and restore the registers that might be holding
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // a result.
a61af66fc99e Initial load
duke
parents:
diff changeset
290 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // 32bit build returns longs in G1
a61af66fc99e Initial load
duke
parents:
diff changeset
294 __ ldx(SP, g1_offset+STACK_BIAS, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // Retrieve the 64-bit O's.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 __ ldx(SP, o0_offset+STACK_BIAS, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 __ ldx(SP, o1_offset+STACK_BIAS, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // and save to TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
300 __ stx(O0, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
301 __ stx(O1, G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 __ ldf(FloatRegisterImpl::D, SP, d00_offset+STACK_BIAS, as_FloatRegister(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Now reload the 64bit Oregs after we've restore the window.
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+0*8, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 __ ldx(G2_thread, JavaThread::o_reg_temps_offset_in_bytes()+1*8, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // The java_calling_convention describes stack locations as ideal slots on
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // a frame with no abi restrictions. Since we must observe abi restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // (like the placement of the register window) the slots must be biased by
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // the following value.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 static int reg2offset(VMReg r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
324 static VMRegPair reg64_to_VMRegPair(Register r) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
325 VMRegPair ret;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
326 if (wordSize == 8) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
327 ret.set2(r->as_VMReg());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
328 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
329 ret.set_pair(r->successor()->as_VMReg(), r->as_VMReg());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
330 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
331 return ret;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
332 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
333
0
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Read the array of BasicTypes from a signature, and compute where the
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // arguments should go. Values in the VMRegPair regs array refer to 4-byte (VMRegImpl::stack_slot_size)
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // quantities. Values less than VMRegImpl::stack0 are registers, those above
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // refer to 4-byte stack slots. All stack slots are based off of the window
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // top. VMRegImpl::stack0 refers to the first slot past the 16-word window,
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // and VMRegImpl::stack0+1 refers to the memory word 4-byes higher. Register
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // values 0-63 (up to RegisterImpl::number_of_registers) are the 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // integer registers. Values 64-95 are the (32-bit only) float registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // Each 32-bit quantity is given its own number, so the integer registers
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // (in either 32- or 64-bit builds) use 2 numbers. For example, there is
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // an O0-low and an O0-high. Essentially, all int register numbers are doubled.
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Register results are passed in O0-O5, for outgoing call arguments. To
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // convert to incoming arguments, convert all O's to I's. The regs array
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // refer to the low and hi 32-bit words of 64-bit registers or stack slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // If the regs[].second() field is set to VMRegImpl::Bad(), it means it's unused (a
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // 32-bit value was passed). If both are VMRegImpl::Bad(), it means no value was
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // passed (used as a placeholder for the other half of longs and doubles in
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // the 64-bit build). regs[].second() is either VMRegImpl::Bad() or regs[].second() is
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // regs[].first()+1 (regs[].first() may be misaligned in the C calling convention).
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Sparc never passes a value in regs[].second() but not regs[].first() (regs[].first()
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // == VMRegImpl::Bad() && regs[].second() != VMRegImpl::Bad()) nor unrelated values in the
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // same VMRegPair.
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // Note: the INPUTS in sig_bt are in units of Java argument words, which are
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // either 32-bit or 64-bit depending on the build. The OUTPUTS are in 32-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // units regardless of build.
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // The compiled Java calling convention. The Java convention always passes
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // 64-bit values in adjacent aligned locations (either registers or stack),
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // floats in float registers and doubles in aligned float pairs. Values are
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // packed in the registers. There is no backing varargs store for values in
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // registers. In the 32-bit build, longs are passed in G1 and G4 (cannot be
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // passed in I's, because longs in I's get their heads chopped off at
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // interrupt).
a61af66fc99e Initial load
duke
parents:
diff changeset
372 int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
373 VMRegPair *regs,
a61af66fc99e Initial load
duke
parents:
diff changeset
374 int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
375 int is_outgoing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 assert(F31->as_VMReg()->is_reg(), "overlapping stack/register numbers");
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Convention is to pack the first 6 int/oop args into the first 6 registers
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // (I0-I5), extras spill to the stack. Then pack the first 8 float args
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // into F0-F7, extras spill to the stack. Then pad all register sets to
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // align. Then put longs and doubles into the same registers as they fit,
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // else spill to the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
383 const int int_reg_max = SPARC_ARGS_IN_REGS_NUM;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 const int flt_reg_max = 8;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 //
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Where 32-bit 1-reg longs start being passed
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // In tiered we must pass on stack because c1 can't use a "pair" in a single reg.
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // So make it look like we've filled all the G regs that c2 wants to use.
a61af66fc99e Initial load
duke
parents:
diff changeset
389 Register g_reg = TieredCompilation ? noreg : G1;
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Count int/oop and float args. See how many stack slots we'll need and
a61af66fc99e Initial load
duke
parents:
diff changeset
392 // where the longs & doubles will go.
a61af66fc99e Initial load
duke
parents:
diff changeset
393 int int_reg_cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 int flt_reg_cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // int stk_reg_pairs = frame::register_save_words*(wordSize>>2);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // int stk_reg_pairs = SharedRuntime::out_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
397 int stk_reg_pairs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 for (int i = 0; i < total_args_passed; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 switch (sig_bt[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 case T_LONG: // LP64, longs compete with int args
a61af66fc99e Initial load
duke
parents:
diff changeset
401 assert(sig_bt[i+1] == T_VOID, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
402 #ifdef _LP64
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
403 if (int_reg_cnt < int_reg_max) int_reg_cnt++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
404 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
405 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
406 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
407 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
408 case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
409 if (int_reg_cnt < int_reg_max) int_reg_cnt++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
410 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
411 else stk_reg_pairs++;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
413 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
415 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
416 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
417 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
418 case T_BOOLEAN:
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
419 if (int_reg_cnt < int_reg_max) int_reg_cnt++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
420 else stk_reg_pairs++;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 case T_FLOAT:
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
423 if (flt_reg_cnt < flt_reg_max) flt_reg_cnt++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
424 else stk_reg_pairs++;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
426 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
427 assert(sig_bt[i+1] == T_VOID, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
428 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
429 case T_VOID:
a61af66fc99e Initial load
duke
parents:
diff changeset
430 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
432 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // This is where the longs/doubles start on the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
437 stk_reg_pairs = (stk_reg_pairs+1) & ~1; // Round
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 int flt_reg_pairs = (flt_reg_cnt+1) & ~1;
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // int stk_reg = frame::register_save_words*(wordSize>>2);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // int stk_reg = SharedRuntime::out_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
443 int stk_reg = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 int int_reg = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 int flt_reg = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // Now do the signature layout
a61af66fc99e Initial load
duke
parents:
diff changeset
448 for (int i = 0; i < total_args_passed; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 switch (sig_bt[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
451 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
452 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
453 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
454 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
455 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
456 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
457 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
458 case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address
a61af66fc99e Initial load
duke
parents:
diff changeset
459 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
460 if (int_reg < int_reg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 regs[i].set1(r->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
463 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 regs[i].set1(VMRegImpl::stack2reg(stk_reg++));
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
469 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
470 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
471 case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (int_reg < int_reg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 regs[i].set2(r->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
475 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
476 regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
a61af66fc99e Initial load
duke
parents:
diff changeset
477 stk_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
483 assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half");
a61af66fc99e Initial load
duke
parents:
diff changeset
484 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
485 if (int_reg < int_reg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 regs[i].set2(r->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
488 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
a61af66fc99e Initial load
duke
parents:
diff changeset
490 stk_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 #else
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
493 #ifdef COMPILER2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // For 32-bit build, can't pass longs in O-regs because they become
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // I-regs and get trashed. Use G-regs instead. G1 and G4 are almost
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // spare and available. This convention isn't used by the Sparc ABI or
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // anywhere else. If we're tiered then we don't use G-regs because c1
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
498 // can't deal with them as a "pair". (Tiered makes this code think g's are filled)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // G0: zero
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // G1: 1st Long arg
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // G2: global allocated to TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // G3: used in inline cache check
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // G4: 2nd Long arg
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // G5: used in inline cache check
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // G6: used by OS
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // G7: used by OS
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (g_reg == G1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 regs[i].set2(G1->as_VMReg()); // This long arg in G1
a61af66fc99e Initial load
duke
parents:
diff changeset
510 g_reg = G4; // Where the next arg goes
a61af66fc99e Initial load
duke
parents:
diff changeset
511 } else if (g_reg == G4) {
a61af66fc99e Initial load
duke
parents:
diff changeset
512 regs[i].set2(G4->as_VMReg()); // The 2nd long arg in G4
a61af66fc99e Initial load
duke
parents:
diff changeset
513 g_reg = noreg; // No more longs in registers
a61af66fc99e Initial load
duke
parents:
diff changeset
514 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
a61af66fc99e Initial load
duke
parents:
diff changeset
516 stk_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
518 #else // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
519 regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
a61af66fc99e Initial load
duke
parents:
diff changeset
520 stk_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 #endif // COMPILER2
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
522 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
523 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (flt_reg < flt_reg_max) regs[i].set1(as_FloatRegister(flt_reg++)->as_VMReg());
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
527 else regs[i].set1(VMRegImpl::stack2reg(stk_reg++));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
528 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 assert(sig_bt[i+1] == T_VOID, "expecting half");
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (flt_reg_pairs + 1 < flt_reg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 regs[i].set2(as_FloatRegister(flt_reg_pairs)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
533 flt_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
a61af66fc99e Initial load
duke
parents:
diff changeset
536 stk_reg_pairs += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 case T_VOID: regs[i].set_bad(); break; // Halves of longs & doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
540 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
541 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // retun the amount of stack space these arguments will need.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 return stk_reg_pairs;
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
550 // Helper class mostly to avoid passing masm everywhere, and handle
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
551 // store displacement overflow logic.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
552 class AdapterGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 MacroAssembler *masm;
a61af66fc99e Initial load
duke
parents:
diff changeset
554 Register Rdisp;
a61af66fc99e Initial load
duke
parents:
diff changeset
555 void set_Rdisp(Register r) { Rdisp = r; }
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 void patch_callers_callsite();
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // base+st_off points to top of argument
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
560 int arg_offset(const int st_off) { return st_off; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
561 int next_arg_offset(const int st_off) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
562 return st_off - Interpreter::stackElementSize;
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
563 }
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
564
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
565 // Argument slot values may be loaded first into a register because
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
566 // they might not fit into displacement.
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
567 RegisterOrConstant arg_slot(const int st_off);
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
568 RegisterOrConstant next_arg_slot(const int st_off);
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
569
0
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Stores long into offset pointed to by base
a61af66fc99e Initial load
duke
parents:
diff changeset
571 void store_c2i_long(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
572 const int st_off, bool is_stack);
a61af66fc99e Initial load
duke
parents:
diff changeset
573 void store_c2i_object(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
574 const int st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
575 void store_c2i_int(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
576 const int st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 void store_c2i_double(VMReg r_2,
a61af66fc99e Initial load
duke
parents:
diff changeset
578 VMReg r_1, Register base, const int st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
579 void store_c2i_float(FloatRegister f, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
580 const int st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
583 void gen_c2i_adapter(int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // VMReg max_arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
585 int comp_args_on_stack, // VMRegStackSlots
a61af66fc99e Initial load
duke
parents:
diff changeset
586 const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
587 const VMRegPair *regs,
a61af66fc99e Initial load
duke
parents:
diff changeset
588 Label& skip_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
589 void gen_i2c_adapter(int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
590 // VMReg max_arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
591 int comp_args_on_stack, // VMRegStackSlots
a61af66fc99e Initial load
duke
parents:
diff changeset
592 const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
593 const VMRegPair *regs);
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595 AdapterGenerator(MacroAssembler *_masm) : masm(_masm) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
596 };
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // Patch the callers callsite with entry to compiled code if it exists.
a61af66fc99e Initial load
duke
parents:
diff changeset
600 void AdapterGenerator::patch_callers_callsite() {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 Label L;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
602 __ ld_ptr(G5_method, in_bytes(Method::code_offset()), G3_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
603 __ br_null(G3_scratch, false, Assembler::pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Schedule the branch target address early.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
605 __ delayed()->ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // Call into the VM to patch the caller, then jump to compiled callee
a61af66fc99e Initial load
duke
parents:
diff changeset
607 __ save_frame(4); // Args in compiled layout; do not blow them
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Must save all the live Gregs the list is:
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // G1: 1st Long arg (32bit build)
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // G2: global allocated to TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // G3: used in inline cache check (scratch)
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // G4: 2nd Long arg (32bit build);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
614 // G5: used in inline cache check (Method*)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // The longs must go to the stack by hand since in the 32 bit build they can be trashed by window ops.
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // mov(s,d)
a61af66fc99e Initial load
duke
parents:
diff changeset
620 __ mov(G1, L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 __ mov(G4, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 __ mov(G5_method, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 __ mov(G5_method, O0); // VM needs target method
a61af66fc99e Initial load
duke
parents:
diff changeset
624 __ mov(I7, O1); // VM needs caller's callsite
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // Must be a leaf call...
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // can be very far once the blob has been relocated
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
627 AddressLiteral dest(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
628 __ relocate(relocInfo::runtime_call_type);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
629 __ jumpl_to(dest, O7, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
630 __ delayed()->mov(G2_thread, L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 __ mov(L7_thread_cache, G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 __ mov(L1, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 __ mov(L4, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 __ mov(L5, G5_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
635 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
636 __ stx(G1, FP, -8 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 __ stx(G4, FP, -16 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 __ mov(G5_method, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
639 __ mov(G5_method, O0); // VM needs target method
a61af66fc99e Initial load
duke
parents:
diff changeset
640 __ mov(I7, O1); // VM needs caller's callsite
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // Must be a leaf call...
a61af66fc99e Initial load
duke
parents:
diff changeset
642 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
643 __ delayed()->mov(G2_thread, L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
644 __ mov(L7_thread_cache, G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 __ ldx(FP, -8 + STACK_BIAS, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 __ ldx(FP, -16 + STACK_BIAS, G4);
a61af66fc99e Initial load
duke
parents:
diff changeset
647 __ mov(L5, G5_method);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
648 __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
649 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 __ restore(); // Restore args
a61af66fc99e Initial load
duke
parents:
diff changeset
652 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
655
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
656 RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) {
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
657 RegisterOrConstant roc(arg_offset(st_off));
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
658 return __ ensure_simm13_or_reg(roc, Rdisp);
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
659 }
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
660
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
661 RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) {
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
662 RegisterOrConstant roc(next_arg_offset(st_off));
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
663 return __ ensure_simm13_or_reg(roc, Rdisp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
666
0
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Stores long into offset pointed to by base
a61af66fc99e Initial load
duke
parents:
diff changeset
668 void AdapterGenerator::store_c2i_long(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
669 const int st_off, bool is_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // In V9, longs are given 2 64-bit slots in the interpreter, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // data is passed in only 1 slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
673 __ stx(r, base, next_arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
674 #else
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 116
diff changeset
675 #ifdef COMPILER2
0
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // Misaligned store of 64-bit data
a61af66fc99e Initial load
duke
parents:
diff changeset
677 __ stw(r, base, arg_slot(st_off)); // lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
678 __ srlx(r, 32, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
679 __ stw(r, base, next_arg_slot(st_off)); // hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
680 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
681 if (is_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // Misaligned store of 64-bit data
a61af66fc99e Initial load
duke
parents:
diff changeset
683 __ stw(r, base, arg_slot(st_off)); // lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
684 __ srlx(r, 32, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 __ stw(r, base, next_arg_slot(st_off)); // hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
686 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
687 __ stw(r->successor(), base, arg_slot(st_off) ); // lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
688 __ stw(r , base, next_arg_slot(st_off)); // hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 #endif // COMPILER2
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 116
diff changeset
691 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 void AdapterGenerator::store_c2i_object(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
695 const int st_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 __ st_ptr (r, base, arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 void AdapterGenerator::store_c2i_int(Register r, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
700 const int st_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 __ st (r, base, arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // Stores into offset pointed to by base
a61af66fc99e Initial load
duke
parents:
diff changeset
705 void AdapterGenerator::store_c2i_double(VMReg r_2,
a61af66fc99e Initial load
duke
parents:
diff changeset
706 VMReg r_1, Register base, const int st_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // In V9, doubles are given 2 64-bit slots in the interpreter, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // data is passed in only 1 slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
710 __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), base, next_arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
711 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // Need to marshal 64-bit value from misaligned Lesp loads
a61af66fc99e Initial load
duke
parents:
diff changeset
713 __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), base, next_arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
714 __ stf(FloatRegisterImpl::S, r_2->as_FloatRegister(), base, arg_slot(st_off) );
a61af66fc99e Initial load
duke
parents:
diff changeset
715 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 void AdapterGenerator::store_c2i_float(FloatRegister f, Register base,
a61af66fc99e Initial load
duke
parents:
diff changeset
719 const int st_off) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 __ stf(FloatRegisterImpl::S, f, base, arg_slot(st_off));
a61af66fc99e Initial load
duke
parents:
diff changeset
721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
722
a61af66fc99e Initial load
duke
parents:
diff changeset
723 void AdapterGenerator::gen_c2i_adapter(
a61af66fc99e Initial load
duke
parents:
diff changeset
724 int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // VMReg max_arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
726 int comp_args_on_stack, // VMRegStackSlots
a61af66fc99e Initial load
duke
parents:
diff changeset
727 const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
728 const VMRegPair *regs,
a61af66fc99e Initial load
duke
parents:
diff changeset
729 Label& skip_fixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // Before we get into the guts of the C2I adapter, see if we should be here
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // at all. We've come from compiled code and are attempting to jump to the
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // interpreter, which means the caller made a static call to get here
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // (vcalls always get a compiled target if there is one). Check for a
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // compiled target. If there is one, we need to patch the caller's call.
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // However we will run interpreted if we come thru here. The next pass
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // thru the call site will run compiled. If we ran compiled here then
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // we can (theorectically) do endless i2c->c2i->i2c transitions during
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // deopt/uncommon trap cycles. If we always go interpreted here then
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // we can have at most one and don't need to play any tricks to keep
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // from endlessly growing the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
742 //
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // Actually if we detected that we had an i2c->c2i transition here we
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // ought to be able to reset the world back to the state of the interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // call and not bother building another interpreter arg area. We don't
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // do that at this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 patch_callers_callsite();
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 __ bind(skip_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // Since all args are passed on the stack, total_args_passed*wordSize is the
a61af66fc99e Initial load
duke
parents:
diff changeset
753 // space we need. Add in varargs area needed by the interpreter. Round up
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // to stack alignment.
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
755 const int arg_size = total_args_passed * Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
756 const int varargs_area =
a61af66fc99e Initial load
duke
parents:
diff changeset
757 (frame::varargs_offset - frame::register_save_words)*wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
758 const int extraspace = round_to(arg_size + varargs_area, 2*wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
759
a61af66fc99e Initial load
duke
parents:
diff changeset
760 int bias = STACK_BIAS;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 const int interp_arg_offset = frame::varargs_offset*wordSize +
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
762 (total_args_passed-1)*Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 Register base = SP;
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // In the 64bit build because of wider slots and STACKBIAS we can run
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // out of bits in the displacement to do loads and stores. Use g3 as
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // temporary displacement.
4114
6729bbc1fcd6 7003454: order constants in constant table by number of references in code
twisti
parents: 3839
diff changeset
770 if (!Assembler::is_simm13(extraspace)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
771 __ set(extraspace, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
772 __ sub(SP, G3_scratch, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
773 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 __ sub(SP, extraspace, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
776 set_Rdisp(G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
778 __ sub(SP, extraspace, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
779 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
780
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // First write G1 (if used) to where ever it must go
a61af66fc99e Initial load
duke
parents:
diff changeset
782 for (int i=0; i<total_args_passed; i++) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
783 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
784 VMReg r_1 = regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
785 VMReg r_2 = regs[i].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
786 if (r_1 == G1_scratch->as_VMReg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 store_c2i_object(G1_scratch, base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 } else if (sig_bt[i] == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 assert(!TieredCompilation, "should not use register args for longs");
a61af66fc99e Initial load
duke
parents:
diff changeset
791 store_c2i_long(G1_scratch, base, st_off, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
792 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 store_c2i_int(G1_scratch, base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // Now write the args into the outgoing interpreter space
a61af66fc99e Initial load
duke
parents:
diff changeset
799 for (int i=0; i<total_args_passed; i++) {
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
800 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
801 VMReg r_1 = regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
802 VMReg r_2 = regs[i].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (!r_1->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 assert(!r_2->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
805 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // Skip G1 if found as we did it first in order to free it up
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (r_1 == G1_scratch->as_VMReg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
811 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
812 bool G1_forced = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
814 if (r_1->is_stack()) { // Pretend stack targets are loaded into G1
a61af66fc99e Initial load
duke
parents:
diff changeset
815 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
816 Register ld_off = Rdisp;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 __ set(reg2offset(r_1) + extraspace + bias, ld_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
818 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
819 int ld_off = reg2offset(r_1) + extraspace + bias;
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1187
diff changeset
820 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
821 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
822 G1_forced = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
823 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
824 r_1 = G1_scratch->as_VMReg();// as part of the load/store shuffle
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if (!r_2->is_valid()) __ ld (base, ld_off, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
826 else __ ldx(base, ld_off, G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 if (r_1->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 Register r = r_1->as_Register()->after_restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 store_c2i_object(r, base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
833 } else if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1187
diff changeset
834 #ifndef _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
835 if (TieredCompilation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 assert(G1_forced || sig_bt[i] != T_LONG, "should not use register args for longs");
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
1251
576e77447e3c 6923002: assert(false,"this call site should not be polymorphic")
kvn
parents: 1187
diff changeset
838 #endif // _LP64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
839 store_c2i_long(r, base, st_off, r_2->is_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
840 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 store_c2i_int(r, base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
843 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 assert(r_1->is_FloatRegister(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (sig_bt[i] == T_FLOAT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
846 store_c2i_float(r_1->as_FloatRegister(), base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 assert(sig_bt[i] == T_DOUBLE, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
849 store_c2i_double(r_2, r_1, base, st_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851 }
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // Need to reload G3_scratch, used for temporary displacements.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
856 __ ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // Pass O5_savedSP as an argument to the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
859 // The interpreter will restore SP to this value before returning.
a61af66fc99e Initial load
duke
parents:
diff changeset
860 __ set(extraspace, G1);
a61af66fc99e Initial load
duke
parents:
diff changeset
861 __ add(SP, G1, O5_savedSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // Pass O5_savedSP as an argument to the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // The interpreter will restore SP to this value before returning.
a61af66fc99e Initial load
duke
parents:
diff changeset
865 __ add(SP, extraspace, O5_savedSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
866 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 __ mov((frame::varargs_offset)*wordSize -
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
869 1*Interpreter::stackElementSize+bias+BytesPerWord, G1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // Jump to the interpreter just as if interpreter was doing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
871 __ jmpl(G3_scratch, 0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // Setup Lesp for the call. Cannot actually set Lesp as the current Lesp
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // (really L0) is in use by the compiled frame as a generic temp. However,
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // the interpreter does not know where its args are without some kind of
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // arg pointer being passed in. Pass it in Gargs.
a61af66fc99e Initial load
duke
parents:
diff changeset
876 __ delayed()->add(SP, G1, Gargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
879 static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg, Register temp2_reg,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
880 address code_start, address code_end,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
881 Label& L_ok) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
882 Label L_fail;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
883 __ set(ExternalAddress(code_start), temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
884 __ set(pointer_delta(code_end, code_start, 1), temp2_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
885 __ cmp(pc_reg, temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
886 __ brx(Assembler::lessEqualUnsigned, false, Assembler::pn, L_fail);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
887 __ delayed()->add(temp_reg, temp2_reg, temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
888 __ cmp(pc_reg, temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
889 __ cmp_and_brx_short(pc_reg, temp_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
890 __ bind(L_fail);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
891 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
892
0
a61af66fc99e Initial load
duke
parents:
diff changeset
893 void AdapterGenerator::gen_i2c_adapter(
a61af66fc99e Initial load
duke
parents:
diff changeset
894 int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // VMReg max_arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
896 int comp_args_on_stack, // VMRegStackSlots
a61af66fc99e Initial load
duke
parents:
diff changeset
897 const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
898 const VMRegPair *regs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // Generate an I2C adapter: adjust the I-frame to make space for the C-frame
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // layout. Lesp was saved by the calling I-frame and will be restored on
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // return. Meanwhile, outgoing arg space is all owned by the callee
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // C-frame, so we can mangle it at will. After adjusting the frame size,
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // hoist register arguments and repack other args according to the compiled
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // code convention. Finally, end in a jump to the compiled code. The entry
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // point address is the start of the buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // We will only enter here from an interpreted frame and never from after
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // passing thru a c2i. Azul allowed this but we do not. If we lose the
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // race and use a c2i we will remain interpreted for the race loser(s).
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // This removes all sorts of headaches on the x86 side and also eliminates
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // the possibility of having c2i -> i2c -> c2i -> ... endless transitions.
a61af66fc99e Initial load
duke
parents:
diff changeset
913
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
914 // More detail:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
915 // Adapters can be frameless because they do not require the caller
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
916 // to perform additional cleanup work, such as correcting the stack pointer.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
917 // An i2c adapter is frameless because the *caller* frame, which is interpreted,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
918 // routinely repairs its own stack pointer (from interpreter_frame_last_sp),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
919 // even if a callee has modified the stack pointer.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
920 // A c2i adapter is frameless because the *callee* frame, which is interpreted,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
921 // routinely repairs its caller's stack pointer (from sender_sp, which is set
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
922 // up via the senderSP register).
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
923 // In other words, if *either* the caller or callee is interpreted, we can
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
924 // get the stack pointer repaired after a call.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
925 // This is why c2i and i2c adapters cannot be indefinitely composed.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
926 // In particular, if a c2i adapter were to somehow call an i2c adapter,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
927 // both caller and callee would be compiled methods, and neither would
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
928 // clean up the stack pointer changes performed by the two adapters.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
929 // If this happens, control eventually transfers back to the compiled
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
930 // caller, but with an uncorrected stack, causing delayed havoc.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
931
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
932 if (VerifyAdapterCalls &&
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
933 (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
934 // So, let's test for cascading c2i/i2c adapters right now.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
935 // assert(Interpreter::contains($return_addr) ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
936 // StubRoutines::contains($return_addr),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
937 // "i2c adapter must return to an interpreter frame");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
938 __ block_comment("verify_i2c { ");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
939 Label L_ok;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
940 if (Interpreter::code() != NULL)
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
941 range_check(masm, O7, O0, O1,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
942 Interpreter::code()->code_start(), Interpreter::code()->code_end(),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
943 L_ok);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
944 if (StubRoutines::code1() != NULL)
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
945 range_check(masm, O7, O0, O1,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
946 StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
947 L_ok);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
948 if (StubRoutines::code2() != NULL)
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
949 range_check(masm, O7, O0, O1,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
950 StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
951 L_ok);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
952 const char* msg = "i2c adapter must return to an interpreter frame";
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
953 __ block_comment(msg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
954 __ stop(msg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
955 __ bind(L_ok);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
956 __ block_comment("} verify_i2ce ");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
957 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
958
0
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // As you can see from the list of inputs & outputs there are not a lot
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // of temp registers to work with: mostly G1, G3 & G4.
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // Inputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // G2_thread - TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
964 // G5_method - Method oop
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 610
diff changeset
965 // G4 (Gargs) - Pointer to interpreter's args
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 610
diff changeset
966 // O0..O4 - free for scratch
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 610
diff changeset
967 // O5_savedSP - Caller's saved SP, to be restored if needed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // O6 - Current SP!
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // O7 - Valid return address
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 610
diff changeset
970 // L0-L7, I0-I7 - Caller's temps (no frame pushed yet)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // Outputs:
a61af66fc99e Initial load
duke
parents:
diff changeset
973 // G2_thread - TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // G1, G4 - Outgoing long args in 32-bit build
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // O0-O5 - Outgoing args in compiled layout
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // O6 - Adjusted or restored SP
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // O7 - Valid return address
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1506
diff changeset
978 // L0-L7, I0-I7 - Caller's temps (no frame pushed yet)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // F0-F7 - more outgoing args
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 610
diff changeset
982 // Gargs is the incoming argument base, and also an outgoing argument.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
983 __ sub(Gargs, BytesPerWord, Gargs);
a61af66fc99e Initial load
duke
parents:
diff changeset
984
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // ON ENTRY TO THE CODE WE ARE MAKING, WE HAVE AN INTERPRETED FRAME
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // WITH O7 HOLDING A VALID RETURN PC
a61af66fc99e Initial load
duke
parents:
diff changeset
987 //
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // : java stack :
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // +--------------+ <--- start of outgoing args
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // | receiver | |
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // : rest of args : |---size is java-arg-words
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // +--------------+ <--- O4_args (misaligned) and Lesp if prior is not C2I
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // : unused : |---Space for max Java stack, plus stack alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // +--------------+ <--- SP + 16*wordsize
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 // : window :
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // +--------------+ <--- SP
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // WE REPACK THE STACK. We use the common calling convention layout as
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // discovered by calling SharedRuntime::calling_convention. We assume it
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // causes an arbitrary shuffle of memory, which may require some register
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 // temps to do the shuffle. We hope for (and optimize for) the case where
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // temps are not needed. We may have to resize the stack slightly, in case
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // we need alignment padding (32-bit interpreter can pass longs & doubles
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // misaligned, but the compilers expect them aligned).
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // : java stack :
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // +--------------+ <--- start of outgoing args
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // | pad, align | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // +--------------+ |
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // | ints, floats | |---Outgoing stack args, packed low.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // +--------------+ | First few args in registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // : doubles : |
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // | longs | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // +--------------+ <--- SP' + 16*wordsize
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // : window :
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // +--------------+ <--- SP'
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // ON EXIT FROM THE CODE WE ARE MAKING, WE STILL HAVE AN INTERPRETED FRAME
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // WITH O7 HOLDING A VALID RETURN PC - ITS JUST THAT THE ARGS ARE NOW SETUP
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // FOR COMPILED CODE AND THE FRAME SLIGHTLY GROWN.
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // Cut-out for having no stack args. Since up to 6 args are passed
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // in registers, we will commonly have no stack args.
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 if (comp_args_on_stack > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // Convert VMReg stack slots to words.
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 int comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // Round up to miminum stack alignment, in wordSize
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 comp_words_on_stack = round_to(comp_words_on_stack, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // Now compute the distance from Lesp to SP. This calculation does not
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // include the space for total_args_passed because Lesp has not yet popped
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // the arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 __ sub(SP, (comp_words_on_stack)*wordSize, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // Will jump to the compiled code just as if compiled code was doing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // Pre-load the register-jump target early, to schedule it better.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1049 __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // Now generate the shuffle code. Pick up all register args and move the
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // rest through G1_scratch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 for (int i=0; i<total_args_passed; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 if (sig_bt[i] == T_VOID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // Longs and doubles are passed in native word order, but misaligned
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // in the 32-bit build.
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // Pick up 0, 1 or 2 words from Lesp+offset. Assume mis-aligned in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // 32-bit build and aligned in the 64-bit build. Look for the obvious
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // ldx/lddf optimizations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // Load in argument order going down.
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
1066 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 set_Rdisp(G1_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 VMReg r_1 = regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 VMReg r_2 = regs[i].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 if (!r_1->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 assert(!r_2->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 if (r_1->is_stack()) { // Pretend stack targets are loaded into F8/F9
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 r_1 = F8->as_VMReg(); // as part of the load/store shuffle
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 if (r_2->is_valid()) r_2 = r_1->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if (r_1->is_Register()) { // Register argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 Register r = r_1->as_Register()->after_restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if (!r_2->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 __ ld(Gargs, arg_slot(ld_off), r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // In V9, longs are given 2 64-bit slots in the interpreter, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // data is passed in only 1 slot.
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
1087 RegisterOrConstant slot = (sig_bt[i] == T_LONG) ?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 next_arg_slot(ld_off) : arg_slot(ld_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 __ ldx(Gargs, slot, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // stack shuffle. Load the first 2 longs into G1/G4 later.
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 assert(r_1->is_FloatRegister(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (!r_2->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // In V9, doubles are given 2 64-bit slots in the interpreter, but the
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 // data is passed in only 1 slot. This code also handles longs that
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // are passed on the stack, but need a stack-to-stack move through a
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // spare float register.
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
1105 RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 next_arg_slot(ld_off) : arg_slot(ld_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // Need to marshal 64-bit value from misaligned Lesp loads
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // Was the argument really intended to be on the stack, but was loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // into F8/F9?
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 if (regs[i].first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 assert(r_1->as_FloatRegister() == F8, "fix this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 // Convert stack slot to an SP offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 int st_off = reg2offset(regs[i].first()) + STACK_BIAS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // Store down the shuffled stack word. Target address _is_ aligned.
1006
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
1122 RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp);
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
1123 if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot);
dcf03e02b020 6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
twisti
parents: 727
diff changeset
1124 else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 bool made_space = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // May need to pick up a few long args in G1/G4
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 bool g4_crushed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 bool g3_crushed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 for (int i=0; i<total_args_passed; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 if (regs[i].first()->is_Register() && regs[i].second()->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // Load in argument order going down
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
1135 int ld_off = (total_args_passed-i)*Interpreter::stackElementSize;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Need to marshal 64-bit value from misaligned Lesp loads
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 Register r = regs[i].first()->as_Register()->after_restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 if (r == G1 || r == G4) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 assert(!g4_crushed, "ordering problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if (r == G4){
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 g4_crushed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 __ lduw(Gargs, arg_slot(ld_off) , G3_scratch); // Load lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // better schedule this way
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 __ lduw(Gargs, arg_slot(ld_off) , G3_scratch); // Load lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 g3_crushed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 __ sllx(r, 32, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 __ or3(G3_scratch, r, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 assert(r->is_out(), "longs passed in two O registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 __ ld (Gargs, arg_slot(ld_off) , r->successor()); // Load lo bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 __ ld (Gargs, next_arg_slot(ld_off), r); // Load hi bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // Jump to the compiled code just as if compiled code was doing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 if (g3_crushed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // Rats load was wasted, at least it is in cache...
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1166 __ ld_ptr(G5_method, Method::from_compiled_offset(), G3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1169
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // 6243940 We might end up in handle_wrong_method if
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // the callee is deoptimized as we race thru here. If that
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // happens we don't want to take a safepoint because the
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // caller frame will look interpreted and arguments are now
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // "compiled" so it is much better to make this transition
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // invisible to the stack walking code. Unfortunately if
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // we try and find the callee by normal means a safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // is possible. So we stash the desired callee in the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 // and the vm will find there should this case occur.
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1179 Address callee_target_addr(G2_thread, JavaThread::callee_target_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 __ st_ptr(G5_method, callee_target_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 if (StressNonEntrant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // Open a big window for deopt failure
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 __ save_frame(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 __ mov(G0, L0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 Label loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 __ bind(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 __ sub(L0, 1, L0);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
1189 __ br_null_short(L0, Assembler::pt, loop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 __ jmpl(G3, 0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // ---------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 int total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // VMReg max_arg,
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 int comp_args_on_stack, // VMRegStackSlots
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 const BasicType *sig_bt,
1187
cf0685d550f1 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 1037
diff changeset
1205 const VMRegPair *regs,
cf0685d550f1 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 1037
diff changeset
1206 AdapterFingerPrint* fingerprint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 address i2c_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1208
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 AdapterGenerator agen(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1212
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // -------------------------------------------------------------------------
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1215 // Generate a C2I adapter. On entry we know G5 holds the Method*. The
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // args start out packed in the compiled layout. They need to be unpacked
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // into the interpreter layout. This will almost always require some stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // space. We grow the current (compiled) stack, then repack the args. We
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // finally end in a jump to the generic interpreter entry point. On exit
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // from the interpreter, the interpreter will restore our SP (lest the
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // compiled code, which relys solely on SP and not FP, get sick).
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 address c2i_unverified_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 Label skip_fixup;
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 #if !defined(_LP64) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 Register R_temp = L0; // another scratch register
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 Register R_temp = G1; // another scratch register
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1232 AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1233
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 __ verify_oop(O0);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1235 __ load_klass(O0, G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 #if !defined(_LP64) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 __ save(SP, -frame::register_save_words*wordSize, SP);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1239 __ ld_ptr(G5_method, CompiledICHolder::holder_klass_offset(), R_temp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 __ cmp(G3_scratch, R_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 #else
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1243 __ ld_ptr(G5_method, CompiledICHolder::holder_klass_offset(), R_temp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 __ cmp(G3_scratch, R_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 Label ok, ok2;
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 __ brx(Assembler::equal, false, Assembler::pt, ok);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1249 __ delayed()->ld_ptr(G5_method, CompiledICHolder::holder_method_offset(), G5_method);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1250 __ jump_to(ic_miss, G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 __ bind(ok);
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // Method might have been compiled since the call site was patched to
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // interpreted if that is the case treat it as a miss so we can get
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // the call site corrected.
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1257 __ ld_ptr(G5_method, in_bytes(Method::code_offset()), G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 __ bind(ok2);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
1259 __ br_null(G3_scratch, false, Assembler::pt, skip_fixup);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
1260 __ delayed()->ld_ptr(G5_method, in_bytes(Method::interpreter_entry_offset()), G3_scratch);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1261 __ jump_to(ic_miss, G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1263
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1265
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 address c2i_entry = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1267
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 __ flush();
1187
cf0685d550f1 6911204: generated adapters with large signatures can fill up the code cache
never
parents: 1037
diff changeset
1271 return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1274
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // Helper function for native calling conventions
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 static VMReg int_stk_helper( int i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // Bias any stack based VMReg we get by ignoring the window area
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // but not the register parameter save area.
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // This is strange for the following reasons. We'd normally expect
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // the calling convention to return an VMReg for a stack slot
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // completely ignoring any abi reserved area. C2 thinks of that
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // abi area as only out_preserve_stack_slots. This does not include
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // the area allocated by the C abi to store down integer arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // because the java calling convention does not use it. So
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // since c2 assumes that there are only out_preserve_stack_slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // to bias the optoregs (which impacts VMRegs) when actually referencing any actual stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // location the c calling convention must add in this bias amount
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // to make up for the fact that the out_preserve_stack_slots is
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // insufficient for C calls. What a mess. I sure hope those 6
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // stack words were worth it on every java call!
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // Another way of cleaning this up would be for out_preserve_stack_slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 // to take a parameter to say whether it was C or java calling conventions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // Then things might look a little better (but not much).
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 int mem_parm_offset = i - SPARC_ARGS_IN_REGS_NUM;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 if( mem_parm_offset < 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 return as_oRegister(i)->as_VMReg();
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 int actual_offset = (mem_parm_offset + frame::memory_parameter_word_sp_offset) * VMRegImpl::slots_per_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // Now return a biased offset that will be correct when out_preserve_slots is added back in
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 return VMRegImpl::stack2reg(actual_offset - SharedRuntime::out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 VMRegPair *regs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 int total_args_passed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // Return the number of VMReg stack_slots needed for the args.
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // This value does not include an abi space (like register window
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // save area).
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // The native convention is V8 if !LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // The LP64 convention is the V9 convention which is slightly more sane.
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // We return the amount of VMReg stack slots we need to reserve for all
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // the arguments NOT counting out_preserve_stack_slots. Since we always
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // have space for storing at least 6 registers to memory we start with that.
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // See int_stk_helper for a further discussion.
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 int max_stack_slots = (frame::varargs_offset * VMRegImpl::slots_per_word) - SharedRuntime::out_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // V9 convention: All things "as-if" on double-wide stack slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // Hoist any int/ptr/long's in the first 6 to int regs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // Hoist any flt/dbl's in the first 16 dbl regs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 int j = 0; // Count of actual args, not HALVES
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 for( int i=0; i<total_args_passed; i++, j++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 switch( sig_bt[i] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 regs[i].set1( int_stk_helper( j ) ); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 assert( sig_bt[i+1] == T_VOID, "expecting half" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 case T_ADDRESS: // raw pointers, like current thread, for VM calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 case T_OBJECT:
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6725
diff changeset
1343 case T_METADATA:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 regs[i].set2( int_stk_helper( j ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if ( j < 16 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // V9ism: floats go in ODD registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 regs[i].set1(as_FloatRegister(1 + (j<<1))->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 // V9ism: floats go in ODD stack slot
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 regs[i].set1(VMRegImpl::stack2reg(1 + (j<<1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 assert( sig_bt[i+1] == T_VOID, "expecting half" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 if ( j < 16 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // V9ism: doubles go in EVEN/ODD regs
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 regs[i].set2(as_FloatRegister(j<<1)->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // V9ism: doubles go in EVEN/ODD stack slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 regs[i].set2(VMRegImpl::stack2reg(j<<1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 case T_VOID: regs[i].set_bad(); j--; break; // Do not count HALVES
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 if (regs[i].first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 int off = regs[i].first()->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 if (off > max_stack_slots) max_stack_slots = off;
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 if (regs[i].second()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 int off = regs[i].second()->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 if (off > max_stack_slots) max_stack_slots = off;
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1378
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 #else // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // V8 convention: first 6 things in O-regs, rest on stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // Alignment is willy-nilly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 for( int i=0; i<total_args_passed; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 switch( sig_bt[i] ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 case T_ADDRESS: // raw pointers, like current thread, for VM calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 case T_OBJECT:
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6725
diff changeset
1392 case T_METADATA:
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 regs[i].set1( int_stk_helper( i ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 assert( sig_bt[i+1] == T_VOID, "expecting half" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 regs[i].set_pair( int_stk_helper( i+1 ), int_stk_helper( i ) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 case T_VOID: regs[i].set_bad(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 if (regs[i].first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 int off = regs[i].first()->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 if (off > max_stack_slots) max_stack_slots = off;
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 if (regs[i].second()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 int off = regs[i].second()->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if (off > max_stack_slots) max_stack_slots = off;
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 return round_to(max_stack_slots + 1, 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1419
a61af66fc99e Initial load
duke
parents:
diff changeset
1420
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 switch (ret_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 __ stf(FloatRegisterImpl::S, F0, SP, frame_slots*VMRegImpl::stack_slot_size - 4+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 __ stf(FloatRegisterImpl::D, F0, SP, frame_slots*VMRegImpl::stack_slot_size - 8+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 switch (ret_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 __ ldf(FloatRegisterImpl::S, SP, frame_slots*VMRegImpl::stack_slot_size - 4+STACK_BIAS, F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 __ ldf(FloatRegisterImpl::D, SP, frame_slots*VMRegImpl::stack_slot_size - 8+STACK_BIAS, F0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // Check and forward and pending exception. Thread is stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 // L7_thread_cache and possibly NOT in G2_thread. Since this is a native call, there
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 // is no exception handler. We merely pop this frame off and throw the
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 // exception in the caller's frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 static void check_forward_pending_exception(MacroAssembler *masm, Register Rex_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 __ br_null(Rex_oop, false, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 __ delayed()->mov(L7_thread_cache, G2_thread); // restore in case we have exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // Since this is a native call, we *know* the proper exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // without calling into the VM: it's the empty function. Just pop this
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // frame and then jump to forward_exception_entry; O7 will contain the
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // native caller's return PC.
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1456 AddressLiteral exception_entry(StubRoutines::forward_exception_entry());
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
1457 __ jump_to(exception_entry, G3_scratch);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 __ delayed()->restore(); // Pop this frame off.
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1461
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // A simple move of integer like type
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 static void simple_move32(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 if (src.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // stack to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // stack to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 } else if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // reg to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 __ st(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 __ mov(src.first()->as_Register(), dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1480
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // On 64 bit we will store integer like items to the stack as
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // 64 bits items (sparc abi) even though java would only store
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // 32bits for a parameter. On 32bit it will simply be 32 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // So this routine will do 32->32 on 32bit and 32->64 on 64bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 if (src.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // stack to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 __ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // stack to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 } else if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // reg to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 __ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 __ mov(src.first()->as_Register(), dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1504 static void move_ptr(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1505 if (src.first()->is_stack()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1506 if (dst.first()->is_stack()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1507 // stack to stack
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1508 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, L5);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1509 __ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1510 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1511 // stack to reg
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1512 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1513 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1514 } else if (dst.first()->is_stack()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1515 // reg to stack
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1516 __ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1517 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1518 __ mov(src.first()->as_Register(), dst.first()->as_Register());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1519 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1520 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1521
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1522
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // An oop arg. Must pass a handle not the oop itself
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 static void object_move(MacroAssembler* masm,
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 OopMap* map,
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 int oop_handle_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 int framesize_in_slots,
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 VMRegPair src,
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 VMRegPair dst,
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 bool is_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 int* receiver_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // must pass a handle. First figure out the location we use as a handle
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 if (src.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // Oop is already on the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 Register rHandle = dst.first()->is_stack() ? L5 : dst.first()->as_Register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 __ add(FP, reg2offset(src.first()) + STACK_BIAS, rHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 __ ld_ptr(rHandle, 0, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 __ movr( Assembler::rc_z, L4, G0, rHandle );
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 __ tst( L4 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 __ movcc( Assembler::zero, false, Assembler::icc, G0, rHandle );
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 __ st_ptr(rHandle, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 if (is_receiver) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots));
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // Oop is in an input register pass we must flush it to the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 const Register rOop = src.first()->as_Register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 const Register rHandle = L5;
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 int oop_slot = rOop->input_number() * VMRegImpl::slots_per_word + oop_handle_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 int offset = oop_slot*VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 Label skip;
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 __ st_ptr(rOop, SP, offset + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if (is_receiver) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 *receiver_offset = oop_slot * VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 map->set_oop(VMRegImpl::stack2reg(oop_slot));
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 __ add(SP, offset + STACK_BIAS, rHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 __ movr( Assembler::rc_z, rOop, G0, rHandle );
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 __ tst( rOop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 __ movcc( Assembler::zero, false, Assembler::icc, G0, rHandle );
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 __ st_ptr(rHandle, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 __ mov(rHandle, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1581
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 // A float arg may have to do float reg int reg conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 assert(!src.second()->is_valid() && !dst.second()->is_valid(), "bad float_move");
a61af66fc99e Initial load
duke
parents:
diff changeset
1585
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 if (src.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // stack to stack the easiest of the bunch
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 // stack to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 __ ldf(FloatRegisterImpl::S, FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 } else if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 // reg to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 if (src.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 __ st(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // reg to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 if (src.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // gpr -> gpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 __ mov(src.first()->as_Register(), dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // gpr -> fpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 __ st(src.first()->as_Register(), FP, -4 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 __ ldf(FloatRegisterImpl::S, FP, -4 + STACK_BIAS, dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 } else if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // fpr -> gpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), FP, -4 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 __ ld(FP, -4 + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // fpr -> fpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // In theory these overlap but the ordering is such that this is likely a nop
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 if ( src.first() != dst.first()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 __ fmov(FloatRegisterImpl::S, src.first()->as_FloatRegister(), dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1630
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 static void split_long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 VMRegPair src_lo(src.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 VMRegPair src_hi(src.second());
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 VMRegPair dst_lo(dst.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 VMRegPair dst_hi(dst.second());
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 simple_move32(masm, src_lo, dst_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 simple_move32(masm, src_hi, dst_hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1639
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 // A long move
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1642
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // Do the simple ones here else do two int moves
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 if (src.is_single_phys_reg() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 if (dst.is_single_phys_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 __ mov(src.first()->as_Register(), dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // split src into two separate registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 // Remember hi means hi address or lsw on sparc
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // Move msw to lsw
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 if (dst.second()->is_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // MSW -> MSW
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 __ srax(src.first()->as_Register(), 32, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // Now LSW -> LSW
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // this will only move lo -> lo and ignore hi
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 VMRegPair split(dst.second());
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 simple_move32(masm, src, split);
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 VMRegPair split(src.first(), L4->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // MSW -> MSW (lo ie. first word)
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 __ srax(src.first()->as_Register(), 32, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 split_long_move(masm, split, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 } else if (dst.is_single_phys_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 if (src.is_adjacent_aligned_on_stack(2)) {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
1667 __ ldx(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 // dst is a single reg.
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // Remember lo is low address not msb for stack slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // and lo is the "real" register for registers
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 // src is
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 VMRegPair split;
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 if (src.first()->is_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 // src.lo (msw) is a reg, src.hi is stk/reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // we will move: src.hi (LSW) -> dst.lo, src.lo (MSW) -> src.lo [the MSW is in the LSW of the reg]
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 split.set_pair(dst.first(), src.first());
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 // msw is stack move to L5
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 // lsw is stack move to dst.lo (real reg)
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // we will move: src.hi (LSW) -> dst.lo, src.lo (MSW) -> L5
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 split.set_pair(dst.first(), L5->as_VMReg());
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 // src.lo -> src.lo/L5, src.hi -> dst.lo (the real reg)
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 // msw -> src.lo/L5, lsw -> dst.lo
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 split_long_move(masm, src, split);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 // So dst now has the low order correct position the
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 // msw half
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 __ sllx(split.first()->as_Register(), 32, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1694
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 const Register d = dst.first()->as_Register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 __ or3(L5, d, d);
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // For LP64 we can probably do better.
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 split_long_move(masm, src, dst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1703
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // A double move
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1706
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 // The painful thing here is that like long_move a VMRegPair might be
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // 1: a single physical register
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // 2: two physical registers (v8)
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 // 3: a physical reg [lo] and a stack slot [hi] (v8)
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 // 4: two stack slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1712
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 // Since src is always a java calling convention we know that the src pair
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 // is always either all registers or all stack (and aligned?)
a61af66fc99e Initial load
duke
parents:
diff changeset
1715
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 // in a register [lo] and a stack slot [hi]
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 if (src.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 // stack to stack the easiest of the bunch
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // ought to be a way to do this where if alignment is ok we use ldd/std when possible
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 __ ld(FP, reg2offset(src.second()) + STACK_BIAS, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 __ st(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 __ st(L4, SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // stack to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 if (dst.second()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // stack -> reg, stack -> stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 __ ld(FP, reg2offset(src.second()) + STACK_BIAS, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 __ ldf(FloatRegisterImpl::S, FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 // This was missing. (very rare case)
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 __ st(L4, SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // stack -> reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // Eventually optimize for alignment QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 __ ld(FP, reg2offset(src.second()) + STACK_BIAS, dst.second()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 __ ldf(FloatRegisterImpl::S, FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 __ ldf(FloatRegisterImpl::S, FP, reg2offset(src.second()) + STACK_BIAS, dst.second()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 } else if (dst.first()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // reg to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 if (src.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // Eventually optimize for alignment QQQ
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 __ st(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 if (src.second()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 __ ld(FP, reg2offset(src.second()) + STACK_BIAS, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 __ st(L4, SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 __ st(src.second()->as_Register(), SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // fpr to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 if (src.second()->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 // Is the stack aligned?
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 if (reg2offset(dst.first()) & 0x7) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // No do as pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 __ stf(FloatRegisterImpl::S, src.second()->as_FloatRegister(), SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(), SP, reg2offset(dst.first()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 // reg to reg
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 if (src.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // gpr -> gpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 __ mov(src.first()->as_Register(), dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 __ mov(src.second()->as_Register(), dst.second()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // gpr -> fpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // ought to be able to do a single store
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 __ stx(src.first()->as_Register(), FP, -8 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 __ stx(src.second()->as_Register(), FP, -4 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // ought to be able to do a single load
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 __ ldf(FloatRegisterImpl::S, FP, -8 + STACK_BIAS, dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 __ ldf(FloatRegisterImpl::S, FP, -4 + STACK_BIAS, dst.second()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 } else if (dst.first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 // fpr -> gpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // ought to be able to do a single store
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(), FP, -8 + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // ought to be able to do a single load
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // REMEMBER first() is low address not LSB
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 __ ld(FP, -8 + STACK_BIAS, dst.first()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 if (dst.second()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 __ ld(FP, -4 + STACK_BIAS, dst.second()->as_Register());
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 __ ld(FP, -4 + STACK_BIAS, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 __ st(L4, SP, reg2offset(dst.second()) + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 // fpr -> fpr
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 // In theory these overlap but the ordering is such that this is likely a nop
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 if ( src.first() != dst.first()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 __ fmov(FloatRegisterImpl::D, src.first()->as_FloatRegister(), dst.first()->as_FloatRegister());
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1813
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // Creates an inner frame if one hasn't already been created, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // saves a copy of the thread in L7_thread_cache
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 static void create_inner_frame(MacroAssembler* masm, bool* already_created) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 if (!*already_created) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 __ save_frame(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 // Save thread in L7 (INNER FRAME); it crosses a bunch of VM calls below
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 // Don't use save_thread because it smashes G2 and we merely want to save a
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 // copy
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 __ mov(G2_thread, L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 *already_created = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1826
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1827
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1828 static void save_or_restore_arguments(MacroAssembler* masm,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1829 const int stack_slots,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1830 const int total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1831 const int arg_save_area,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1832 OopMap* map,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1833 VMRegPair* in_regs,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1834 BasicType* in_sig_bt) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1835 // if map is non-NULL then the code should store the values,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1836 // otherwise it should load them.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1837 if (map != NULL) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1838 // Fill in the map
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1839 for (int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1840 if (in_sig_bt[i] == T_ARRAY) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1841 if (in_regs[i].first()->is_stack()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1842 int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1843 map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots));
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1844 } else if (in_regs[i].first()->is_Register()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1845 map->set_oop(in_regs[i].first());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1846 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1847 ShouldNotReachHere();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1848 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1849 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1850 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1851 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1852
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1853 // Save or restore double word values
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1854 int handle_index = 0;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1855 for (int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1856 int slot = handle_index + arg_save_area;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1857 int offset = slot * VMRegImpl::stack_slot_size;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1858 if (in_sig_bt[i] == T_LONG && in_regs[i].first()->is_Register()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1859 const Register reg = in_regs[i].first()->as_Register();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1860 if (reg->is_global()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1861 handle_index += 2;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1862 assert(handle_index <= stack_slots, "overflow");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1863 if (map != NULL) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1864 __ stx(reg, SP, offset + STACK_BIAS);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1865 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1866 __ ldx(SP, offset + STACK_BIAS, reg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1867 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1868 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1869 } else if (in_sig_bt[i] == T_DOUBLE && in_regs[i].first()->is_FloatRegister()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1870 handle_index += 2;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1871 assert(handle_index <= stack_slots, "overflow");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1872 if (map != NULL) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1873 __ stf(FloatRegisterImpl::D, in_regs[i].first()->as_FloatRegister(), SP, offset + STACK_BIAS);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1874 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1875 __ ldf(FloatRegisterImpl::D, SP, offset + STACK_BIAS, in_regs[i].first()->as_FloatRegister());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1876 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1877 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1878 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1879 // Save floats
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1880 for (int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1881 int slot = handle_index + arg_save_area;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1882 int offset = slot * VMRegImpl::stack_slot_size;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1883 if (in_sig_bt[i] == T_FLOAT && in_regs[i].first()->is_FloatRegister()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1884 handle_index++;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1885 assert(handle_index <= stack_slots, "overflow");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1886 if (map != NULL) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1887 __ stf(FloatRegisterImpl::S, in_regs[i].first()->as_FloatRegister(), SP, offset + STACK_BIAS);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1888 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1889 __ ldf(FloatRegisterImpl::S, SP, offset + STACK_BIAS, in_regs[i].first()->as_FloatRegister());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1890 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1891 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1892 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1893
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1894 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1895
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1896
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1897 // Check GC_locker::needs_gc and enter the runtime if it's true. This
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1898 // keeps a new JNI critical region from starting until a GC has been
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1899 // forced. Save down any oops in registers and describe them in an
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1900 // OopMap.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1901 static void check_needs_gc_for_critical_native(MacroAssembler* masm,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1902 const int stack_slots,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1903 const int total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1904 const int arg_save_area,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1905 OopMapSet* oop_maps,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1906 VMRegPair* in_regs,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1907 BasicType* in_sig_bt) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1908 __ block_comment("check GC_locker::needs_gc");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1909 Label cont;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1910 AddressLiteral sync_state(GC_locker::needs_gc_address());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1911 __ load_bool_contents(sync_state, G3_scratch);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1912 __ cmp_zero_and_br(Assembler::equal, G3_scratch, cont);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1913 __ delayed()->nop();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1914
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1915 // Save down any values that are live in registers and call into the
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1916 // runtime to halt for a GC
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1917 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1918 save_or_restore_arguments(masm, stack_slots, total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1919 arg_save_area, map, in_regs, in_sig_bt);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1920
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1921 __ mov(G2_thread, L7_thread_cache);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1922
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1923 __ set_last_Java_frame(SP, noreg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1924
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1925 __ block_comment("block_for_jni_critical");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1926 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical), relocInfo::runtime_call_type);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1927 __ delayed()->mov(L7_thread_cache, O0);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1928 oop_maps->add_gc_map( __ offset(), map);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1929
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1930 __ restore_thread(L7_thread_cache); // restore G2_thread
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1931 __ reset_last_Java_frame();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1932
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1933 // Reload all the register arguments
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1934 save_or_restore_arguments(masm, stack_slots, total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1935 arg_save_area, NULL, in_regs, in_sig_bt);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1936
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1937 __ bind(cont);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1938 #ifdef ASSERT
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1939 if (StressCriticalJNINatives) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1940 // Stress register saving
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1941 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1942 save_or_restore_arguments(masm, stack_slots, total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1943 arg_save_area, map, in_regs, in_sig_bt);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1944 // Destroy argument registers
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1945 for (int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1946 if (in_regs[i].first()->is_Register()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1947 const Register reg = in_regs[i].first()->as_Register();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1948 if (reg->is_global()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1949 __ mov(G0, reg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1950 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1951 } else if (in_regs[i].first()->is_FloatRegister()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1952 __ fneg(FloatRegisterImpl::D, in_regs[i].first()->as_FloatRegister(), in_regs[i].first()->as_FloatRegister());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1953 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1954 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1955
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1956 save_or_restore_arguments(masm, stack_slots, total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1957 arg_save_area, NULL, in_regs, in_sig_bt);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1958 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1959 #endif
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1960 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1961
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1962 // Unpack an array argument into a pointer to the body and the length
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1963 // if the array is non-null, otherwise pass 0 for both.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1964 static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1965 // Pass the length, ptr pair
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1966 Label is_null, done;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1967 if (reg.first()->is_stack()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1968 VMRegPair tmp = reg64_to_VMRegPair(L2);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1969 // Load the arg up from the stack
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1970 move_ptr(masm, reg, tmp);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1971 reg = tmp;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1972 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1973 __ cmp(reg.first()->as_Register(), G0);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1974 __ brx(Assembler::equal, false, Assembler::pt, is_null);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1975 __ delayed()->add(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type), L4);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1976 move_ptr(masm, reg64_to_VMRegPair(L4), body_arg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1977 __ ld(reg.first()->as_Register(), arrayOopDesc::length_offset_in_bytes(), L4);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1978 move32_64(masm, reg64_to_VMRegPair(L4), length_arg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1979 __ ba_short(done);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1980 __ bind(is_null);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1981 // Pass zeros
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1982 move_ptr(masm, reg64_to_VMRegPair(G0), body_arg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1983 move32_64(masm, reg64_to_VMRegPair(G0), length_arg);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1984 __ bind(done);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1985 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
1986
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1987 static void verify_oop_args(MacroAssembler* masm,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1988 int total_args_passed,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1989 const BasicType* sig_bt,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1990 const VMRegPair* regs) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1991 Register temp_reg = G5_method; // not part of any compiled calling seq
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1992 if (VerifyOops) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1993 for (int i = 0; i < total_args_passed; i++) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1994 if (sig_bt[i] == T_OBJECT ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1995 sig_bt[i] == T_ARRAY) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1996 VMReg r = regs[i].first();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1997 assert(r->is_valid(), "bad oop arg");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1998 if (r->is_stack()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
1999 RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2000 ld_off = __ ensure_simm13_or_reg(ld_off, temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2001 __ ld_ptr(SP, ld_off, temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2002 __ verify_oop(temp_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2003 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2004 __ verify_oop(r->as_Register());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2005 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2006 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2007 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2008 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2009 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2010
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2011 static void gen_special_dispatch(MacroAssembler* masm,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2012 int total_args_passed,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2013 int comp_args_on_stack,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2014 vmIntrinsics::ID special_dispatch,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2015 const BasicType* sig_bt,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2016 const VMRegPair* regs) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2017 verify_oop_args(masm, total_args_passed, sig_bt, regs);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2018
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2019 // Now write the args into the outgoing interpreter space
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2020 bool has_receiver = false;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2021 Register receiver_reg = noreg;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2022 int member_arg_pos = -1;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2023 Register member_reg = noreg;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2024 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2025 if (ref_kind != 0) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2026 member_arg_pos = total_args_passed - 1; // trailing MemberName argument
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2027 member_reg = G5_method; // known to be free at this point
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2028 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2029 } else if (special_dispatch == vmIntrinsics::_invokeBasic) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2030 has_receiver = true;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2031 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2032 fatal(err_msg("special_dispatch=%d", special_dispatch));
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2033 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2034
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2035 if (member_reg != noreg) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2036 // Load the member_arg into register, if necessary.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2037 assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2038 assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2039 VMReg r = regs[member_arg_pos].first();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2040 assert(r->is_valid(), "bad member arg");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2041 if (r->is_stack()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2042 RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2043 ld_off = __ ensure_simm13_or_reg(ld_off, member_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2044 __ ld_ptr(SP, ld_off, member_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2045 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2046 // no data motion is needed
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2047 member_reg = r->as_Register();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2048 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2049 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2050
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2051 if (has_receiver) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2052 // Make sure the receiver is loaded into a register.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2053 assert(total_args_passed > 0, "oob");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2054 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2055 VMReg r = regs[0].first();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2056 assert(r->is_valid(), "bad receiver arg");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2057 if (r->is_stack()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2058 // Porting note: This assumes that compiled calling conventions always
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2059 // pass the receiver oop in a register. If this is not true on some
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2060 // platform, pick a temp and load the receiver from stack.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2061 assert(false, "receiver always in a register");
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2062 receiver_reg = G3_scratch; // known to be free at this point
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2063 RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2064 ld_off = __ ensure_simm13_or_reg(ld_off, member_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2065 __ ld_ptr(SP, ld_off, receiver_reg);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2066 } else {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2067 // no data motion is needed
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2068 receiver_reg = r->as_Register();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2069 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2070 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2071
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2072 // Figure out which address we are really jumping to:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2073 MethodHandles::generate_method_handle_dispatch(masm, special_dispatch,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2074 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2075 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2076
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 // Generate a native wrapper for a given method. The method takes arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // in the Java compiled code convention, marshals them to the native
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 // convention (handlizes oops, etc), transitions to native, makes the call,
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 // returns to java state (possibly blocking), unhandlizes any result and
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // returns.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2083 //
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2084 // Critical native functions are a shorthand for the use of
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2085 // GetPrimtiveArrayCritical and disallow the use of any other JNI
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2086 // functions. The wrapper is expected to unpack the arguments before
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2087 // passing them to the callee and perform checks before and after the
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2088 // native call to ensure that they GC_locker
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2089 // lock_critical/unlock_critical semantics are followed. Some other
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2090 // parts of JNI setup are skipped like the tear down of the JNI handle
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2091 // block and the check for pending exceptions it's impossible for them
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2092 // to be thrown.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2093 //
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2094 // They are roughly structured like this:
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2095 // if (GC_locker::needs_gc())
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2096 // SharedRuntime::block_for_jni_critical();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2097 // tranistion to thread_in_native
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2098 // unpack arrray arguments and call native entry point
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2099 // check for safepoint in progress
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2100 // check if any thread suspend flags are set
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2101 // call into JVM and possible unlock the JNI critical
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2102 // if a GC was suppressed while in the critical native.
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2103 // transition back to thread_in_Java
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2104 // return to caller
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2105 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 methodHandle method,
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 2177
diff changeset
2108 int compile_id,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 int total_in_args,
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 int comp_args_on_stack, // in VMRegStackSlots
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2111 BasicType* in_sig_bt,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2112 VMRegPair* in_regs,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 BasicType ret_type) {
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2114 if (method->is_method_handle_intrinsic()) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2115 vmIntrinsics::ID iid = method->intrinsic_id();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2116 intptr_t start = (intptr_t)__ pc();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2117 int vep_offset = ((intptr_t)__ pc()) - start;
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2118 gen_special_dispatch(masm,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2119 total_in_args,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2120 comp_args_on_stack,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2121 method->intrinsic_id(),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2122 in_sig_bt,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2123 in_regs);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2124 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2125 __ flush();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2126 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2127 return nmethod::new_native_nmethod(method,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2128 compile_id,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2129 masm->code(),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2130 vep_offset,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2131 frame_complete,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2132 stack_slots / VMRegImpl::slots_per_word,
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2133 in_ByteSize(-1),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2134 in_ByteSize(-1),
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2135 (OopMapSet*)NULL);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 5923
diff changeset
2136 }
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2137 bool is_critical_native = true;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2138 address native_func = method->critical_native_function();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2139 if (native_func == NULL) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2140 native_func = method->native_function();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2141 is_critical_native = false;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2142 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2143 assert(native_func != NULL, "must have function");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2144
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // Native nmethod wrappers never take possesion of the oop arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 // So the caller will gc the arguments. The only thing we need an
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 // oopMap for is if the call is static
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 // An OopMap for lock (and class if static), and one for the VM call itself
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 OopMapSet *oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 intptr_t start = (intptr_t)__ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2152
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 // First thing make an ic check to see if we should even be here
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 const Register temp_reg = G3_scratch;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2157 AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 __ verify_oop(O0);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2159 __ load_klass(O0, temp_reg);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
2160 __ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2161
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2162 __ jump_to(ic_miss, temp_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 __ align(CodeEntryAlignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2167
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 int vep_offset = ((intptr_t)__ pc()) - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2169
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 #ifdef COMPILER1
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 if (InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // Object.hashCode can pull the hashCode from the header word
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // instead of doing a full VM transition once it's been computed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 // Since hashCode is usually polymorphic at call sites we can't do
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 // this optimization at the call site without a lot of work.
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 Label slowCase;
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 Register receiver = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 Register result = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 Register header = G3_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 Register hash = G3_scratch; // overwrite header value with hash value
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 Register mask = G1; // to get hash field from header
a61af66fc99e Initial load
duke
parents:
diff changeset
2182
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // Read the header and build a mask to get its hash field. Give up if the object is not unlocked.
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // We depend on hash_mask being at most 32 bits and avoid the use of
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // vm: see markOop.hpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 __ ld_ptr(receiver, oopDesc::mark_offset_in_bytes(), header);
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 __ sethi(markOopDesc::hash_mask, mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 __ btst(markOopDesc::unlocked_value, header);
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 __ br(Assembler::zero, false, Assembler::pn, slowCase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // Check if biased and fall through to runtime if so
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 __ btst(markOopDesc::biased_lock_bit_in_place, header);
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 __ br(Assembler::notZero, false, Assembler::pn, slowCase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 __ delayed()->or3(mask, markOopDesc::hash_mask & 0x3ff, mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
2198
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // Check for a valid (non-zero) hash code and get its value.
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 __ srlx(header, markOopDesc::hash_shift, hash);
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 __ srl(header, markOopDesc::hash_shift, hash);
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 __ andcc(hash, mask, hash);
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 __ br(Assembler::equal, false, Assembler::pn, slowCase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2208
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 // leaf return.
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 __ delayed()->mov(hash, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 __ bind(slowCase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 #endif // COMPILER1
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 // We have received a description of where all the java arg are located
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // on entry to the wrapper. We need to convert these args to where
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // the jni function will expect them. To figure out where they go
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // we convert the java signature to a C signature by inserting
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // the hidden arguments as arg[0] and possibly arg[1] (static method)
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2223 int total_c_args = total_in_args;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2224 int total_save_slots = 6 * VMRegImpl::slots_per_word;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2225 if (!is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2226 total_c_args += 1;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2227 if (method->is_static()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2228 total_c_args++;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2229 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2230 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2231 for (int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2232 if (in_sig_bt[i] == T_ARRAY) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2233 // These have to be saved and restored across the safepoint
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2234 total_c_args++;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2235 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2236 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2238
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2240 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2241 BasicType* in_elem_bt = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 int argc = 0;
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2244 if (!is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2245 out_sig_bt[argc++] = T_ADDRESS;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2246 if (method->is_static()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2247 out_sig_bt[argc++] = T_OBJECT;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2248 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2249
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2250 for (int i = 0; i < total_in_args ; i++ ) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2251 out_sig_bt[argc++] = in_sig_bt[i];
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2252 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2253 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2254 Thread* THREAD = Thread::current();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2255 in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2256 SignatureStream ss(method->signature());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2257 for (int i = 0; i < total_in_args ; i++ ) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2258 if (in_sig_bt[i] == T_ARRAY) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2259 // Arrays are passed as int, elem* pair
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2260 out_sig_bt[argc++] = T_INT;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2261 out_sig_bt[argc++] = T_ADDRESS;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2262 Symbol* atype = ss.as_symbol(CHECK_NULL);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2263 const char* at = atype->as_C_string();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2264 if (strlen(at) == 2) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2265 assert(at[0] == '[', "must be");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2266 switch (at[1]) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2267 case 'B': in_elem_bt[i] = T_BYTE; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2268 case 'C': in_elem_bt[i] = T_CHAR; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2269 case 'D': in_elem_bt[i] = T_DOUBLE; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2270 case 'F': in_elem_bt[i] = T_FLOAT; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2271 case 'I': in_elem_bt[i] = T_INT; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2272 case 'J': in_elem_bt[i] = T_LONG; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2273 case 'S': in_elem_bt[i] = T_SHORT; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2274 case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2275 default: ShouldNotReachHere();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2276 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2277 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2278 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2279 out_sig_bt[argc++] = in_sig_bt[i];
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2280 in_elem_bt[i] = T_VOID;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2281 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2282 if (in_sig_bt[i] != T_VOID) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2283 assert(in_sig_bt[i] == ss.type(), "must match");
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2284 ss.next();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2285 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2286 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2288
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // Now figure out where the args must be stored and how much stack space
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // they require (neglecting out_preserve_stack_slots but space for storing
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // the 1st six register arguments). It's weird see int_stk_helper.
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 int out_arg_slots;
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args);
a61af66fc99e Initial load
duke
parents:
diff changeset
2295
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2296 if (is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2297 // Critical natives may have to call out so they need a save area
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2298 // for register arguments.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2299 int double_slots = 0;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2300 int single_slots = 0;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2301 for ( int i = 0; i < total_in_args; i++) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2302 if (in_regs[i].first()->is_Register()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2303 const Register reg = in_regs[i].first()->as_Register();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2304 switch (in_sig_bt[i]) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2305 case T_ARRAY:
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2306 case T_BOOLEAN:
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2307 case T_BYTE:
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2308 case T_SHORT:
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2309 case T_CHAR:
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2310 case T_INT: assert(reg->is_in(), "don't need to save these"); break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2311 case T_LONG: if (reg->is_global()) double_slots++; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2312 default: ShouldNotReachHere();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2313 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2314 } else if (in_regs[i].first()->is_FloatRegister()) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2315 switch (in_sig_bt[i]) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2316 case T_FLOAT: single_slots++; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2317 case T_DOUBLE: double_slots++; break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2318 default: ShouldNotReachHere();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2319 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2320 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2321 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2322 total_save_slots = double_slots * 2 + single_slots;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2323 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2324
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 // Compute framesize for the wrapper. We need to handlize all oops in
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 // registers. We must create space for them here that is disjoint from
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 // the windowed save area because we have no control over when we might
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // flush the window again and overwrite values that gc has since modified.
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 // (The live window race)
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 // We always just allocate 6 word for storing down these object. This allow
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 // us to simply record the base and use the Ireg number to decide which
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // slot to use. (Note that the reg number is the inbound number not the
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // outbound number).
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // We must shuffle args to match the native convention, and include var-args space.
a61af66fc99e Initial load
duke
parents:
diff changeset
2336
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 // Calculate the total number of stack slots we will need.
a61af66fc99e Initial load
duke
parents:
diff changeset
2338
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // First count the abi requirement plus all of the outgoing args
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
a61af66fc99e Initial load
duke
parents:
diff changeset
2341
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 // Now the space for the inbound oop handle area
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2344 int oop_handle_offset = round_to(stack_slots, 2);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2345 stack_slots += total_save_slots;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2346
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 // Now any space we need for handlizing a klass if static method
a61af66fc99e Initial load
duke
parents:
diff changeset
2348
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 int klass_slot_offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 int klass_offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 int lock_slot_offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 bool is_static = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2353
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 if (method->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 klass_slot_offset = stack_slots;
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 stack_slots += VMRegImpl::slots_per_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 klass_offset = klass_slot_offset * VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 is_static = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2360
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 // Plus a lock if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 if (method->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 lock_slot_offset = stack_slots;
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 stack_slots += VMRegImpl::slots_per_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2367
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 // Now a place to save return value or as a temporary for any gpr -> fpr moves
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 stack_slots += 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2370
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // Ok The space we have allocated will look like:
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 // FP-> | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 // |---------------------|
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 // | 2 slots for moves |
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 // |---------------------|
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // | lock box (if sync) |
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 // |---------------------| <- lock_slot_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 // | klass (if static) |
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // |---------------------| <- klass_slot_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // | oopHandle area |
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // |---------------------| <- oop_handle_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 // | outbound memory |
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // | based arguments |
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // |---------------------|
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // | vararg area |
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 // |---------------------|
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 // SP-> | out_preserved_slots |
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2394
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 // Now compute actual number of stack words we need rounding to make
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 // stack properly aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 stack_slots = round_to(stack_slots, 2 * VMRegImpl::slots_per_word);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 int stack_size = stack_slots * VMRegImpl::stack_slot_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2401
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 // Generate stack overflow check before creating frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 __ generate_stack_overflow_check(stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 // Generate a new frame for the wrapper.
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 __ save(SP, -stack_size, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
2407
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 int frame_complete = ((intptr_t)__ pc()) - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2409
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 __ verify_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
2411
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2412 if (is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2413 check_needs_gc_for_critical_native(masm, stack_slots, total_in_args,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2414 oop_handle_offset, oop_maps, in_regs, in_sig_bt);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2415 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2416
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 // We immediately shuffle the arguments so that any vm call we have to
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 // make from here on out (sync slow path, jvmti, etc.) we will have
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 // captured the oops from our caller and have a valid oopMap for
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 // them.
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // -----------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 // The Grand Shuffle
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv*
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // (derived from JavaThread* which is in L7_thread_cache) and, if static,
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 // the class mirror instead of a receiver. This pretty much guarantees that
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 // register layout will not match. We ignore these extra arguments during
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 // the shuffle. The shuffle is described by the two calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 // vectors we have in our possession. We simply walk the java vector to
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 // get the source locations and the c vector to get the destinations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 // Because we have a new window and the argument registers are completely
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 // disjoint ( I0 -> O1, I1 -> O2, ...) we have nothing to worry about
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 // here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2436
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 // This is a trick. We double the stack slots so we can claim
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 // the oops in the caller's frame. Since we are sure to have
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 // more args than the caller doubling is enough to make
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 // sure we can capture all the incoming oop args from the
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 // caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 // Record sp-based slot for receiver on stack for non-static methods
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 int receiver_offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2446
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 // We move the arguments backward because the floating point registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 // destination will always be to a register with a greater or equal register
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 // number or the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
2450
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 bool reg_destroyed[RegisterImpl::number_of_registers];
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 bool freg_destroyed[FloatRegisterImpl::number_of_registers];
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 reg_destroyed[r] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 freg_destroyed[f] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2460
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2463 for ( int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0 ; i--, c_arg-- ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2464
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 if (in_regs[i].first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "ack!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 } else if (in_regs[i].first()->is_FloatRegister()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 assert(!freg_destroyed[in_regs[i].first()->as_FloatRegister()->encoding(FloatRegisterImpl::S)], "ack!");
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 if (out_regs[c_arg].first()->is_Register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 } else if (out_regs[c_arg].first()->is_FloatRegister()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 freg_destroyed[out_regs[c_arg].first()->as_FloatRegister()->encoding(FloatRegisterImpl::S)] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
2477
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 switch (in_sig_bt[i]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 case T_ARRAY:
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2480 if (is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2481 unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg], out_regs[c_arg - 1]);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2482 c_arg--;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2483 break;
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2484 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 case T_OBJECT:
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2486 assert(!is_critical_native, "no oop arguments");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 ((i == 0) && (!is_static)),
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 &receiver_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 case T_VOID:
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2493
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 float_move(masm, in_regs[i], out_regs[c_arg]);
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2496 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2497
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 case T_DOUBLE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 assert( i + 1 < total_in_args &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 in_sig_bt[i + 1] == T_VOID &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 double_move(masm, in_regs[i], out_regs[c_arg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2504
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 case T_LONG :
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 long_move(masm, in_regs[i], out_regs[c_arg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2508
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
a61af66fc99e Initial load
duke
parents:
diff changeset
2510
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 move32_64(masm, in_regs[i], out_regs[c_arg]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2515
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 // Pre-load a static method's oop into O1. Used both by locking code and
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 // the normal JNI call code.
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2518 if (method->is_static() && !is_critical_native) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 __ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 // Now handlize the static class mirror in O1. It's known not-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 __ st_ptr(O1, SP, klass_offset + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 __ add(SP, klass_offset + STACK_BIAS, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526
a61af66fc99e Initial load
duke
parents:
diff changeset
2527
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 const Register L6_handle = L6;
a61af66fc99e Initial load
duke
parents:
diff changeset
2529
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 if (method->is_synchronized()) {
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2531 assert(!is_critical_native, "unhandled");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 __ mov(O1, L6_handle);
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 // We have all of the arguments setup at this point. We MUST NOT touch any Oregs
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 // except O6/O7. So if we must call out we must push a new frame. We immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 // push a new frame and flush the windows.
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 intptr_t thepc = (intptr_t) __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 address here = __ pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 // Call the next instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 __ call(here + 8, relocInfo::none);
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 intptr_t thepc = __ load_pc_address(O7, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2549
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 // We use the same pc/oopMap repeatedly when we call out
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 oop_maps->add_gc_map(thepc - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
2552
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 // O7 now has the pc loaded that we will use when we finally call to native.
a61af66fc99e Initial load
duke
parents:
diff changeset
2554
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 // Save thread in L7; it crosses a bunch of VM calls below
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 // Don't use save_thread because it smashes G2 and we merely
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // want to save a copy
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 __ mov(G2_thread, L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
a61af66fc99e Initial load
duke
parents:
diff changeset
2560
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // If we create an inner frame once is plenty
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // when we create it we must also save G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 bool inner_frame_created = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2564
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 // dtrace method entry support
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 SkipIfEqual skip_if(
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 masm, G3_scratch, &DTraceMethodProbes, Assembler::zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 // create inner frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 __ save_frame(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 __ mov(G2_thread, L7_thread_cache);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2572 __ set_metadata_constant(method(), O1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 __ call_VM_leaf(L7_thread_cache,
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 G2_thread, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2578
610
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2579 // RedefineClasses() tracing support for obsolete method entry
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2580 if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2581 // create inner frame
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2582 __ save_frame(0);
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2583 __ mov(G2_thread, L7_thread_cache);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2584 __ set_metadata_constant(method(), O1);
610
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2585 __ call_VM_leaf(L7_thread_cache,
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2586 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2587 G2_thread, O1);
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2588 __ restore();
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2589 }
70998f2e05ef 6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents: 362
diff changeset
2590
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 // We are in the jni frame unless saved_frame is true in which case
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 // we are in one frame deeper (the "inner" frame). If we are in the
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 // "inner" frames the args are in the Iregs and if the jni frame then
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 // they are in the Oregs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 // If we ever need to go to the VM (for locking, jvmti) then
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 // we will always be in the "inner" frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
2597
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 // Lock a synchronized method
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 int lock_offset = -1; // Set if locked
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 if (method->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 Register Roop = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 const Register L3_box = L3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2603
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 create_inner_frame(masm, &inner_frame_created);
a61af66fc99e Initial load
duke
parents:
diff changeset
2605
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 __ ld_ptr(I1, 0, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
2608
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 lock_offset = (lock_slot_offset * VMRegImpl::stack_slot_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 __ add(FP, lock_offset+STACK_BIAS, L3_box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 // making the box point to itself will make it clear it went unused
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 // but also be obviously invalid
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 __ st_ptr(L3_box, L3_box, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 // Compiler_lock_object (Roop, Rmark, Rbox, Rscratch) -- kills Rmark, Rbox, Rscratch
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 __ compiler_lock_object(Roop, L1, L3_box, L2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 __ br(Assembler::equal, false, Assembler::pt, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 __ delayed() -> add(FP, lock_offset+STACK_BIAS, L3_box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2624
a61af66fc99e Initial load
duke
parents:
diff changeset
2625
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 // None of the above fast optimizations worked so we have to get into the
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 // slow case of monitor enter. Inline a special case of call_VM that
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 // disallows any pending_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 __ mov(Roop, O0); // Need oop in O0
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 __ mov(L3_box, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2631
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 // Record last_Java_sp, in case the VM code releases the JVM lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
2633
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 __ set_last_Java_frame(FP, I7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2635
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 // do the call
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 __ delayed()->mov(L7_thread_cache, O2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2639
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 __ restore_thread(L7_thread_cache); // restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2642
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
2646 __ br_null_short(O0, Assembler::pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 __ stop("no pending exception allowed on exit from IR::monitorenter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2653
a61af66fc99e Initial load
duke
parents:
diff changeset
2654
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 // Finally just about ready to make the JNI call
a61af66fc99e Initial load
duke
parents:
diff changeset
2656
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 __ flush_windows();
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 if (inner_frame_created) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 // Store only what we need from this frame
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 // QQQ I think that non-v9 (like we care) we don't need these saves
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 // either as the flush traps and the current window goes too.
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 __ st_ptr(FP, SP, FP->sp_offset_in_saved_window()*wordSize + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 __ st_ptr(I7, SP, I7->sp_offset_in_saved_window()*wordSize + STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2667
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 // get JNIEnv* which is first argument to native
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2669 if (!is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2670 __ add(G2_thread, in_bytes(JavaThread::jni_environment_offset()), O0);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2671 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2672
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 // Use that pc we placed in O7 a while back as the current frame anchor
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 __ set_last_Java_frame(SP, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
2675
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2676 // We flushed the windows ages ago now mark them as flushed before transitioning.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2677 __ set(JavaFrameAnchor::flushed, G3_scratch);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2678 __ st(G3_scratch, G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2679
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 // Transition from _thread_in_Java to _thread_in_native.
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 __ set(_thread_in_native, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2682
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 #ifdef _LP64
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2684 AddressLiteral dest(native_func);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 __ relocate(relocInfo::runtime_call_type);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2686 __ jumpl_to(dest, O7, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 #else
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2688 __ call(native_func, relocInfo::runtime_call_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 #endif
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2690 __ delayed()->st(G3_scratch, G2_thread, JavaThread::thread_state_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2691
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 __ restore_thread(L7_thread_cache); // restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2693
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 // Unpack native results. For int-types, we do any needed sign-extension
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 // and move things into I0. The return value there will survive any VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // calls for blocking or unlocking. An FP or OOP result (handle) is done
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 // specially in the slow-path code.
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 switch (ret_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 case T_VOID: break; // Nothing to do!
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 case T_FLOAT: break; // Got it where we want it (unless slow-path)
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 case T_DOUBLE: break; // Got it where we want it (unless slow-path)
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // In 64 bits build result is in O0, in O0, O1 in 32bit build
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 __ mov(O1, I1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // Fall thru
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 case T_OBJECT: // Really a handle
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 case T_ARRAY:
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 __ mov(O0, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 case T_BOOLEAN: __ subcc(G0, O0, G0); __ addc(G0, 0, I0); break; // !0 => true; 0 => false
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 case T_BYTE : __ sll(O0, 24, O0); __ sra(O0, 24, I0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 case T_CHAR : __ sll(O0, 16, O0); __ srl(O0, 16, I0); break; // cannot use and3, 0xFFFF too big as immediate value!
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 case T_SHORT : __ sll(O0, 16, O0); __ sra(O0, 16, I0); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 break; // Cannot de-handlize until after reclaiming jvm_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2722 Label after_transition;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 // must we block?
a61af66fc99e Initial load
duke
parents:
diff changeset
2724
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 // Block, if necessary, before resuming in _thread_in_Java state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 // In order for GC to work, don't clear the last_Java_sp until after blocking.
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 { Label no_block;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2728 AddressLiteral sync_state(SafepointSynchronize::address_of_state());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2729
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 // Switch thread to "native transition" state before reading the synchronization state.
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 // This additional state is necessary because reading and testing the synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 // state is not atomic w.r.t. GC, as this scenario demonstrates:
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 // VM thread changes sync state to synchronizing and suspends threads for GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 // Thread A is resumed to finish this native method, but doesn't block here since it
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 // didn't see any synchronization is progress, and escapes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 __ set(_thread_in_native_trans, G3_scratch);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2738 __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 if(os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 if (UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 // Force this write out before the read below
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 __ membar(Assembler::StoreLoad);
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 // Write serialization page so VM thread can do a pseudo remote membar.
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // We use the current thread pointer to calculate a thread specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 // offset to write to within the page. This minimizes bus traffic
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 // due to cache line collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 __ serialize_memory(G2_thread, G1_scratch, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 __ load_contents(sync_state, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
a61af66fc99e Initial load
duke
parents:
diff changeset
2753
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 Label L;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2755 Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 __ br(Assembler::notEqual, false, Assembler::pn, L);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2757 __ delayed()->ld(suspend_state, G3_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
2758 __ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2760
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 // Block. Save any potential method result value before the operation and
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 // lets us share the oopMap we used when we went native rather the create
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 // a distinct one for this pc
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 save_native_result(masm, ret_type, stack_slots);
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2767 if (!is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2768 __ call_VM_leaf(L7_thread_cache,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2769 CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2770 G2_thread);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2771 } else {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2772 __ call_VM_leaf(L7_thread_cache,
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2773 CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition),
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2774 G2_thread);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2775 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2776
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 // Restore any method result value
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 restore_native_result(masm, ret_type, stack_slots);
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2779
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2780 if (is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2781 // The call above performed the transition to thread_in_Java so
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2782 // skip the transition logic below.
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2783 __ ba(after_transition);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2784 __ delayed()->nop();
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2785 }
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2786
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 __ bind(no_block);
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2789
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 // thread state is thread_in_native_trans. Any safepoint blocking has already
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 // happened so we can now change state to _thread_in_Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 __ set(_thread_in_Java, G3_scratch);
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2793 __ st(G3_scratch, G2_thread, JavaThread::thread_state_offset());
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2794 __ bind(after_transition);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2795
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 Label no_reguard;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
2797 __ ld(G2_thread, JavaThread::stack_guard_state_offset(), G3_scratch);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
2798 __ cmp_and_br_short(G3_scratch, JavaThread::stack_guard_yellow_disabled, Assembler::notEqual, Assembler::pt, no_reguard);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2799
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 save_native_result(masm, ret_type, stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages));
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2803
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 __ restore_thread(L7_thread_cache); // restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 restore_native_result(masm, ret_type, stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
2806
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 __ bind(no_reguard);
a61af66fc99e Initial load
duke
parents:
diff changeset
2808
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 // Handle possible exception (will unlock if necessary)
a61af66fc99e Initial load
duke
parents:
diff changeset
2810
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 // native result if any is live in freg or I0 (and I1 if long and 32bit vm)
a61af66fc99e Initial load
duke
parents:
diff changeset
2812
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // Unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 if (method->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 Label done;
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 Register I2_ex_oop = I2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 const Register L3_box = L3;
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 // Get locked oop from the handle we passed to jni
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 __ ld_ptr(L6_handle, 0, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 __ add(SP, lock_offset+STACK_BIAS, L3_box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 // Must save pending exception around the slow-path VM call. Since it's a
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 // leaf call, the pending exception (if any) can be kept in a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), I2_ex_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // Now unlock
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // (Roop, Rmark, Rbox, Rscratch)
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 __ compiler_unlock_object(L4, L1, L3_box, L2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 __ br(Assembler::equal, false, Assembler::pt, done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 __ delayed()-> add(SP, lock_offset+STACK_BIAS, L3_box);
a61af66fc99e Initial load
duke
parents:
diff changeset
2829
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 // save and restore any potential method result value around the unlocking
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 // operation. Will save in I0 (or stack for FP returns).
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 save_native_result(masm, ret_type, stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // Must clear pending-exception before re-entering the VM. Since this is
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // a leaf call, pending-exception-oop can be safely kept in a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 __ st_ptr(G0, G2_thread, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2837
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // slow case of monitor enter. Inline a special case of call_VM that
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 // disallows any pending_exception.
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 __ mov(L3_box, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2841
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 __ delayed()->mov(L4, O0); // Need oop in O0
a61af66fc99e Initial load
duke
parents:
diff changeset
2844
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 __ restore_thread(L7_thread_cache); // restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2846
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 { Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O0);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
2850 __ br_null_short(O0, Assembler::pt, L);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 __ stop("no pending exception allowed on exit from IR::monitorexit");
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 restore_native_result(masm, ret_type, stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 // check_forward_pending_exception jump to forward_exception if any pending
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 // exception is set. The forward_exception routine expects to see the
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 // exception in pending_exception and not in a register. Kind of clumsy,
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 // since all folks who branch to forward_exception must have tested
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 // pending_exception first and hence have it in a register already.
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 __ st_ptr(I2_ex_oop, G2_thread, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 __ bind(done);
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2864
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // Tell dtrace about this method exit
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 SkipIfEqual skip_if(
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 masm, G3_scratch, &DTraceMethodProbes, Assembler::zero);
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 save_native_result(masm, ret_type, stack_slots);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
2870 __ set_metadata_constant(method(), O1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 __ call_VM_leaf(L7_thread_cache,
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 G2_thread, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 restore_native_result(masm, ret_type, stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2876
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 // Clear "last Java frame" SP and PC.
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 __ verify_thread(); // G2_thread must be correct
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2880
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 // Unpack oop result
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 Label L;
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 __ addcc(G0, I0, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 __ brx(Assembler::notZero, true, Assembler::pt, L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 __ delayed()->ld_ptr(I0, 0, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 __ mov(G0, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 __ bind(L);
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 __ verify_oop(I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2891
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2892 if (!is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2893 // reset handle block
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2894 __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2895 __ st_ptr(G0, L5, JNIHandleBlock::top_offset_in_bytes());
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2896
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2897 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), G3_scratch);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2898 check_forward_pending_exception(masm, G3_scratch);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2899 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2900
a61af66fc99e Initial load
duke
parents:
diff changeset
2901
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 // Return
a61af66fc99e Initial load
duke
parents:
diff changeset
2903
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 if (ret_type == T_LONG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2906
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 // Must leave proper result in O0,O1 and G1 (c2/tiered only)
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 __ sllx(I0, 32, G1); // Shift bits into high G1
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 __ srl (I1, 0, I1); // Zero extend O1 (harmless?)
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 __ or3 (I1, G1, G1); // OR 64 bits into G1
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2913
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 __ ret();
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 __ delayed()->restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 __ flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
2918
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 nmethod *nm = nmethod::new_native_nmethod(method,
2405
3d58a4983660 7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents: 2177
diff changeset
2920 compile_id,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 masm->code(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 vep_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 frame_complete,
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 stack_slots / VMRegImpl::slots_per_word,
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)),
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 in_ByteSize(lock_offset),
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 oop_maps);
4873
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2928
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2929 if (is_critical_native) {
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2930 nm->set_lazy_critical_native(true);
0382d2b469b2 7013347: allow crypto functions to be called inline to enhance performance
never
parents: 4114
diff changeset
2931 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 return nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2933
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2935
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2936 #ifdef HAVE_DTRACE_H
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2937 // ---------------------------------------------------------------------------
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2938 // Generate a dtrace nmethod for a given signature. The method takes arguments
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2939 // in the Java compiled code convention, marshals them to the native
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2940 // abi and then leaves nops at the position you would expect to call a native
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2941 // function. When the probe is enabled the nops are replaced with a trap
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2942 // instruction that dtrace inserts and the trace will cause a notification
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2943 // to dtrace.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2944 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2945 // The probes are only able to take primitive types and java/lang/String as
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2946 // arguments. No other java types are allowed. Strings are converted to utf8
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2947 // strings so that from dtrace point of view java strings are converted to C
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2948 // strings. There is an arbitrary fixed limit on the total space that a method
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2949 // can use for converting the strings. (256 chars per string in the signature).
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2950 // So any java string larger then this is truncated.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2951
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2952 static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 };
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2953 static bool offsets_initialized = false;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2954
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2955 nmethod *SharedRuntime::generate_dtrace_nmethod(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2956 MacroAssembler *masm, methodHandle method) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2957
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2958
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2959 // generate_dtrace_nmethod is guarded by a mutex so we are sure to
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2960 // be single threaded in this method.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2961 assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2962
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2963 // Fill in the signature array, for the calling-convention call.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2964 int total_args_passed = method->size_of_parameters();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2965
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2966 BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2967 VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2968
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2969 // The signature we are going to use for the trap that dtrace will see
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2970 // java/lang/String is converted. We drop "this" and any other object
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2971 // is converted to NULL. (A one-slot java/lang/Long object reference
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2972 // is converted to a two-slot long, which is why we double the allocation).
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2973 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2974 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2975
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2976 int i=0;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2977 int total_strings = 0;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2978 int first_arg_to_pass = 0;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2979 int total_c_args = 0;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2980
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2981 // Skip the receiver as dtrace doesn't want to see it
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2982 if( !method->is_static() ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2983 in_sig_bt[i++] = T_OBJECT;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2984 first_arg_to_pass = 1;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2985 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2986
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2987 SignatureStream ss(method->signature());
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2988 for ( ; !ss.at_return_type(); ss.next()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2989 BasicType bt = ss.type();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2990 in_sig_bt[i++] = bt; // Collect remaining bits of signature
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2991 out_sig_bt[total_c_args++] = bt;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2992 if( bt == T_OBJECT) {
2177
3582bf76420e 6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents: 1972
diff changeset
2993 Symbol* s = ss.as_symbol_or_null();
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2994 if (s == vmSymbols::java_lang_String()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2995 total_strings++;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2996 out_sig_bt[total_c_args-1] = T_ADDRESS;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2997 } else if (s == vmSymbols::java_lang_Boolean() ||
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2998 s == vmSymbols::java_lang_Byte()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
2999 out_sig_bt[total_c_args-1] = T_BYTE;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3000 } else if (s == vmSymbols::java_lang_Character() ||
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3001 s == vmSymbols::java_lang_Short()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3002 out_sig_bt[total_c_args-1] = T_SHORT;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3003 } else if (s == vmSymbols::java_lang_Integer() ||
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3004 s == vmSymbols::java_lang_Float()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3005 out_sig_bt[total_c_args-1] = T_INT;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3006 } else if (s == vmSymbols::java_lang_Long() ||
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3007 s == vmSymbols::java_lang_Double()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3008 out_sig_bt[total_c_args-1] = T_LONG;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3009 out_sig_bt[total_c_args++] = T_VOID;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3010 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3011 } else if ( bt == T_LONG || bt == T_DOUBLE ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3012 in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3013 // We convert double to long
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3014 out_sig_bt[total_c_args-1] = T_LONG;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3015 out_sig_bt[total_c_args++] = T_VOID;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3016 } else if ( bt == T_FLOAT) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3017 // We convert float to int
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3018 out_sig_bt[total_c_args-1] = T_INT;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3019 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3020 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3021
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3022 assert(i==total_args_passed, "validly parsed signature");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3023
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3024 // Now get the compiled-Java layout as input arguments
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3025 int comp_args_on_stack;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3026 comp_args_on_stack = SharedRuntime::java_calling_convention(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3027 in_sig_bt, in_regs, total_args_passed, false);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3028
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3029 // We have received a description of where all the java arg are located
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3030 // on entry to the wrapper. We need to convert these args to where
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3031 // the a native (non-jni) function would expect them. To figure out
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3032 // where they go we convert the java signature to a C signature and remove
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3033 // T_VOID for any long/double we might have received.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3034
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3035
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3036 // Now figure out where the args must be stored and how much stack space
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3037 // they require (neglecting out_preserve_stack_slots but space for storing
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3038 // the 1st six register arguments). It's weird see int_stk_helper.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3039 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3040 int out_arg_slots;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3041 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3042
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3043 // Calculate the total number of stack slots we will need.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3044
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3045 // First count the abi requirement plus all of the outgoing args
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3046 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3047
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3048 // Plus a temp for possible converion of float/double/long register args
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3049
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3050 int conversion_temp = stack_slots;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3051 stack_slots += 2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3052
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3053
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3054 // Now space for the string(s) we must convert
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3055
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3056 int string_locs = stack_slots;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3057 stack_slots += total_strings *
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3058 (max_dtrace_string_size / VMRegImpl::stack_slot_size);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3059
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3060 // Ok The space we have allocated will look like:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3061 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3062 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3063 // FP-> | |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3064 // |---------------------|
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3065 // | string[n] |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3066 // |---------------------| <- string_locs[n]
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3067 // | string[n-1] |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3068 // |---------------------| <- string_locs[n-1]
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3069 // | ... |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3070 // | ... |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3071 // |---------------------| <- string_locs[1]
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3072 // | string[0] |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3073 // |---------------------| <- string_locs[0]
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3074 // | temp |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3075 // |---------------------| <- conversion_temp
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3076 // | outbound memory |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3077 // | based arguments |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3078 // | |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3079 // |---------------------|
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3080 // | |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3081 // SP-> | out_preserved_slots |
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3082 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3083 //
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3084
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3085 // Now compute actual number of stack words we need rounding to make
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3086 // stack properly aligned.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3087 stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3088
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3089 int stack_size = stack_slots * VMRegImpl::stack_slot_size;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3090
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3091 intptr_t start = (intptr_t)__ pc();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3092
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3093 // First thing make an ic check to see if we should even be here
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3094
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3095 {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3096 Label L;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3097 const Register temp_reg = G3_scratch;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3098 AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3099 __ verify_oop(O0);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3100 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3101 __ cmp_and_brx_short(temp_reg, G5_inline_cache_reg, Assembler::equal, Assembler::pt, L);
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3102
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3103 __ jump_to(ic_miss, temp_reg);
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3104 __ delayed()->nop();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3105 __ align(CodeEntryAlignment);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3106 __ bind(L);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3107 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3108
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3109 int vep_offset = ((intptr_t)__ pc()) - start;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3110
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3111
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3112 // The instruction at the verified entry point must be 5 bytes or longer
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3113 // because it can be patched on the fly by make_non_entrant. The stack bang
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3114 // instruction fits that requirement.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3115
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3116 // Generate stack overflow check before creating frame
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3117 __ generate_stack_overflow_check(stack_size);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3118
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3119 assert(((intptr_t)__ pc() - start - vep_offset) >= 5,
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3120 "valid size for make_non_entrant");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3121
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3122 // Generate a new frame for the wrapper.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3123 __ save(SP, -stack_size, SP);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3124
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3125 // Frame is now completed as far a size and linkage.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3126
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3127 int frame_complete = ((intptr_t)__ pc()) - start;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3128
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3129 #ifdef ASSERT
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3130 bool reg_destroyed[RegisterImpl::number_of_registers];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3131 bool freg_destroyed[FloatRegisterImpl::number_of_registers];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3132 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3133 reg_destroyed[r] = false;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3134 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3135 for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3136 freg_destroyed[f] = false;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3137 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3138
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3139 #endif /* ASSERT */
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3140
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3141 VMRegPair zero;
176
6b648fefb395 6705523: Fix for 6695506 will violate spec when used in JDK6
kamg
parents: 116
diff changeset
3142 const Register g0 = G0; // without this we get a compiler warning (why??)
6b648fefb395 6705523: Fix for 6695506 will violate spec when used in JDK6
kamg
parents: 116
diff changeset
3143 zero.set2(g0->as_VMReg());
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3144
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3145 int c_arg, j_arg;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3146
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3147 Register conversion_off = noreg;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3148
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3149 for (j_arg = first_arg_to_pass, c_arg = 0 ;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3150 j_arg < total_args_passed ; j_arg++, c_arg++ ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3151
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3152 VMRegPair src = in_regs[j_arg];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3153 VMRegPair dst = out_regs[c_arg];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3154
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3155 #ifdef ASSERT
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3156 if (src.first()->is_Register()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3157 assert(!reg_destroyed[src.first()->as_Register()->encoding()], "ack!");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3158 } else if (src.first()->is_FloatRegister()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3159 assert(!freg_destroyed[src.first()->as_FloatRegister()->encoding(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3160 FloatRegisterImpl::S)], "ack!");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3161 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3162 if (dst.first()->is_Register()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3163 reg_destroyed[dst.first()->as_Register()->encoding()] = true;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3164 } else if (dst.first()->is_FloatRegister()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3165 freg_destroyed[dst.first()->as_FloatRegister()->encoding(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3166 FloatRegisterImpl::S)] = true;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3167 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3168 #endif /* ASSERT */
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3169
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3170 switch (in_sig_bt[j_arg]) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3171 case T_ARRAY:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3172 case T_OBJECT:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3173 {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3174 if (out_sig_bt[c_arg] == T_BYTE || out_sig_bt[c_arg] == T_SHORT ||
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3175 out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3176 // need to unbox a one-slot value
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3177 Register in_reg = L0;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3178 Register tmp = L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3179 if ( src.first()->is_reg() ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3180 in_reg = src.first()->as_Register();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3181 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3182 assert(Assembler::is_simm13(reg2offset(src.first()) + STACK_BIAS),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3183 "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3184 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, in_reg);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3185 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3186 // If the final destination is an acceptable register
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3187 if ( dst.first()->is_reg() ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3188 if ( dst.is_single_phys_reg() || out_sig_bt[c_arg] != T_LONG ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3189 tmp = dst.first()->as_Register();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3190 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3191 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3192
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3193 Label skipUnbox;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3194 if ( wordSize == 4 && out_sig_bt[c_arg] == T_LONG ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3195 __ mov(G0, tmp->successor());
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3196 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3197 __ br_null(in_reg, true, Assembler::pn, skipUnbox);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3198 __ delayed()->mov(G0, tmp);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3199
165
437d03ea40b1 6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents: 116
diff changeset
3200 BasicType bt = out_sig_bt[c_arg];
437d03ea40b1 6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents: 116
diff changeset
3201 int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
437d03ea40b1 6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents: 116
diff changeset
3202 switch (bt) {
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3203 case T_BYTE:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3204 __ ldub(in_reg, box_offset, tmp); break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3205 case T_SHORT:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3206 __ lduh(in_reg, box_offset, tmp); break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3207 case T_INT:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3208 __ ld(in_reg, box_offset, tmp); break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3209 case T_LONG:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3210 __ ld_long(in_reg, box_offset, tmp); break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3211 default: ShouldNotReachHere();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3212 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3213
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3214 __ bind(skipUnbox);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3215 // If tmp wasn't final destination copy to final destination
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3216 if (tmp == L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3217 VMRegPair tmp_as_VM = reg64_to_VMRegPair(L2);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3218 if (out_sig_bt[c_arg] == T_LONG) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3219 long_move(masm, tmp_as_VM, dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3220 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3221 move32_64(masm, tmp_as_VM, out_regs[c_arg]);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3222 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3223 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3224 if (out_sig_bt[c_arg] == T_LONG) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3225 assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3226 ++c_arg; // move over the T_VOID to keep the loop indices in sync
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3227 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3228 } else if (out_sig_bt[c_arg] == T_ADDRESS) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3229 Register s =
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3230 src.first()->is_reg() ? src.first()->as_Register() : L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3231 Register d =
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3232 dst.first()->is_reg() ? dst.first()->as_Register() : L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3233
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3234 // We store the oop now so that the conversion pass can reach
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3235 // while in the inner frame. This will be the only store if
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3236 // the oop is NULL.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3237 if (s != L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3238 // src is register
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3239 if (d != L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3240 // dst is register
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3241 __ mov(s, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3242 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3243 assert(Assembler::is_simm13(reg2offset(dst.first()) +
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3244 STACK_BIAS), "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3245 __ st_ptr(s, SP, reg2offset(dst.first()) + STACK_BIAS);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3246 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3247 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3248 // src not a register
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3249 assert(Assembler::is_simm13(reg2offset(src.first()) +
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3250 STACK_BIAS), "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3251 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3252 if (d == L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3253 assert(Assembler::is_simm13(reg2offset(dst.first()) +
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3254 STACK_BIAS), "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3255 __ st_ptr(d, SP, reg2offset(dst.first()) + STACK_BIAS);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3256 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3257 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3258 } else if (out_sig_bt[c_arg] != T_VOID) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3259 // Convert the arg to NULL
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3260 if (dst.first()->is_reg()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3261 __ mov(G0, dst.first()->as_Register());
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3262 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3263 assert(Assembler::is_simm13(reg2offset(dst.first()) +
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3264 STACK_BIAS), "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3265 __ st_ptr(G0, SP, reg2offset(dst.first()) + STACK_BIAS);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3266 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3267 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3268 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3269 break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3270 case T_VOID:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3271 break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3272
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3273 case T_FLOAT:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3274 if (src.first()->is_stack()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3275 // Stack to stack/reg is simple
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3276 move32_64(masm, src, dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3277 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3278 if (dst.first()->is_reg()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3279 // freg -> reg
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3280 int off =
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3281 STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3282 Register d = dst.first()->as_Register();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3283 if (Assembler::is_simm13(off)) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3284 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3285 SP, off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3286 __ ld(SP, off, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3287 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3288 if (conversion_off == noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3289 __ set(off, L6);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3290 conversion_off = L6;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3291 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3292 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3293 SP, conversion_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3294 __ ld(SP, conversion_off , d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3295 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3296 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3297 // freg -> mem
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3298 int off = STACK_BIAS + reg2offset(dst.first());
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3299 if (Assembler::is_simm13(off)) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3300 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3301 SP, off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3302 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3303 if (conversion_off == noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3304 __ set(off, L6);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3305 conversion_off = L6;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3306 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3307 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3308 SP, conversion_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3309 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3310 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3311 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3312 break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3313
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3314 case T_DOUBLE:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3315 assert( j_arg + 1 < total_args_passed &&
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3316 in_sig_bt[j_arg + 1] == T_VOID &&
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3317 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3318 if (src.first()->is_stack()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3319 // Stack to stack/reg is simple
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3320 long_move(masm, src, dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3321 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3322 Register d = dst.first()->is_reg() ? dst.first()->as_Register() : L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3323
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3324 // Destination could be an odd reg on 32bit in which case
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3325 // we can't load direct to the destination.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3326
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3327 if (!d->is_even() && wordSize == 4) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3328 d = L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3329 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3330 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3331 if (Assembler::is_simm13(off)) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3332 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3333 SP, off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3334 __ ld_long(SP, off, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3335 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3336 if (conversion_off == noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3337 __ set(off, L6);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3338 conversion_off = L6;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3339 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3340 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3341 SP, conversion_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3342 __ ld_long(SP, conversion_off, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3343 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3344 if (d == L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3345 long_move(masm, reg64_to_VMRegPair(L2), dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3346 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3347 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3348 break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3349
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3350 case T_LONG :
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3351 // 32bit can't do a split move of something like g1 -> O0, O1
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3352 // so use a memory temp
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3353 if (src.is_single_phys_reg() && wordSize == 4) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3354 Register tmp = L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3355 if (dst.first()->is_reg() &&
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3356 (wordSize == 8 || dst.first()->as_Register()->is_even())) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3357 tmp = dst.first()->as_Register();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3358 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3359
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3360 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3361 if (Assembler::is_simm13(off)) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3362 __ stx(src.first()->as_Register(), SP, off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3363 __ ld_long(SP, off, tmp);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3364 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3365 if (conversion_off == noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3366 __ set(off, L6);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3367 conversion_off = L6;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3368 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3369 __ stx(src.first()->as_Register(), SP, conversion_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3370 __ ld_long(SP, conversion_off, tmp);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3371 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3372
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3373 if (tmp == L2) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3374 long_move(masm, reg64_to_VMRegPair(L2), dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3375 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3376 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3377 long_move(masm, src, dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3378 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3379 break;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3380
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3381 case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3382
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3383 default:
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3384 move32_64(masm, src, dst);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3385 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3386 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3387
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3388
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3389 // If we have any strings we must store any register based arg to the stack
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3390 // This includes any still live xmm registers too.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3391
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3392 if (total_strings > 0 ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3393
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3394 // protect all the arg registers
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3395 __ save_frame(0);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3396 __ mov(G2_thread, L7_thread_cache);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3397 const Register L2_string_off = L2;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3398
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3399 // Get first string offset
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3400 __ set(string_locs * VMRegImpl::stack_slot_size, L2_string_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3401
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3402 for (c_arg = 0 ; c_arg < total_c_args ; c_arg++ ) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3403 if (out_sig_bt[c_arg] == T_ADDRESS) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3404
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3405 VMRegPair dst = out_regs[c_arg];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3406 const Register d = dst.first()->is_reg() ?
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3407 dst.first()->as_Register()->after_save() : noreg;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3408
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3409 // It's a string the oop and it was already copied to the out arg
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3410 // position
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3411 if (d != noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3412 __ mov(d, O0);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3413 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3414 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3415 "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3416 __ ld_ptr(FP, reg2offset(dst.first()) + STACK_BIAS, O0);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3417 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3418 Label skip;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3419
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3420 __ br_null(O0, false, Assembler::pn, skip);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3421 __ delayed()->add(FP, L2_string_off, O1);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3422
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3423 if (d != noreg) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3424 __ mov(O1, d);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3425 } else {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3426 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3427 "must be");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3428 __ st_ptr(O1, FP, reg2offset(dst.first()) + STACK_BIAS);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3429 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3430
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3431 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::get_utf),
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3432 relocInfo::runtime_call_type);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3433 __ delayed()->add(L2_string_off, max_dtrace_string_size, L2_string_off);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3434
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3435 __ bind(skip);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3436
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3437 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3438
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3439 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3440 __ mov(L7_thread_cache, G2_thread);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3441 __ restore();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3442
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3443 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3444
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3445
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3446 // Ok now we are done. Need to place the nop that dtrace wants in order to
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3447 // patch in the trap
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3448
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3449 int patch_offset = ((intptr_t)__ pc()) - start;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3450
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3451 __ nop();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3452
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3453
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3454 // Return
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3455
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3456 __ ret();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3457 __ delayed()->restore();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3458
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3459 __ flush();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3460
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3461 nmethod *nm = nmethod::new_dtrace_nmethod(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3462 method, masm->code(), vep_offset, patch_offset, frame_complete,
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3463 stack_slots / VMRegImpl::slots_per_word);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3464 return nm;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3465
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3466 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3467
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3468 #endif // HAVE_DTRACE_H
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 113
diff changeset
3469
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 // this function returns the adjust size (in number of words) to a c2i adapter
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 // activation for use during deoptimization
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 assert(callee_locals >= callee_parameters,
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 "test and remove; got more parms than locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 if (callee_locals < callee_parameters)
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 return 0; // No adjustment for negative locals
1506
2338d41fbd81 6943304: remove tagged stack interpreter
twisti
parents: 1251
diff changeset
3477 int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 return round_to(diff, WordsPerLong);
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3480
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 // "Top of Stack" slots that may be unused by the calling convention but must
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 // otherwise be preserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 // On Intel these are not necessary and the value can be zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 // On Sparc this describes the words reserved for storing a register window
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 // when an interrupt occurs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 uint SharedRuntime::out_preserve_stack_slots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 return frame::register_save_words * VMRegImpl::slots_per_word;
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3489
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 static void gen_new_frame(MacroAssembler* masm, bool deopt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 // Common out the new frame generation for deopt and uncommon trap
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 Register G3pcs = G3_scratch; // Array of new pcs (input)
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 Register Oreturn0 = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 Register Oreturn1 = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 Register O2UnrollBlock = O2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 Register O3array = O3; // Array of frame sizes (input)
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 Register O4array_size = O4; // number of frames (input)
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 Register O7frame_size = O7; // number of frames (input)
a61af66fc99e Initial load
duke
parents:
diff changeset
3501
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 __ ld_ptr(O3array, 0, O7frame_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 __ sub(G0, O7frame_size, O7frame_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 __ save(SP, O7frame_size, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 __ ld_ptr(G3pcs, 0, I7); // load frame's new pc
a61af66fc99e Initial load
duke
parents:
diff changeset
3506
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 // make sure that the frames are aligned properly
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 __ btst(wordSize*2-1, SP);
5923
8a48c2906f91 7150046: SIGILL on sparcv9 fastdebug
coleenp
parents: 4957
diff changeset
3511 __ breakpoint_trap(Assembler::notZero, Assembler::ptr_cc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3514
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // Deopt needs to pass some extra live values from frame to frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3516
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 if (deopt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 __ mov(Oreturn0->after_save(), Oreturn0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 __ mov(Oreturn1->after_save(), Oreturn1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3521
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 __ mov(O4array_size->after_save(), O4array_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 __ sub(O4array_size, 1, O4array_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 __ mov(O3array->after_save(), O3array);
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 __ mov(O2UnrollBlock->after_save(), O2UnrollBlock);
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 __ add(G3pcs, wordSize, G3pcs); // point to next pc value
a61af66fc99e Initial load
duke
parents:
diff changeset
3527
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // trash registers to show a clear pattern in backtraces
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 __ set(0xDEAD0000, I0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 __ add(I0, 2, I1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 __ add(I0, 4, I2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 __ add(I0, 6, I3);
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 __ add(I0, 8, I4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 // Don't touch I5 could have valuable savedSP
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 __ set(0xDEADBEEF, L0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 __ mov(L0, L1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 __ mov(L0, L2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 __ mov(L0, L3);
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 __ mov(L0, L4);
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 __ mov(L0, L5);
a61af66fc99e Initial load
duke
parents:
diff changeset
3542
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 // trash the return value as there is nothing to return yet
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 __ set(0xDEAD0001, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3546
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 __ mov(SP, O5_savedSP);
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3549
a61af66fc99e Initial load
duke
parents:
diff changeset
3550
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 static void make_new_frames(MacroAssembler* masm, bool deopt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 // loop through the UnrollBlock info and create new frames
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 Register G3pcs = G3_scratch;
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 Register Oreturn0 = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 Register Oreturn1 = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 Register O2UnrollBlock = O2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 Register O3array = O3;
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 Register O4array_size = O4;
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 Label loop;
a61af66fc99e Initial load
duke
parents:
diff changeset
3562
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 // Before we make new frames, check to see if stack is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 // Do this after the caller's return address is on top of stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 if (UseStackBanging) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 // Get total frame size for interpreted frames
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3567 __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes(), O4);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 __ bang_stack_size(O4, O3, G3_scratch);
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3570
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3571 __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes(), O4array_size);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3572 __ ld_ptr(O2UnrollBlock, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes(), G3pcs);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3573 __ ld_ptr(O2UnrollBlock, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes(), O3array);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3574
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 // Adjust old interpreter frame to make space for new frame's extra java locals
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 // We capture the original sp for the transition frame only because it is needed in
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 // order to properly calculate interpreter_sp_adjustment. Even though in real life
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 // every interpreter frame captures a savedSP it is only needed at the transition
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 // (fortunately). If we had to have it correct everywhere then we would need to
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 // be told the sp_adjustment for each frame we create. If the frame size array
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 // were to have twice the frame count entries then we could have pairs [sp_adjustment, frame_size]
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 // for each frame we create and keep up the illusion every where.
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3585
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3586 __ ld(O2UnrollBlock, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes(), O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 __ mov(SP, O5_savedSP); // remember initial sender's original sp before adjustment
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 __ sub(SP, O7, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
3589
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 // make sure that there is at least one entry in the array
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 __ tst(O4array_size);
5923
8a48c2906f91 7150046: SIGILL on sparcv9 fastdebug
coleenp
parents: 4957
diff changeset
3593 __ breakpoint_trap(Assembler::zero, Assembler::icc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3595
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 // Now push the new interpreter frames
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 __ bind(loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 // allocate a new frame, filling the registers
a61af66fc99e Initial load
duke
parents:
diff changeset
3600
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 gen_new_frame(masm, deopt); // allocate an interpreter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3602
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3603 __ cmp_zero_and_br(Assembler::notZero, O4array_size, loop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 __ delayed()->add(O3array, wordSize, O3array);
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 __ ld_ptr(G3pcs, 0, O7); // load final frame new pc
a61af66fc99e Initial load
duke
parents:
diff changeset
3606
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3608
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 //------------------------------generate_deopt_blob----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 // Ought to generate an ideal graph & compile, but here's some SPARC ASM
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 // instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 void SharedRuntime::generate_deopt_blob() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 // allocate space for the code
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 // setup code generation tools
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code
4957
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3617 if (UseStackBanging) {
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3618 pad += StackShadowPages*16 + 32;
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3619 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 CodeBuffer buffer("deopt_blob", 2100+pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 // Measured 8/7/03 at 1212 in 32bit debug build (no VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 // Measured 8/7/03 at 1396 in 32bit debug build (VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 CodeBuffer buffer("deopt_blob", 1600+pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 MacroAssembler* masm = new MacroAssembler(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 FloatRegister Freturn0 = F0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 Register Greturn1 = G1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 Register Oreturn0 = O0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 Register Oreturn1 = O1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 Register O2UnrollBlock = O2;
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3633 Register L0deopt_mode = L0;
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3634 Register G4deopt_mode = G4_scratch;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 int frame_size_words;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3636 Address saved_Freturn0_addr(FP, -sizeof(double) + STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 #if !defined(_LP64) && defined(COMPILER2)
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3638 Address saved_Greturn1_addr(FP, -sizeof(double) -sizeof(jlong) + STACK_BIAS);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 Label cont;
a61af66fc99e Initial load
duke
parents:
diff changeset
3641
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 OopMapSet *oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
3643
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 // This is the entry point for code which is returning to a de-optimized
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 // The steps taken by this frame are as follows:
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // - push a dummy "register_save" and save the return values (O0, O1, F0/F1, G1)
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // and all potentially live registers (at a pollpoint many registers can be live).
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // - call the C routine: Deoptimization::fetch_unroll_info (this function
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 // returns information about the number and size of interpreter frames
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 // which are equivalent to the frame which is being deoptimized)
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 // - deallocate the unpack frame, restoring only results values. Other
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 // volatile registers will now be captured in the vframeArray as needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 // - deallocate the deoptimization frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 // - in a loop using the information returned in the previous step
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // push new interpreter frames (take care to propagate the return
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 // values through each new frame pushed)
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 // - create a dummy "unpack_frame" and save the return values (O0, O1, F0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 // - call the C routine: Deoptimization::unpack_frames (this function
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 // lays out values on the interpreter frame which was just created)
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 // - deallocate the dummy unpack_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // - ensure that all the return values are correctly set and then do
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 // a return to the interpreter entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // Refer to the following methods for more information:
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // - Deoptimization::fetch_unroll_info
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // - Deoptimization::unpack_frames
a61af66fc99e Initial load
duke
parents:
diff changeset
3670
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 OopMap* map = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3672
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 int start = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3674
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // restore G2, the trampoline destroyed it
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 __ get_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3677
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // On entry we have been called by the deoptimized nmethod with a call that
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // replaced the original call (or safepoint polling location) so the deoptimizing
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // pc is now in O7. Return values are still in the expected places
a61af66fc99e Initial load
duke
parents:
diff changeset
3681
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3683 __ ba(cont);
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3684 __ delayed()->mov(Deoptimization::Unpack_deopt, L0deopt_mode);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3685
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 int exception_offset = __ offset() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3687
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // restore G2, the trampoline destroyed it
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 __ get_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3690
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 // On entry we have been jumped to by the exception handler (or exception_blob
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // for server). O0 contains the exception oop and O7 contains the original
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 // exception pc. So if we push a frame here it will look to the
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 // stack walking code (fetch_unroll_info) just like a normal call so
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 // state will be extracted normally.
a61af66fc99e Initial load
duke
parents:
diff changeset
3696
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 // save exception oop in JavaThread and fall through into the
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 // exception_in_tls case since they are handled in same way except
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 // for where the pending exception is kept.
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3700 __ st_ptr(Oexception, G2_thread, JavaThread::exception_oop_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3701
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 // Vanilla deoptimization with an exception pending in exception_oop
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 int exception_in_tls_offset = __ offset() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3706
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // No need to update oop_map as each call to save_live_registers will produce identical oopmap
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
3709
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 // Restore G2_thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 __ get_thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3712
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 // verify that there is really an exception oop in exception_oop
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 Label has_exception;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3717 __ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3718 __ br_notnull_short(Oexception, Assembler::pt, has_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 __ stop("no exception in thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 __ bind(has_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
3721
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 // verify that there is no pending exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 Label no_pending_exception;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 710
diff changeset
3724 Address exception_addr(G2_thread, Thread::pending_exception_offset());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 __ ld_ptr(exception_addr, Oexception);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3726 __ br_null_short(Oexception, Assembler::pt, no_pending_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 __ stop("must not have pending exception here");
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 __ bind(no_pending_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3731
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3732 __ ba(cont);
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3733 __ delayed()->mov(Deoptimization::Unpack_exception, L0deopt_mode);;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3734
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 // Reexecute entry, similar to c2 uncommon trap
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 int reexecute_offset = __ offset() - start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3739
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 // No need to update oop_map as each call to save_live_registers will produce identical oopmap
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
3742
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3743 __ mov(Deoptimization::Unpack_reexecute, L0deopt_mode);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3744
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 __ bind(cont);
a61af66fc99e Initial load
duke
parents:
diff changeset
3746
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3748
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // do the call by hand so we can get the oopmap
a61af66fc99e Initial load
duke
parents:
diff changeset
3750
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 __ mov(G2_thread, L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 __ call(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info), relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 __ delayed()->mov(G2_thread, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3754
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 // Set an oopmap for the call site this describes all our saved volatile registers
a61af66fc99e Initial load
duke
parents:
diff changeset
3756
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 oop_maps->add_gc_map( __ offset()-start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
3758
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 __ mov(L7_thread_cache, G2_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3760
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3762
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 // so this move will survive
a61af66fc99e Initial load
duke
parents:
diff changeset
3765
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3766 __ mov(L0deopt_mode, G4deopt_mode);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3767
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 __ mov(O0, O2UnrollBlock->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3769
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 RegisterSaver::restore_result_registers(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
3771
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 Label noException;
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3773 __ cmp_and_br_short(G4deopt_mode, Deoptimization::Unpack_exception, Assembler::notEqual, Assembler::pt, noException);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3774
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 // Move the pending exception from exception_oop to Oexception so
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 // the pending exception will be picked up the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 __ ld_ptr(G2_thread, in_bytes(JavaThread::exception_oop_offset()), Oexception);
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 __ st_ptr(G0, G2_thread, in_bytes(JavaThread::exception_oop_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 __ bind(noException);
a61af66fc99e Initial load
duke
parents:
diff changeset
3780
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 // deallocate the deoptimization frame taking care to preserve the return values
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 __ mov(Oreturn0, Oreturn0->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 __ mov(Oreturn1, Oreturn1->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 __ mov(O2UnrollBlock, O2UnrollBlock->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3786
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 // Allocate new interpreter frame(s) and possible c2i adapter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3788
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 make_new_frames(masm, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3790
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 // push a dummy "unpack_frame" taking care of float return values and
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 // call Deoptimization::unpack_frames to have the unpacker layout
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 // information in the interpreter frames just created and then return
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 // to the interpreter entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 __ save(SP, -frame_size_words*wordSize, SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 __ stf(FloatRegisterImpl::D, Freturn0, saved_Freturn0_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 #if !defined(_LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 #if defined(COMPILER2)
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3799 // 32-bit 1-register longs return longs in G1
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3800 __ stx(Greturn1, saved_Greturn1_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 __ set_last_Java_frame(SP, noreg);
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3803 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, G4deopt_mode);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 // LP64 uses g4 in set_last_Java_frame
1037
0a46d0c5dccb 6891750: deopt blob kills values in O5
never
parents: 1007
diff changeset
3806 __ mov(G4deopt_mode, O1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 __ set_last_Java_frame(SP, G0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, O1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 __ ldf(FloatRegisterImpl::D, saved_Freturn0_addr, Freturn0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3812
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 #if !defined(_LP64) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 // In 32 bit, C2 returns longs in G1 so restore the saved G1 into
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3815 // I0/I1 if the return value is long.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3816 Label not_long;
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3817 __ cmp_and_br_short(O0,T_LONG, Assembler::notEqual, Assembler::pt, not_long);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3818 __ ldd(saved_Greturn1_addr,I0);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1579
diff changeset
3819 __ bind(not_long);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 __ ret();
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 __ delayed()->restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3823
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 masm->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3828
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
3830
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 //------------------------------generate_uncommon_trap_blob--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 // Ought to generate an ideal graph & compile, but here's some SPARC ASM
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 // instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 void SharedRuntime::generate_uncommon_trap_blob() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 // allocate space for the code
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 // setup code generation tools
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 int pad = VerifyThread ? 512 : 0;
4957
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3839 if (UseStackBanging) {
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3840 pad += StackShadowPages*16 + 32;
931e5f39e365 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c
kvn
parents: 4873
diff changeset
3841 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 CodeBuffer buffer("uncommon_trap_blob", 2700+pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 // Measured 8/7/03 at 660 in 32bit debug build (no VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 // Measured 8/7/03 at 1028 in 32bit debug build (VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 CodeBuffer buffer("uncommon_trap_blob", 2000+pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 MacroAssembler* masm = new MacroAssembler(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 Register O2UnrollBlock = O2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 Register O2klass_index = O2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3852
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 // This is the entry point for all traps the compiler takes when it thinks
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 // it cannot handle further execution of compilation code. The frame is
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 // deoptimized in these cases and converted into interpreter frames for
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 // execution
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 // The steps taken by this frame are as follows:
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 // - push a fake "unpack_frame"
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 // - call the C routine Deoptimization::uncommon_trap (this function
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 // packs the current compiled frame into vframe arrays and returns
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 // information about the number and size of interpreter frames which
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 // are equivalent to the frame which is being deoptimized)
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 // - deallocate the "unpack_frame"
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 // - deallocate the deoptimization frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 // - in a loop using the information returned in the previous step
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 // push interpreter frames;
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 // - create a dummy "unpack_frame"
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 // - call the C routine: Deoptimization::unpack_frames (this function
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 // lays out values on the interpreter frame which was just created)
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // - deallocate the dummy unpack_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 // - return to the interpreter entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 // Refer to the following methods for more information:
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 // - Deoptimization::uncommon_trap
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 // - Deoptimization::unpack_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3877
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 // the unloaded class index is in O0 (first parameter to this blob)
a61af66fc99e Initial load
duke
parents:
diff changeset
3879
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 // push a dummy "unpack_frame"
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 // and call Deoptimization::uncommon_trap to pack the compiled frame into
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 // vframe array and return the UnrollBlock information
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 __ save_frame(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 __ mov(I0, O2klass_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap), G2_thread, O2klass_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 __ mov(O0, O2UnrollBlock->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3890
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 // deallocate the deoptimized frame taking care to preserve the return values
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 __ mov(O2UnrollBlock, O2UnrollBlock->after_save());
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3894
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 // Allocate new interpreter frame(s) and possible c2i adapter frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3896
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 make_new_frames(masm, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3898
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 // push a dummy "unpack_frame" taking care of float return values and
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 // call Deoptimization::unpack_frames to have the unpacker layout
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 // information in the interpreter frames just created and then return
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 // to the interpreter entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 __ save_frame(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 __ mov(Deoptimization::Unpack_uncommon_trap, O3); // indicate it is the uncommon trap case
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 __ call_VM_leaf(L7_thread_cache, CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), G2_thread, O3);
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 __ ret();
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 __ delayed()->restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3910
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 masm->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, NULL, __ total_frame_size_in_bytes(0)/wordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3914
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 #endif // COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
3916
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 //------------------------------generate_handler_blob-------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 // Generate a special Compile2Runtime blob that saves all registers, and sets
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 // up an OopMap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 // This blob is jumped to (via a breakpoint and the signal handler) from a
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 // safepoint in compiled code. On entry to this blob, O7 contains the
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 // address in the original nmethod at which we should resume normal execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 // Thus, this blob looks like a subroutine which must preserve lots of
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 // registers and return normally. Note that O7 is never register-allocated,
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 // so it is guaranteed to be free here.
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3929
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 // The hardest part of what this blob must do is to save the 64-bit %o
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 // registers in the 32-bit build. A simple 'save' turn the %o's to %i's and
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 // an interrupt will chop off their heads. Making space in the caller's frame
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 // first will let us save the 64-bit %o's before save'ing, but we cannot hand
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 // the adjusted FP off to the GC stack-crawler: this will modify the caller's
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 // SP and mess up HIS OopMaps. So we first adjust the caller's SP, then save
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 // the 64-bit %o's, then do a save, then fixup the caller's SP (our FP).
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 // Tricky, tricky, tricky...
a61af66fc99e Initial load
duke
parents:
diff changeset
3938
3753
cba7b5c2d53f 7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents: 2405
diff changeset
3939 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
3941
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 // allocate space for the code
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 // setup code generation tools
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 // Measured 8/7/03 at 896 in 32bit debug build (no VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 // Measured 8/7/03 at 1080 in 32bit debug build (VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
3947 // even larger with TraceJumps
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 int pad = TraceJumps ? 512 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 CodeBuffer buffer("handler_blob", 1600 + pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 MacroAssembler* masm = new MacroAssembler(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 int frame_size_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 OopMapSet *oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 OopMap* map = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3954
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 int start = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3956
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 // If this causes a return before the processing, then do a "restore"
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 if (cause_return) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 __ restore();
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 // Make it look like we were called via the poll
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 // so that frame constructor always sees a valid return address
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 __ ld_ptr(G2_thread, in_bytes(JavaThread::saved_exception_pc_offset()), O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 __ sub(O7, frame::pc_return_offset, O7);
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3966
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
3968
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 // setup last_Java_sp (blows G4)
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3971
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 // call into the runtime to handle illegal instructions exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 // Do not use call_VM_leaf, because we need to make a GC map at this call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 __ mov(G2_thread, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 __ save_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 __ call(call_ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
3978
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 // Set an oopmap for the call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 // We need this not only for callee-saved registers, but also for volatile
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 // registers that the compiler might be keeping live across a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
3982
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 oop_maps->add_gc_map( __ offset() - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
3984
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 __ restore_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 // clear last_Java_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
3988
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 // Check for exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 Label pending;
a61af66fc99e Initial load
duke
parents:
diff changeset
3991
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
3993 __ br_notnull_short(O1, Assembler::pn, pending);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3994
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 RegisterSaver::restore_live_registers(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
3996
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 // We are back the the original state on entry and ready to go.
a61af66fc99e Initial load
duke
parents:
diff changeset
3998
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 __ retl();
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4001
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 // Pending exception after the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
4003
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 __ bind(pending);
a61af66fc99e Initial load
duke
parents:
diff changeset
4005
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 RegisterSaver::restore_live_registers(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
4007
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 // We are back the the original state on entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
4009
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 // Tail-call forward_exception_entry, with the issuing PC in O7,
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 // so it looks like the original nmethod called forward_exception_entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 __ set((intptr_t)StubRoutines::forward_exception_entry(), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 __ JMP(O0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4015
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 // make sure all code is generated
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 masm->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
4019
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 // return exception blob
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 return SafepointBlob::create(&buffer, oop_maps, frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4023
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 // generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 // Generate a stub that calls into vm to find out the proper destination
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 // of a java call. All the argument registers are live at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 // but since this is generic code we don't know what they are and the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 // must do any gc of the args.
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 //
3753
cba7b5c2d53f 7045514: SPARC assembly code for JSR 292 ricochet frames
never
parents: 2405
diff changeset
4032 RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
4034
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 // allocate space for the code
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 // setup code generation tools
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 // Measured 8/7/03 at 896 in 32bit debug build (no VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 // Measured 8/7/03 at 1080 in 32bit debug build (VerifyThread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 // even larger with TraceJumps
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 int pad = TraceJumps ? 512 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 CodeBuffer buffer(name, 1600 + pad, 512);
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 MacroAssembler* masm = new MacroAssembler(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 int frame_size_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 OopMapSet *oop_maps = new OopMapSet();
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 OopMap* map = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4047
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 int start = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4049
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
4051
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 int frame_complete = __ offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4053
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 // setup last_Java_sp (blows G4)
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 __ set_last_Java_frame(SP, noreg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4056
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 // call into the runtime to handle illegal instructions exception
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 // Do not use call_VM_leaf, because we need to make a GC map at this call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 __ mov(G2_thread, O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 __ save_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 __ call(destination, relocInfo::runtime_call_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4063
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 // O0 contains the address we are going to jump to assuming no exception got installed
a61af66fc99e Initial load
duke
parents:
diff changeset
4065
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 // Set an oopmap for the call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 // We need this not only for callee-saved registers, but also for volatile
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 // registers that the compiler might be keeping live across a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
4069
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 oop_maps->add_gc_map( __ offset() - start, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
4071
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 __ restore_thread(L7_thread_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 // clear last_Java_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 __ reset_last_Java_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
4075
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 // Check for exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
4077 Label pending;
a61af66fc99e Initial load
duke
parents:
diff changeset
4078
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 __ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 3753
diff changeset
4080 __ br_notnull_short(O1, Assembler::pn, pending);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4081
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
4082 // get the returned Method*
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
4083
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6266
diff changeset
4084 __ get_vm_result_2(G5_method);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 __ stx(G5_method, SP, RegisterSaver::G5_offset()+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
4086
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 // O0 is where we want to jump, overwrite G3 which is saved and scratch
a61af66fc99e Initial load
duke
parents:
diff changeset
4088
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 __ stx(O0, SP, RegisterSaver::G3_offset()+STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
4090
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 RegisterSaver::restore_live_registers(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
4092
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 // We are back the the original state on entry and ready to go.
a61af66fc99e Initial load
duke
parents:
diff changeset
4094
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 __ JMP(G3, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4097
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 // Pending exception after the safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
4099
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 __ bind(pending);
a61af66fc99e Initial load
duke
parents:
diff changeset
4101
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 RegisterSaver::restore_live_registers(masm);
a61af66fc99e Initial load
duke
parents:
diff changeset
4103
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 // We are back the the original state on entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
4105
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 // Tail-call forward_exception_entry, with the issuing PC in O7,
a61af66fc99e Initial load
duke
parents:
diff changeset
4107 // so it looks like the original nmethod called forward_exception_entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 __ set((intptr_t)StubRoutines::forward_exception_entry(), O0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 __ JMP(O0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 __ delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
4111
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 // -------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 // make sure all code is generated
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 masm->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
4115
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 // return the blob
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 // frame_size_words or bytes??
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 }