src/cpu/mips/vm/sharedRuntime_mips_64.cpp

Mon, 13 Mar 2017 01:52:16 -0400

author
fujie
date
Mon, 13 Mar 2017 01:52:16 -0400
changeset 375
fb7da68ac0c3
parent 373
3a34fc828b4a
child 376
030cb2764106
permissions
-rw-r--r--

[C2] For the reason of deopt, the size of call-instructions must be the same.

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #include "precompiled.hpp"
aoqi@1 27 #include "asm/macroAssembler.hpp"
aoqi@1 28 #include "asm/macroAssembler.inline.hpp"
aoqi@1 29 #include "code/debugInfoRec.hpp"
aoqi@1 30 #include "code/icBuffer.hpp"
aoqi@1 31 #include "code/vtableStubs.hpp"
aoqi@1 32 #include "interpreter/interpreter.hpp"
aoqi@1 33 #include "oops/compiledICHolder.hpp"
aoqi@1 34 #include "prims/jvmtiRedefineClassesTrace.hpp"
aoqi@1 35 #include "runtime/sharedRuntime.hpp"
aoqi@1 36 #include "runtime/vframeArray.hpp"
aoqi@1 37 #include "vmreg_mips.inline.hpp"
aoqi@1 38 #ifdef COMPILER1
aoqi@1 39 #include "c1/c1_Runtime1.hpp"
aoqi@1 40 #endif
aoqi@1 41 #ifdef COMPILER2
aoqi@1 42 #include "opto/runtime.hpp"
aoqi@1 43 #endif
aoqi@1 44
aoqi@1 45 #define __ masm->
aoqi@1 46 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
aoqi@1 47
aoqi@1 48 class RegisterSaver {
aoqi@1 49 enum { FPU_regs_live = 32 };
aoqi@1 50 // Capture info about frame layout
aoqi@1 51 enum layout {
aoqi@1 52 #define DEF_LAYOUT_OFFS(regname) regname ## _off, regname ## H_off,
aoqi@1 53 DEF_LAYOUT_OFFS(for_16_bytes_aligned)
aoqi@1 54 DEF_LAYOUT_OFFS(fpr0)
aoqi@1 55 DEF_LAYOUT_OFFS(fpr1)
aoqi@1 56 DEF_LAYOUT_OFFS(fpr2)
aoqi@1 57 DEF_LAYOUT_OFFS(fpr3)
aoqi@1 58 DEF_LAYOUT_OFFS(fpr4)
aoqi@1 59 DEF_LAYOUT_OFFS(fpr5)
aoqi@1 60 DEF_LAYOUT_OFFS(fpr6)
aoqi@1 61 DEF_LAYOUT_OFFS(fpr7)
aoqi@1 62 DEF_LAYOUT_OFFS(fpr8)
aoqi@1 63 DEF_LAYOUT_OFFS(fpr9)
aoqi@1 64 DEF_LAYOUT_OFFS(fpr10)
aoqi@1 65 DEF_LAYOUT_OFFS(fpr11)
aoqi@1 66 DEF_LAYOUT_OFFS(fpr12)
aoqi@1 67 DEF_LAYOUT_OFFS(fpr13)
aoqi@1 68 DEF_LAYOUT_OFFS(fpr14)
aoqi@1 69 DEF_LAYOUT_OFFS(fpr15)
aoqi@1 70 DEF_LAYOUT_OFFS(fpr16)
aoqi@1 71 DEF_LAYOUT_OFFS(fpr17)
aoqi@1 72 DEF_LAYOUT_OFFS(fpr18)
aoqi@1 73 DEF_LAYOUT_OFFS(fpr19)
aoqi@1 74 DEF_LAYOUT_OFFS(fpr20)
aoqi@1 75 DEF_LAYOUT_OFFS(fpr21)
aoqi@1 76 DEF_LAYOUT_OFFS(fpr22)
aoqi@1 77 DEF_LAYOUT_OFFS(fpr23)
aoqi@1 78 DEF_LAYOUT_OFFS(fpr24)
aoqi@1 79 DEF_LAYOUT_OFFS(fpr25)
aoqi@1 80 DEF_LAYOUT_OFFS(fpr26)
aoqi@1 81 DEF_LAYOUT_OFFS(fpr27)
aoqi@1 82 DEF_LAYOUT_OFFS(fpr28)
aoqi@1 83 DEF_LAYOUT_OFFS(fpr29)
aoqi@1 84 DEF_LAYOUT_OFFS(fpr30)
aoqi@1 85 DEF_LAYOUT_OFFS(fpr31)
aoqi@1 86
aoqi@1 87 DEF_LAYOUT_OFFS(v0)
aoqi@1 88 DEF_LAYOUT_OFFS(v1)
aoqi@1 89 DEF_LAYOUT_OFFS(a0)
aoqi@1 90 DEF_LAYOUT_OFFS(a1)
aoqi@1 91 DEF_LAYOUT_OFFS(a2)
aoqi@1 92 DEF_LAYOUT_OFFS(a3)
aoqi@1 93 DEF_LAYOUT_OFFS(a4)
aoqi@1 94 DEF_LAYOUT_OFFS(a5)
aoqi@1 95 DEF_LAYOUT_OFFS(a6)
aoqi@1 96 DEF_LAYOUT_OFFS(a7)
aoqi@1 97 DEF_LAYOUT_OFFS(t0)
aoqi@1 98 DEF_LAYOUT_OFFS(t1)
aoqi@1 99 DEF_LAYOUT_OFFS(t2)
aoqi@1 100 DEF_LAYOUT_OFFS(t3)
aoqi@1 101 DEF_LAYOUT_OFFS(s0)
aoqi@1 102 DEF_LAYOUT_OFFS(s1)
aoqi@1 103 DEF_LAYOUT_OFFS(s2)
aoqi@1 104 DEF_LAYOUT_OFFS(s3)
aoqi@1 105 DEF_LAYOUT_OFFS(s4)
aoqi@1 106 DEF_LAYOUT_OFFS(s5)
aoqi@1 107 DEF_LAYOUT_OFFS(s6)
aoqi@1 108 DEF_LAYOUT_OFFS(s7)
aoqi@1 109 DEF_LAYOUT_OFFS(t8)
aoqi@1 110 DEF_LAYOUT_OFFS(t9)
aoqi@1 111
aoqi@1 112 DEF_LAYOUT_OFFS(gp)
aoqi@1 113 DEF_LAYOUT_OFFS(fp)
aoqi@1 114 DEF_LAYOUT_OFFS(return)
aoqi@1 115 /*
aoqi@1 116 fpr0_off, fpr1_off,
aoqi@1 117 fpr2_off, fpr3_off,
aoqi@1 118 fpr4_off, fpr5_off,
aoqi@1 119 fpr6_off, fpr7_off,
aoqi@1 120 fpr8_off, fpr9_off,
aoqi@1 121 fpr10_off, fpr11_off,
aoqi@1 122 fpr12_off, fpr13_off,
aoqi@1 123 fpr14_off, fpr15_off,
aoqi@1 124 fpr16_off, fpr17_off,
aoqi@1 125 fpr18_off, fpr19_off,
aoqi@1 126 fpr20_off, fpr21_off,
aoqi@1 127 fpr22_off, fpr23_off,
aoqi@1 128 fpr24_off, fpr25_off,
aoqi@1 129 fpr26_off, fpr27_off,
aoqi@1 130 fpr28_off, fpr29_off,
aoqi@1 131 fpr30_off, fpr31_off,
aoqi@1 132
aoqi@1 133 v0_off, v1_off,
aoqi@1 134 a0_off, a1_off,
aoqi@1 135 a2_off, a3_off,
aoqi@1 136 a4_off, a5_off,
aoqi@1 137 a6_off, a7_off,
aoqi@1 138 t0_off, t1_off, t2_off, t3_off,
aoqi@1 139 s0_off, s1_off, s2_off, s3_off, s4_off, s5_off, s6_off, s7_off,
aoqi@1 140 t8_off, t9_off,
aoqi@1 141
aoqi@1 142 gp_off, fp_off,
aoqi@1 143 return_off,
aoqi@1 144 */
aoqi@1 145 reg_save_size
aoqi@1 146 };
aoqi@1 147
aoqi@1 148 public:
aoqi@1 149
aoqi@1 150 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors =false );
aoqi@1 151 static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
aoqi@1 152 //FIXME, I have no idea which register to use
aoqi@1 153 static int raOffset(void) { return return_off / 2; }
aoqi@1 154 //Rmethod
aoqi@1 155 static int methodOffset(void) { return s3_off / 2; }
aoqi@1 156
aoqi@1 157 static int v0Offset(void) { return v0_off / 2; }
aoqi@1 158 static int v1Offset(void) { return v1_off / 2; }
aoqi@1 159
aoqi@1 160 static int fpResultOffset(void) { return fpr0_off / 2; }
aoqi@1 161
aoqi@1 162 // During deoptimization only the result register need to be restored
aoqi@1 163 // all the other values have already been extracted.
aoqi@1 164
aoqi@1 165 static void restore_result_registers(MacroAssembler* masm);
aoqi@1 166 };
aoqi@1 167
aoqi@1 168 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors ) {
aoqi@1 169
aoqi@1 170 /*
aoqi@1 171 int frame_words = reg_save_size + additional_frame_words;
aoqi@1 172 int frame_size_in_bytes = frame_words * wordSize;
aoqi@1 173 *total_frame_words = frame_words;
aoqi@1 174 */
aoqi@1 175 // Always make the frame size 16-byte aligned
aoqi@1 176 int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
aoqi@1 177 reg_save_size*BytesPerInt, 16);
aoqi@1 178 // OopMap frame size is in compiler stack slots (jint's) not bytes or words
aoqi@1 179 int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
aoqi@1 180 // The caller will allocate additional_frame_words
aoqi@1 181 int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt;
aoqi@1 182 // CodeBlob frame size is in words.
aoqi@1 183 int frame_size_in_words = frame_size_in_bytes / wordSize;
aoqi@1 184 *total_frame_words = frame_size_in_words;
aoqi@1 185
aoqi@1 186 // save registers, fpu state, and flags
aoqi@1 187 // We assume caller has already has return address slot on the stack
aoqi@1 188 // We push epb twice in this sequence because we want the real ebp
aoqi@1 189 // to be under the return like a normal enter and we want to use pushad
aoqi@1 190 // We push by hand instead of pusing push
aoqi@1 191
aoqi@1 192 __ daddiu(SP, SP, - reg_save_size * jintSize);
aoqi@1 193
aoqi@1 194 __ sdc1(F0, SP, fpr0_off * jintSize); __ sdc1(F1, SP, fpr1_off * jintSize);
aoqi@1 195 __ sdc1(F2, SP, fpr2_off * jintSize); __ sdc1(F3, SP, fpr3_off * jintSize);
aoqi@1 196 __ sdc1(F4, SP, fpr4_off * jintSize); __ sdc1(F5, SP, fpr5_off * jintSize);
aoqi@1 197 __ sdc1(F6, SP, fpr6_off * jintSize); __ sdc1(F7, SP, fpr7_off * jintSize);
aoqi@1 198 __ sdc1(F8, SP, fpr8_off * jintSize); __ sdc1(F9, SP, fpr9_off * jintSize);
aoqi@1 199 __ sdc1(F10, SP, fpr10_off * jintSize); __ sdc1(F11, SP, fpr11_off * jintSize);
aoqi@1 200 __ sdc1(F12, SP, fpr12_off * jintSize); __ sdc1(F13, SP, fpr13_off * jintSize);
aoqi@1 201 __ sdc1(F14, SP, fpr14_off * jintSize); __ sdc1(F15, SP, fpr15_off * jintSize);
aoqi@1 202 __ sdc1(F16, SP, fpr16_off * jintSize); __ sdc1(F17, SP, fpr17_off * jintSize);
aoqi@1 203 __ sdc1(F18, SP, fpr18_off * jintSize); __ sdc1(F19, SP, fpr19_off * jintSize);
aoqi@1 204 __ sdc1(F20, SP, fpr20_off * jintSize); __ sdc1(F21, SP, fpr21_off * jintSize);
aoqi@1 205 __ sdc1(F22, SP, fpr22_off * jintSize); __ sdc1(F23, SP, fpr23_off * jintSize);
aoqi@1 206 __ sdc1(F24, SP, fpr24_off * jintSize); __ sdc1(F25, SP, fpr25_off * jintSize);
aoqi@1 207 __ sdc1(F26, SP, fpr26_off * jintSize); __ sdc1(F27, SP, fpr27_off * jintSize);
aoqi@1 208 __ sdc1(F28, SP, fpr28_off * jintSize); __ sdc1(F29, SP, fpr29_off * jintSize);
aoqi@1 209 __ sdc1(F30, SP, fpr30_off * jintSize); __ sdc1(F31, SP, fpr31_off * jintSize);
aoqi@1 210 __ sd(V0, SP, v0_off * jintSize); __ sd(V1, SP, v1_off * jintSize);
aoqi@1 211 __ sd(A0, SP, a0_off * jintSize); __ sd(A1, SP, a1_off * jintSize);
aoqi@1 212 __ sd(A2, SP, a2_off * jintSize); __ sd(A3, SP, a3_off * jintSize);
aoqi@1 213 __ sd(A4, SP, a4_off * jintSize); __ sd(A5, SP, a5_off * jintSize);
aoqi@1 214 __ sd(A6, SP, a6_off * jintSize); __ sd(A7, SP, a7_off * jintSize);
aoqi@1 215 __ sd(T0, SP, t0_off * jintSize);
aoqi@1 216 __ sd(T1, SP, t1_off * jintSize);
aoqi@1 217 __ sd(T2, SP, t2_off * jintSize);
aoqi@1 218 __ sd(T3, SP, t3_off * jintSize);
aoqi@1 219 __ sd(S0, SP, s0_off * jintSize);
aoqi@1 220 __ sd(S1, SP, s1_off * jintSize);
aoqi@1 221 __ sd(S2, SP, s2_off * jintSize);
aoqi@1 222 __ sd(S3, SP, s3_off * jintSize);
aoqi@1 223 __ sd(S4, SP, s4_off * jintSize);
aoqi@1 224 __ sd(S5, SP, s5_off * jintSize);
aoqi@1 225 __ sd(S6, SP, s6_off * jintSize);
aoqi@1 226 __ sd(S7, SP, s7_off * jintSize);
aoqi@1 227
aoqi@1 228 __ sd(T8, SP, t8_off * jintSize);
aoqi@1 229 __ sd(T9, SP, t9_off * jintSize);
aoqi@1 230
aoqi@1 231 __ sd(GP, SP, gp_off * jintSize);
aoqi@1 232 __ sd(FP, SP, fp_off * jintSize);
aoqi@1 233 __ sd(RA, SP, return_off * jintSize);
aoqi@1 234 __ daddi(FP, SP, fp_off * jintSize);
aoqi@1 235
aoqi@1 236 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 237 //OopMap* map = new OopMap( frame_words, 0 );
aoqi@1 238 OopMap* map = new OopMap( frame_size_in_slots, 0 );
aoqi@1 239
aoqi@1 240
aoqi@1 241 //#define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words)
aoqi@1 242 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots)
aoqi@1 243 map->set_callee_saved(STACK_OFFSET( v0_off), V0->as_VMReg());
aoqi@1 244 map->set_callee_saved(STACK_OFFSET( v1_off), V1->as_VMReg());
aoqi@1 245 map->set_callee_saved(STACK_OFFSET( a0_off), A0->as_VMReg());
aoqi@1 246 map->set_callee_saved(STACK_OFFSET( a1_off), A1->as_VMReg());
aoqi@1 247 map->set_callee_saved(STACK_OFFSET( a2_off), A2->as_VMReg());
aoqi@1 248 map->set_callee_saved(STACK_OFFSET( a3_off), A3->as_VMReg());
aoqi@1 249 map->set_callee_saved(STACK_OFFSET( a4_off), A4->as_VMReg());
aoqi@1 250 map->set_callee_saved(STACK_OFFSET( a5_off), A5->as_VMReg());
aoqi@1 251 map->set_callee_saved(STACK_OFFSET( a6_off), A6->as_VMReg());
aoqi@1 252 map->set_callee_saved(STACK_OFFSET( a7_off), A7->as_VMReg());
aoqi@1 253 map->set_callee_saved(STACK_OFFSET( t0_off), T0->as_VMReg());
aoqi@1 254 map->set_callee_saved(STACK_OFFSET( t1_off), T1->as_VMReg());
aoqi@1 255 map->set_callee_saved(STACK_OFFSET( t2_off), T2->as_VMReg());
aoqi@1 256 map->set_callee_saved(STACK_OFFSET( t3_off), T3->as_VMReg());
aoqi@1 257 map->set_callee_saved(STACK_OFFSET( s0_off), S0->as_VMReg());
aoqi@1 258 map->set_callee_saved(STACK_OFFSET( s1_off), S1->as_VMReg());
aoqi@1 259 map->set_callee_saved(STACK_OFFSET( s2_off), S2->as_VMReg());
aoqi@1 260 map->set_callee_saved(STACK_OFFSET( s3_off), S3->as_VMReg());
aoqi@1 261 map->set_callee_saved(STACK_OFFSET( s4_off), S4->as_VMReg());
aoqi@1 262 map->set_callee_saved(STACK_OFFSET( s5_off), S5->as_VMReg());
aoqi@1 263 map->set_callee_saved(STACK_OFFSET( s6_off), S6->as_VMReg());
aoqi@1 264 map->set_callee_saved(STACK_OFFSET( s7_off), S7->as_VMReg());
aoqi@1 265 map->set_callee_saved(STACK_OFFSET( t8_off), T8->as_VMReg());
aoqi@1 266 map->set_callee_saved(STACK_OFFSET( t9_off), T9->as_VMReg());
aoqi@1 267 map->set_callee_saved(STACK_OFFSET( gp_off), GP->as_VMReg());
aoqi@1 268 map->set_callee_saved(STACK_OFFSET( fp_off), FP->as_VMReg());
aoqi@1 269 map->set_callee_saved(STACK_OFFSET( return_off), RA->as_VMReg());
aoqi@1 270
aoqi@1 271 map->set_callee_saved(STACK_OFFSET( fpr0_off), F0->as_VMReg());
aoqi@1 272 map->set_callee_saved(STACK_OFFSET( fpr1_off), F1->as_VMReg());
aoqi@1 273 map->set_callee_saved(STACK_OFFSET( fpr2_off), F2->as_VMReg());
aoqi@1 274 map->set_callee_saved(STACK_OFFSET( fpr3_off), F3->as_VMReg());
aoqi@1 275 map->set_callee_saved(STACK_OFFSET( fpr4_off), F4->as_VMReg());
aoqi@1 276 map->set_callee_saved(STACK_OFFSET( fpr5_off), F5->as_VMReg());
aoqi@1 277 map->set_callee_saved(STACK_OFFSET( fpr6_off), F6->as_VMReg());
aoqi@1 278 map->set_callee_saved(STACK_OFFSET( fpr7_off), F7->as_VMReg());
aoqi@1 279 map->set_callee_saved(STACK_OFFSET( fpr8_off), F8->as_VMReg());
aoqi@1 280 map->set_callee_saved(STACK_OFFSET( fpr9_off), F9->as_VMReg());
aoqi@1 281 map->set_callee_saved(STACK_OFFSET( fpr10_off), F10->as_VMReg());
aoqi@1 282 map->set_callee_saved(STACK_OFFSET( fpr11_off), F11->as_VMReg());
aoqi@1 283 map->set_callee_saved(STACK_OFFSET( fpr12_off), F12->as_VMReg());
aoqi@1 284 map->set_callee_saved(STACK_OFFSET( fpr13_off), F13->as_VMReg());
aoqi@1 285 map->set_callee_saved(STACK_OFFSET( fpr14_off), F14->as_VMReg());
aoqi@1 286 map->set_callee_saved(STACK_OFFSET( fpr15_off), F15->as_VMReg());
aoqi@1 287 map->set_callee_saved(STACK_OFFSET( fpr16_off), F16->as_VMReg());
aoqi@1 288 map->set_callee_saved(STACK_OFFSET( fpr17_off), F17->as_VMReg());
aoqi@1 289 map->set_callee_saved(STACK_OFFSET( fpr18_off), F18->as_VMReg());
aoqi@1 290 map->set_callee_saved(STACK_OFFSET( fpr19_off), F19->as_VMReg());
aoqi@1 291 map->set_callee_saved(STACK_OFFSET( fpr20_off), F20->as_VMReg());
aoqi@1 292 map->set_callee_saved(STACK_OFFSET( fpr21_off), F21->as_VMReg());
aoqi@1 293 map->set_callee_saved(STACK_OFFSET( fpr22_off), F22->as_VMReg());
aoqi@1 294 map->set_callee_saved(STACK_OFFSET( fpr23_off), F23->as_VMReg());
aoqi@1 295 map->set_callee_saved(STACK_OFFSET( fpr24_off), F24->as_VMReg());
aoqi@1 296 map->set_callee_saved(STACK_OFFSET( fpr25_off), F25->as_VMReg());
aoqi@1 297 map->set_callee_saved(STACK_OFFSET( fpr26_off), F26->as_VMReg());
aoqi@1 298 map->set_callee_saved(STACK_OFFSET( fpr27_off), F27->as_VMReg());
aoqi@1 299 map->set_callee_saved(STACK_OFFSET( fpr28_off), F28->as_VMReg());
aoqi@1 300 map->set_callee_saved(STACK_OFFSET( fpr29_off), F29->as_VMReg());
aoqi@1 301 map->set_callee_saved(STACK_OFFSET( fpr30_off), F30->as_VMReg());
aoqi@1 302 map->set_callee_saved(STACK_OFFSET( fpr31_off), F31->as_VMReg());
aoqi@1 303
aoqi@1 304 /*
aoqi@1 305 if (true) {
aoqi@1 306 map->set_callee_saved(STACK_OFFSET( v0H_off), V0->as_VMReg()->next());
aoqi@1 307 map->set_callee_saved(STACK_OFFSET( v1H_off), V1->as_VMReg()->next());
aoqi@1 308 map->set_callee_saved(STACK_OFFSET( a0H_off), A0->as_VMReg()->next());
aoqi@1 309 map->set_callee_saved(STACK_OFFSET( a1H_off), A1->as_VMReg()->next());
aoqi@1 310 map->set_callee_saved(STACK_OFFSET( a2H_off), A2->as_VMReg()->next());
aoqi@1 311 map->set_callee_saved(STACK_OFFSET( a3H_off), A3->as_VMReg()->next());
aoqi@1 312 map->set_callee_saved(STACK_OFFSET( a4H_off), A4->as_VMReg()->next());
aoqi@1 313 map->set_callee_saved(STACK_OFFSET( a5H_off), A5->as_VMReg()->next());
aoqi@1 314 map->set_callee_saved(STACK_OFFSET( a6H_off), A6->as_VMReg()->next());
aoqi@1 315 map->set_callee_saved(STACK_OFFSET( a7H_off), A7->as_VMReg()->next());
aoqi@1 316 map->set_callee_saved(STACK_OFFSET( t0H_off), T0->as_VMReg()->next());
aoqi@1 317 map->set_callee_saved(STACK_OFFSET( t1H_off), T1->as_VMReg()->next());
aoqi@1 318 map->set_callee_saved(STACK_OFFSET( t2H_off), T2->as_VMReg()->next());
aoqi@1 319 map->set_callee_saved(STACK_OFFSET( t3H_off), T3->as_VMReg()->next());
aoqi@1 320 map->set_callee_saved(STACK_OFFSET( s0H_off), S0->as_VMReg()->next());
aoqi@1 321 map->set_callee_saved(STACK_OFFSET( s1H_off), S1->as_VMReg()->next());
aoqi@1 322 map->set_callee_saved(STACK_OFFSET( s2H_off), S2->as_VMReg()->next());
aoqi@1 323 map->set_callee_saved(STACK_OFFSET( s3H_off), S3->as_VMReg()->next());
aoqi@1 324 map->set_callee_saved(STACK_OFFSET( s4H_off), S4->as_VMReg()->next());
aoqi@1 325 map->set_callee_saved(STACK_OFFSET( s5H_off), S5->as_VMReg()->next());
aoqi@1 326 map->set_callee_saved(STACK_OFFSET( s6H_off), S6->as_VMReg()->next());
aoqi@1 327 map->set_callee_saved(STACK_OFFSET( s7H_off), S7->as_VMReg()->next());
aoqi@1 328 map->set_callee_saved(STACK_OFFSET( t8H_off), T8->as_VMReg()->next());
aoqi@1 329 map->set_callee_saved(STACK_OFFSET( t9H_off), T9->as_VMReg()->next());
aoqi@1 330 map->set_callee_saved(STACK_OFFSET( gpH_off), GP->as_VMReg()->next());
aoqi@1 331 map->set_callee_saved(STACK_OFFSET( fpH_off), FP->as_VMReg()->next());
aoqi@1 332 map->set_callee_saved(STACK_OFFSET( returnH_off), RA->as_VMReg()->next());
aoqi@1 333
aoqi@1 334 map->set_callee_saved(STACK_OFFSET( fpr0H_off), F0->as_VMReg()->next());
aoqi@1 335 map->set_callee_saved(STACK_OFFSET( fpr2H_off), F2->as_VMReg()->next());
aoqi@1 336 map->set_callee_saved(STACK_OFFSET( fpr4H_off), F4->as_VMReg()->next());
aoqi@1 337 map->set_callee_saved(STACK_OFFSET( fpr6H_off), F6->as_VMReg()->next());
aoqi@1 338 map->set_callee_saved(STACK_OFFSET( fpr8H_off), F8->as_VMReg()->next());
aoqi@1 339 map->set_callee_saved(STACK_OFFSET( fpr10H_off), F10->as_VMReg()->next());
aoqi@1 340 map->set_callee_saved(STACK_OFFSET( fpr12H_off), F12->as_VMReg()->next());
aoqi@1 341 map->set_callee_saved(STACK_OFFSET( fpr14H_off), F14->as_VMReg()->next());
aoqi@1 342 map->set_callee_saved(STACK_OFFSET( fpr16H_off), F16->as_VMReg()->next());
aoqi@1 343 map->set_callee_saved(STACK_OFFSET( fpr18H_off), F18->as_VMReg()->next());
aoqi@1 344 map->set_callee_saved(STACK_OFFSET( fpr20H_off), F20->as_VMReg()->next());
aoqi@1 345 map->set_callee_saved(STACK_OFFSET( fpr22H_off), F22->as_VMReg()->next());
aoqi@1 346 map->set_callee_saved(STACK_OFFSET( fpr24H_off), F24->as_VMReg()->next());
aoqi@1 347 map->set_callee_saved(STACK_OFFSET( fpr26H_off), F26->as_VMReg()->next());
aoqi@1 348 map->set_callee_saved(STACK_OFFSET( fpr28H_off), F28->as_VMReg()->next());
aoqi@1 349 map->set_callee_saved(STACK_OFFSET( fpr30H_off), F30->as_VMReg()->next());
aoqi@1 350 }
aoqi@1 351 */
aoqi@1 352 #undef STACK_OFFSET
aoqi@1 353 return map;
aoqi@1 354 }
aoqi@1 355
aoqi@1 356
aoqi@1 357 // Pop the current frame and restore all the registers that we
aoqi@1 358 // saved.
aoqi@1 359 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
aoqi@1 360 __ ldc1(F0, SP, fpr0_off * jintSize); __ ldc1(F1, SP, fpr1_off * jintSize);
aoqi@1 361 __ ldc1(F2, SP, fpr2_off * jintSize); __ ldc1(F3, SP, fpr3_off * jintSize);
aoqi@1 362 __ ldc1(F4, SP, fpr4_off * jintSize); __ ldc1(F5, SP, fpr5_off * jintSize);
aoqi@1 363 __ ldc1(F6, SP, fpr6_off * jintSize); __ ldc1(F7, SP, fpr7_off * jintSize);
aoqi@1 364 __ ldc1(F8, SP, fpr8_off * jintSize); __ ldc1(F9, SP, fpr9_off * jintSize);
aoqi@1 365 __ ldc1(F10, SP, fpr10_off * jintSize); __ ldc1(F11, SP, fpr11_off * jintSize);
aoqi@1 366 __ ldc1(F12, SP, fpr12_off * jintSize); __ ldc1(F13, SP, fpr13_off * jintSize);
aoqi@1 367 __ ldc1(F14, SP, fpr14_off * jintSize); __ ldc1(F15, SP, fpr15_off * jintSize);
aoqi@1 368 __ ldc1(F16, SP, fpr16_off * jintSize); __ ldc1(F17, SP, fpr17_off * jintSize);
aoqi@1 369 __ ldc1(F18, SP, fpr18_off * jintSize); __ ldc1(F19, SP, fpr19_off * jintSize);
aoqi@1 370 __ ldc1(F20, SP, fpr20_off * jintSize); __ ldc1(F21, SP, fpr21_off * jintSize);
aoqi@1 371 __ ldc1(F22, SP, fpr22_off * jintSize); __ ldc1(F23, SP, fpr23_off * jintSize);
aoqi@1 372 __ ldc1(F24, SP, fpr24_off * jintSize); __ ldc1(F25, SP, fpr25_off * jintSize);
aoqi@1 373 __ ldc1(F26, SP, fpr26_off * jintSize); __ ldc1(F27, SP, fpr27_off * jintSize);
aoqi@1 374 __ ldc1(F28, SP, fpr28_off * jintSize); __ ldc1(F29, SP, fpr29_off * jintSize);
aoqi@1 375 __ ldc1(F30, SP, fpr30_off * jintSize); __ ldc1(F31, SP, fpr31_off * jintSize);
aoqi@1 376
aoqi@1 377 __ ld(V0, SP, v0_off * jintSize); __ ld(V1, SP, v1_off * jintSize);
aoqi@1 378 __ ld(A0, SP, a0_off * jintSize); __ ld(A1, SP, a1_off * jintSize);
aoqi@1 379 __ ld(A2, SP, a2_off * jintSize); __ ld(A3, SP, a3_off * jintSize);
aoqi@1 380 __ ld(A4, SP, a4_off * jintSize); __ ld(A5, SP, a5_off * jintSize);
aoqi@1 381 __ ld(A6, SP, a6_off * jintSize); __ ld(A7, SP, a7_off * jintSize);
aoqi@1 382 __ ld(T0, SP, t0_off * jintSize);
aoqi@1 383 __ ld(T1, SP, t1_off * jintSize);
aoqi@1 384 __ ld(T2, SP, t2_off * jintSize);
aoqi@1 385 __ ld(T3, SP, t3_off * jintSize);
aoqi@1 386 __ ld(S0, SP, s0_off * jintSize);
aoqi@1 387 __ ld(S1, SP, s1_off * jintSize);
aoqi@1 388 __ ld(S2, SP, s2_off * jintSize);
aoqi@1 389 __ ld(S3, SP, s3_off * jintSize);
aoqi@1 390 __ ld(S4, SP, s4_off * jintSize);
aoqi@1 391 __ ld(S5, SP, s5_off * jintSize);
aoqi@1 392 __ ld(S6, SP, s6_off * jintSize);
aoqi@1 393 __ ld(S7, SP, s7_off * jintSize);
aoqi@1 394
aoqi@1 395 __ ld(T8, SP, t8_off * jintSize);
aoqi@1 396 __ ld(T9, SP, t9_off * jintSize);
aoqi@1 397
aoqi@1 398 __ ld(GP, SP, gp_off * jintSize);
aoqi@1 399 __ ld(FP, SP, fp_off * jintSize);
aoqi@1 400 __ ld(RA, SP, return_off * jintSize);
aoqi@1 401
aoqi@1 402 __ addiu(SP, SP, reg_save_size * jintSize);
aoqi@1 403 }
aoqi@1 404
aoqi@1 405 // Pop the current frame and restore the registers that might be holding
aoqi@1 406 // a result.
aoqi@1 407 // FIXME, if the result is float?
aoqi@1 408 void RegisterSaver::restore_result_registers(MacroAssembler* masm) {
aoqi@1 409 // Just restore result register. Only used by deoptimization. By
aoqi@1 410 // now any callee save register that needs to be restore to a c2
aoqi@1 411 // caller of the deoptee has been extracted into the vframeArray
aoqi@1 412 // and will be stuffed into the c2i adapter we create for later
aoqi@1 413 // restoration so only result registers need to be restored here.
aoqi@1 414 //
aoqi@1 415 __ ld(V0, SP, v0_off * jintSize);
aoqi@1 416 __ ld(V1, SP, v1_off * jintSize);
aoqi@1 417 __ addiu(SP, SP, return_off * jintSize);
aoqi@1 418 }
aoqi@1 419
aoqi@1 420 // Is vector's size (in bytes) bigger than a size saved by default?
aoqi@1 421 // 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions.
aoqi@1 422 bool SharedRuntime::is_wide_vector(int size) {
aoqi@1 423 return size > 16;
aoqi@1 424 }
aoqi@1 425
aoqi@1 426 // The java_calling_convention describes stack locations as ideal slots on
aoqi@1 427 // a frame with no abi restrictions. Since we must observe abi restrictions
aoqi@1 428 // (like the placement of the register window) the slots must be biased by
aoqi@1 429 // the following value.
aoqi@1 430
aoqi@1 431 static int reg2offset_in(VMReg r) {
aoqi@1 432 // Account for saved ebp and return address
aoqi@1 433 // This should really be in_preserve_stack_slots
aoqi@1 434 return (r->reg2stack() + 2 * VMRegImpl::slots_per_word) * VMRegImpl::stack_slot_size; // + 2 * VMRegImpl::stack_slot_size);
aoqi@1 435 }
aoqi@1 436
aoqi@1 437 static int reg2offset_out(VMReg r) {
aoqi@1 438 return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
aoqi@1 439 }
aoqi@1 440
aoqi@1 441 // ---------------------------------------------------------------------------
aoqi@1 442 // Read the array of BasicTypes from a signature, and compute where the
aoqi@1 443 // arguments should go. Values in the VMRegPair regs array refer to 4-byte
aoqi@1 444 // quantities. Values less than SharedInfo::stack0 are registers, those above
aoqi@1 445 // refer to 4-byte stack slots. All stack slots are based off of the stack pointer
aoqi@1 446 // as framesizes are fixed.
aoqi@1 447 // VMRegImpl::stack0 refers to the first slot 0(sp).
aoqi@1 448 // and VMRegImpl::stack0+1 refers to the memory word 4-byes higher. Register
aoqi@1 449 // up to RegisterImpl::number_of_registers) are the 32-bit
aoqi@1 450 // integer registers.
aoqi@1 451
aoqi@1 452 // Pass first five oop/int args in registers T0, A0 - A3.
aoqi@1 453 // Pass float/double/long args in stack.
aoqi@1 454 // Doubles have precedence, so if you pass a mix of floats and doubles
aoqi@1 455 // the doubles will grab the registers before the floats will.
aoqi@1 456
aoqi@1 457 // Note: the INPUTS in sig_bt are in units of Java argument words, which are
aoqi@1 458 // either 32-bit or 64-bit depending on the build. The OUTPUTS are in 32-bit
aoqi@1 459 // units regardless of build. Of course for i486 there is no 64 bit build
aoqi@1 460
aoqi@1 461
aoqi@1 462 // ---------------------------------------------------------------------------
aoqi@1 463 // The compiled Java calling convention.
aoqi@1 464 // Pass first five oop/int args in registers T0, A0 - A3.
aoqi@1 465 // Pass float/double/long args in stack.
aoqi@1 466 // Doubles have precedence, so if you pass a mix of floats and doubles
aoqi@1 467 // the doubles will grab the registers before the floats will.
aoqi@1 468
aoqi@1 469 int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
aoqi@1 470 VMRegPair *regs,
aoqi@1 471 int total_args_passed,
aoqi@1 472 int is_outgoing) {
aoqi@1 473 //#define aoqi_test
aoqi@1 474 #ifdef aoqi_test
aoqi@1 475 tty->print_cr(" SharedRuntime::%s :%d, total_args_passed: %d", __func__, __LINE__, total_args_passed);
aoqi@1 476 #endif
aoqi@1 477
aoqi@1 478 // Create the mapping between argument positions and
aoqi@1 479 // registers.
aoqi@1 480 //static const Register INT_ArgReg[Argument::n_int_register_parameters_j] = {
aoqi@1 481 static const Register INT_ArgReg[Argument::n_register_parameters + 1] = {
aoqi@1 482 T0, A0, A1, A2, A3, A4, A5, A6, A7
aoqi@1 483 };
aoqi@1 484 //static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters_j] = {
aoqi@1 485 static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters] = {
aoqi@1 486 F12, F13, F14, F15, F16, F17, F18, F19
aoqi@1 487 };
aoqi@1 488
aoqi@1 489
aoqi@1 490 uint args = 0;
aoqi@1 491 uint stk_args = 0; // inc by 2 each time
aoqi@1 492
aoqi@1 493 for (int i = 0; i < total_args_passed; i++) {
aoqi@1 494 switch (sig_bt[i]) {
aoqi@1 495 case T_VOID:
aoqi@1 496 // halves of T_LONG or T_DOUBLE
aoqi@1 497 assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
aoqi@1 498 regs[i].set_bad();
aoqi@1 499 break;
aoqi@1 500 case T_BOOLEAN:
aoqi@1 501 case T_CHAR:
aoqi@1 502 case T_BYTE:
aoqi@1 503 case T_SHORT:
aoqi@1 504 case T_INT:
aoqi@1 505 if (args < Argument::n_register_parameters) {
aoqi@1 506 regs[i].set1(INT_ArgReg[args++]->as_VMReg());
aoqi@1 507 } else {
aoqi@1 508 regs[i].set1(VMRegImpl::stack2reg(stk_args));
aoqi@1 509 stk_args += 2;
aoqi@1 510 }
aoqi@1 511 break;
aoqi@1 512 case T_LONG:
aoqi@1 513 assert(sig_bt[i + 1] == T_VOID, "expecting half");
aoqi@1 514 // fall through
aoqi@1 515 case T_OBJECT:
aoqi@1 516 case T_ARRAY:
aoqi@1 517 case T_ADDRESS:
aoqi@1 518 if (args < Argument::n_register_parameters) {
aoqi@1 519 regs[i].set2(INT_ArgReg[args++]->as_VMReg());
aoqi@1 520 } else {
aoqi@1 521 regs[i].set2(VMRegImpl::stack2reg(stk_args));
aoqi@1 522 stk_args += 2;
aoqi@1 523 }
aoqi@1 524 break;
aoqi@1 525 case T_FLOAT:
aoqi@1 526 if (args < Argument::n_float_register_parameters) {
aoqi@1 527 regs[i].set1(FP_ArgReg[args++]->as_VMReg());
aoqi@1 528 } else {
aoqi@1 529 regs[i].set1(VMRegImpl::stack2reg(stk_args));
aoqi@1 530 stk_args += 2;
aoqi@1 531 }
aoqi@1 532 break;
aoqi@1 533 case T_DOUBLE:
aoqi@1 534 assert(sig_bt[i + 1] == T_VOID, "expecting half");
aoqi@1 535 if (args < Argument::n_float_register_parameters) {
aoqi@1 536 regs[i].set2(FP_ArgReg[args++]->as_VMReg());
aoqi@1 537 } else {
aoqi@1 538 regs[i].set2(VMRegImpl::stack2reg(stk_args));
aoqi@1 539 stk_args += 2;
aoqi@1 540 }
aoqi@1 541 break;
aoqi@1 542 default:
aoqi@1 543 ShouldNotReachHere();
aoqi@1 544 break;
aoqi@1 545 }
aoqi@1 546 #ifdef aoqi_test
aoqi@1 547 tty->print_cr(" SharedRuntime::%s :%d, sig_bt[%d]: %d, reg[%d]:%d|%d, stk_args:%d", __func__, __LINE__, i, sig_bt[i], i, regs[i].first(), regs[i].second(), stk_args);
aoqi@1 548 #endif
aoqi@1 549 }
aoqi@1 550
aoqi@1 551 return round_to(stk_args, 2);
aoqi@1 552 /*
aoqi@1 553 // Starting stack position for args on stack
aoqi@1 554 uint stack = 0;
aoqi@1 555
aoqi@1 556 // Pass first five oop/int args in registers T0, A0 - A3.
aoqi@1 557 uint reg_arg0 = 9999;
aoqi@1 558 uint reg_arg1 = 9999;
aoqi@1 559 uint reg_arg2 = 9999;
aoqi@1 560 uint reg_arg3 = 9999;
aoqi@1 561 uint reg_arg4 = 9999;
aoqi@1 562
aoqi@1 563
aoqi@1 564 // Pass doubles & longs &float ligned on the stack. First count stack slots for doubles
aoqi@1 565 int i;
aoqi@1 566 for( i = 0; i < total_args_passed; i++) {
aoqi@1 567 if( sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG ) {
aoqi@1 568 stack += 2;
aoqi@1 569 }
aoqi@1 570 }
aoqi@1 571 int dstack = 0; // Separate counter for placing doubles
aoqi@1 572 for( i = 0; i < total_args_passed; i++) {
aoqi@1 573 // From the type and the argument number (count) compute the location
aoqi@1 574 switch( sig_bt[i] ) {
aoqi@1 575 case T_SHORT:
aoqi@1 576 case T_CHAR:
aoqi@1 577 case T_BYTE:
aoqi@1 578 case T_BOOLEAN:
aoqi@1 579 case T_INT:
aoqi@1 580 case T_ARRAY:
aoqi@1 581 case T_OBJECT:
aoqi@1 582 case T_ADDRESS:
aoqi@1 583 if( reg_arg0 == 9999 ) {
aoqi@1 584 reg_arg0 = i;
aoqi@1 585 regs[i].set1(T0->as_VMReg());
aoqi@1 586 } else if( reg_arg1 == 9999 ) {
aoqi@1 587 reg_arg1 = i;
aoqi@1 588 regs[i].set1(A0->as_VMReg());
aoqi@1 589 } else if( reg_arg2 == 9999 ) {
aoqi@1 590 reg_arg2 = i;
aoqi@1 591 regs[i].set1(A1->as_VMReg());
aoqi@1 592 }else if( reg_arg3 == 9999 ) {
aoqi@1 593 reg_arg3 = i;
aoqi@1 594 regs[i].set1(A2->as_VMReg());
aoqi@1 595 }else if( reg_arg4 == 9999 ) {
aoqi@1 596 reg_arg4 = i;
aoqi@1 597 regs[i].set1(A3->as_VMReg());
aoqi@1 598 } else {
aoqi@1 599 regs[i].set1(VMRegImpl::stack2reg(stack++));
aoqi@1 600 }
aoqi@1 601 break;
aoqi@1 602 case T_FLOAT:
aoqi@1 603 regs[i].set1(VMRegImpl::stack2reg(stack++));
aoqi@1 604 break;
aoqi@1 605 case T_LONG:
aoqi@1 606 assert(sig_bt[i+1] == T_VOID, "missing Half" );
aoqi@1 607 regs[i].set2(VMRegImpl::stack2reg(dstack));
aoqi@1 608 dstack += 2;
aoqi@1 609 break;
aoqi@1 610 case T_DOUBLE:
aoqi@1 611 assert(sig_bt[i+1] == T_VOID, "missing Half" );
aoqi@1 612 regs[i].set2(VMRegImpl::stack2reg(dstack));
aoqi@1 613 dstack += 2;
aoqi@1 614 break;
aoqi@1 615 case T_VOID: regs[i].set_bad(); break;
aoqi@1 616 break;
aoqi@1 617 default:
aoqi@1 618 ShouldNotReachHere();
aoqi@1 619 break;
aoqi@1 620 }
aoqi@1 621 }
aoqi@1 622 // return value can be odd number of VMRegImpl stack slots make multiple of 2
aoqi@1 623 return round_to(stack, 2);
aoqi@1 624 */
aoqi@1 625 }
aoqi@1 626
aoqi@1 627 // Helper class mostly to avoid passing masm everywhere, and handle store
aoqi@1 628 // displacement overflow logic for LP64
aoqi@1 629 class AdapterGenerator {
aoqi@1 630 MacroAssembler *masm;
aoqi@1 631 #ifdef _LP64
aoqi@1 632 Register Rdisp;
aoqi@1 633 void set_Rdisp(Register r) { Rdisp = r; }
aoqi@1 634 #endif // _LP64
aoqi@1 635
aoqi@1 636 void patch_callers_callsite();
aoqi@1 637 // void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch);
aoqi@1 638
aoqi@1 639 // base+st_off points to top of argument
aoqi@1 640 int arg_offset(const int st_off) { return st_off; }
aoqi@1 641 int next_arg_offset(const int st_off) {
aoqi@1 642 return st_off - Interpreter::stackElementSize;
aoqi@1 643 }
aoqi@1 644
aoqi@1 645 #ifdef _LP64
aoqi@1 646 // On _LP64 argument slot values are loaded first into a register
aoqi@1 647 // because they might not fit into displacement.
aoqi@1 648 Register arg_slot(const int st_off);
aoqi@1 649 Register next_arg_slot(const int st_off);
aoqi@1 650 #else
aoqi@1 651 int arg_slot(const int st_off) { return arg_offset(st_off); }
aoqi@1 652 int next_arg_slot(const int st_off) { return next_arg_offset(st_off); }
aoqi@1 653 #endif // _LP64
aoqi@1 654
aoqi@1 655 // Stores long into offset pointed to by base
aoqi@1 656 void store_c2i_long(Register r, Register base,
aoqi@1 657 const int st_off, bool is_stack);
aoqi@1 658 void store_c2i_object(Register r, Register base,
aoqi@1 659 const int st_off);
aoqi@1 660 void store_c2i_int(Register r, Register base,
aoqi@1 661 const int st_off);
aoqi@1 662 void store_c2i_double(VMReg r_2,
aoqi@1 663 VMReg r_1, Register base, const int st_off);
aoqi@1 664 void store_c2i_float(FloatRegister f, Register base,
aoqi@1 665 const int st_off);
aoqi@1 666
aoqi@1 667 public:
aoqi@1 668 //void tag_stack(const BasicType sig, int st_off);
aoqi@1 669 void gen_c2i_adapter(int total_args_passed,
aoqi@1 670 // VMReg max_arg,
aoqi@1 671 int comp_args_on_stack, // VMRegStackSlots
aoqi@1 672 const BasicType *sig_bt,
aoqi@1 673 const VMRegPair *regs,
aoqi@1 674 Label& skip_fixup);
aoqi@1 675 void gen_i2c_adapter(int total_args_passed,
aoqi@1 676 // VMReg max_arg,
aoqi@1 677 int comp_args_on_stack, // VMRegStackSlots
aoqi@1 678 const BasicType *sig_bt,
aoqi@1 679 const VMRegPair *regs);
aoqi@1 680
aoqi@1 681 AdapterGenerator(MacroAssembler *_masm) : masm(_masm) {}
aoqi@1 682 };
aoqi@1 683
aoqi@1 684
aoqi@1 685 // Patch the callers callsite with entry to compiled code if it exists.
aoqi@1 686 void AdapterGenerator::patch_callers_callsite() {
aoqi@1 687 Label L;
aoqi@1 688 //FIXME , what is stored in eax?
aoqi@1 689 //__ verify_oop(ebx);
aoqi@1 690 __ verify_oop(Rmethod);
aoqi@1 691 // __ cmpl(Address(ebx, in_bytes(Method::code_offset())), NULL_WORD);
aoqi@1 692 __ ld_ptr(AT, Rmethod, in_bytes(Method::code_offset()));
aoqi@1 693 //__ jcc(Assembler::equal, L);
aoqi@1 694 __ beq(AT,R0,L);
aoqi@1 695 __ delayed()->nop();
aoqi@1 696 // Schedule the branch target address early.
aoqi@1 697 // Call into the VM to patch the caller, then jump to compiled callee
aoqi@1 698 // eax isn't live so capture return address while we easily can
aoqi@1 699 // __ movl(eax, Address(esp, 0));
aoqi@1 700 // __ lw(T5,SP,0);
aoqi@1 701 __ move(V0, RA);
aoqi@1 702
aoqi@1 703 __ pushad();
aoqi@1 704 //jerome_for_debug
aoqi@1 705 // __ pushad();
aoqi@1 706 // __ pushfd();
aoqi@1 707 #ifdef COMPILER2
aoqi@1 708 // C2 may leave the stack dirty if not in SSE2+ mode
aoqi@1 709 __ empty_FPU_stack();
aoqi@1 710 #endif /* COMPILER2 */
aoqi@1 711
aoqi@1 712 // VM needs caller's callsite
aoqi@1 713 // __ pushl(eax);
aoqi@1 714
aoqi@1 715 // VM needs target method
aoqi@1 716 // __ pushl(ebx);
aoqi@1 717 // __ push(Rmethod);
aoqi@1 718 // __ verify_oop(ebx);
aoqi@1 719
aoqi@1 720 __ move(A0, Rmethod);
aoqi@1 721 __ move(A1, V0);
aoqi@1 722 // __ addi(SP, SP, -8);
aoqi@1 723 //we should preserve the return address
aoqi@1 724 __ verify_oop(Rmethod);
aoqi@1 725 __ move(S0, SP);
aoqi@1 726 __ move(AT, -(StackAlignmentInBytes)); // align the stack
aoqi@1 727 __ andr(SP, SP, AT);
aoqi@1 728 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite),
aoqi@1 729 relocInfo::runtime_call_type);
aoqi@1 730 //__ addl(esp, 2*wordSize);
aoqi@1 731
aoqi@1 732 __ delayed()->nop();
aoqi@1 733 // __ addi(SP, SP, 8);
aoqi@1 734 // __ popfd();
aoqi@1 735 __ move(SP, S0);
aoqi@1 736 __ popad();
aoqi@1 737 __ bind(L);
aoqi@1 738 }
aoqi@1 739 /*
aoqi@1 740 void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off,
aoqi@1 741 Register scratch) {
aoqi@1 742 Unimplemented();
aoqi@1 743 }*/
aoqi@1 744
aoqi@1 745 #ifdef _LP64
aoqi@1 746 Register AdapterGenerator::arg_slot(const int st_off) {
aoqi@1 747 Unimplemented();
aoqi@1 748 }
aoqi@1 749
aoqi@1 750 Register AdapterGenerator::next_arg_slot(const int st_off){
aoqi@1 751 Unimplemented();
aoqi@1 752 }
aoqi@1 753 #endif // _LP64
aoqi@1 754
aoqi@1 755 // Stores long into offset pointed to by base
aoqi@1 756 void AdapterGenerator::store_c2i_long(Register r, Register base,
aoqi@1 757 const int st_off, bool is_stack) {
aoqi@1 758 Unimplemented();
aoqi@1 759 }
aoqi@1 760
aoqi@1 761 void AdapterGenerator::store_c2i_object(Register r, Register base,
aoqi@1 762 const int st_off) {
aoqi@1 763 Unimplemented();
aoqi@1 764 }
aoqi@1 765
aoqi@1 766 void AdapterGenerator::store_c2i_int(Register r, Register base,
aoqi@1 767 const int st_off) {
aoqi@1 768 Unimplemented();
aoqi@1 769 }
aoqi@1 770
aoqi@1 771 // Stores into offset pointed to by base
aoqi@1 772 void AdapterGenerator::store_c2i_double(VMReg r_2,
aoqi@1 773 VMReg r_1, Register base, const int st_off) {
aoqi@1 774 Unimplemented();
aoqi@1 775 }
aoqi@1 776
aoqi@1 777 void AdapterGenerator::store_c2i_float(FloatRegister f, Register base,
aoqi@1 778 const int st_off) {
aoqi@1 779 Unimplemented();
aoqi@1 780 }
aoqi@1 781 /*
aoqi@1 782 void AdapterGenerator::tag_stack(const BasicType sig, int st_off) {
aoqi@1 783 if (TaggedStackInterpreter) {
aoqi@1 784 int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0);
aoqi@1 785 if (sig == T_OBJECT || sig == T_ARRAY) {
aoqi@1 786 // __ movl(Address(esp, tag_offset), frame::TagReference);
aoqi@1 787 // __ addi(AT,R0, frame::TagReference);
aoqi@1 788
aoqi@1 789 __ move(AT, frame::TagReference);
aoqi@1 790 __ sw (AT, SP, tag_offset);
aoqi@1 791 } else if (sig == T_LONG || sig == T_DOUBLE) {
aoqi@1 792 int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1);
aoqi@1 793 // __ movl(Address(esp, next_tag_offset), frame::TagValue);
aoqi@1 794 // __ addi(AT,R0, frame::TagValue);
aoqi@1 795 __ move(AT, frame::TagValue);
aoqi@1 796 __ sw (AT, SP, next_tag_offset);
aoqi@1 797 //__ movl(Address(esp, tag_offset), frame::TagValue);
aoqi@1 798 // __ addi(AT,R0, frame::TagValue);
aoqi@1 799 __ move(AT, frame::TagValue);
aoqi@1 800 __ sw (AT, SP, tag_offset);
aoqi@1 801
aoqi@1 802 } else {
aoqi@1 803 // __ movl(Address(esp, tag_offset), frame::TagValue);
aoqi@1 804 //__ addi(AT,R0, frame::TagValue);
aoqi@1 805 __ move(AT, frame::TagValue);
aoqi@1 806 __ sw (AT, SP, tag_offset);
aoqi@1 807
aoqi@1 808 }
aoqi@1 809 }
aoqi@1 810 }*/
aoqi@1 811
aoqi@1 812 void AdapterGenerator::gen_c2i_adapter(
aoqi@1 813 int total_args_passed,
aoqi@1 814 // VMReg max_arg,
aoqi@1 815 int comp_args_on_stack, // VMRegStackSlots
aoqi@1 816 const BasicType *sig_bt,
aoqi@1 817 const VMRegPair *regs,
aoqi@1 818 Label& skip_fixup) {
aoqi@1 819
aoqi@1 820 // Before we get into the guts of the C2I adapter, see if we should be here
aoqi@1 821 // at all. We've come from compiled code and are attempting to jump to the
aoqi@1 822 // interpreter, which means the caller made a static call to get here
aoqi@1 823 // (vcalls always get a compiled target if there is one). Check for a
aoqi@1 824 // compiled target. If there is one, we need to patch the caller's call.
aoqi@1 825 // However we will run interpreted if we come thru here. The next pass
aoqi@1 826 // thru the call site will run compiled. If we ran compiled here then
aoqi@1 827 // we can (theorectically) do endless i2c->c2i->i2c transitions during
aoqi@1 828 // deopt/uncommon trap cycles. If we always go interpreted here then
aoqi@1 829 // we can have at most one and don't need to play any tricks to keep
aoqi@1 830 // from endlessly growing the stack.
aoqi@1 831 //
aoqi@1 832 // Actually if we detected that we had an i2c->c2i transition here we
aoqi@1 833 // ought to be able to reset the world back to the state of the interpreted
aoqi@1 834 // call and not bother building another interpreter arg area. We don't
aoqi@1 835 // do that at this point.
aoqi@1 836
aoqi@1 837 patch_callers_callsite();
aoqi@1 838
aoqi@1 839 __ bind(skip_fixup);
aoqi@1 840
aoqi@1 841 #ifdef COMPILER2
aoqi@1 842 __ empty_FPU_stack();
aoqi@1 843 #endif /* COMPILER2 */
aoqi@1 844 //this is for native ?
aoqi@1 845 // Since all args are passed on the stack, total_args_passed * interpreter_
aoqi@1 846 // stack_element_size is the
aoqi@1 847 // space we need.
aoqi@1 848 int extraspace = total_args_passed * Interpreter::stackElementSize;
aoqi@1 849
aoqi@1 850 // stack is aligned, keep it that way
aoqi@1 851 extraspace = round_to(extraspace, 2*wordSize);
aoqi@1 852
aoqi@1 853 // Get return address
aoqi@1 854 // __ popl(eax);
aoqi@1 855 //__ pop(T4);
aoqi@1 856 __ move(V0, RA);
aoqi@1 857 // set senderSP value
aoqi@1 858 // __ movl(esi, esp);
aoqi@1 859 //refer to interpreter_mips.cpp:generate_asm_entry
aoqi@1 860 __ move(Rsender, SP);
aoqi@1 861 //__ subl(esp, extraspace);
aoqi@1 862 __ addi(SP, SP, -extraspace);
aoqi@1 863
aoqi@1 864 // Now write the args into the outgoing interpreter space
aoqi@1 865 for (int i = 0; i < total_args_passed; i++) {
aoqi@1 866 if (sig_bt[i] == T_VOID) {
aoqi@1 867 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE),
aoqi@1 868 "missing half");
aoqi@1 869 continue;
aoqi@1 870 }
aoqi@1 871
aoqi@1 872 // st_off points to lowest address on stack.
aoqi@1 873 int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize;
aoqi@1 874 #ifdef aoqi_test
aoqi@1 875 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d, st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off);
aoqi@1 876 #endif
aoqi@1 877 // Say 4 args:
aoqi@1 878 // i st_off
aoqi@1 879 // 0 12 T_LONG
aoqi@1 880 // 1 8 T_VOID
aoqi@1 881 // 2 4 T_OBJECT
aoqi@1 882 // 3 0 T_BOOL
aoqi@1 883 VMReg r_1 = regs[i].first();
aoqi@1 884 VMReg r_2 = regs[i].second();
aoqi@1 885 if (!r_1->is_valid()) {
aoqi@1 886 assert(!r_2->is_valid(), "");
aoqi@1 887 continue;
aoqi@1 888 }
aoqi@1 889
aoqi@1 890 if (r_1->is_stack()) {
aoqi@1 891 // memory to memory use fpu stack top
aoqi@1 892 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace;
aoqi@1 893 #ifdef aoqi_test
aoqi@1 894 tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_stack, ld_off:%x", __func__, __LINE__, ld_off);
aoqi@1 895 #endif
aoqi@1 896
aoqi@1 897 if (!r_2->is_valid()) {
aoqi@1 898 #ifdef aoqi_test
aoqi@1 899 tty->print_cr(" AdapterGenerator::%s :%d, !r_2->is_valid, ld_off:%x", __func__, __LINE__, ld_off);
aoqi@1 900 #endif
aoqi@1 901 __ ld_ptr(AT, SP, ld_off);
aoqi@1 902 __ st_ptr(AT, SP, st_off);
aoqi@1 903 //tag_stack(sig_bt[i], st_off);
aoqi@1 904 } else {
aoqi@1 905 #ifdef aoqi_test
aoqi@1 906 tty->print_cr(" AdapterGenerator::%s :%d, r_2->is_valid, ld_off:%x", __func__, __LINE__, ld_off);
aoqi@1 907 #endif
aoqi@1 908
aoqi@1 909 // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW
aoqi@1 910 // st_off == MSW, st_off-wordSize == LSW
aoqi@1 911
aoqi@1 912 int next_off = st_off - Interpreter::stackElementSize;
aoqi@1 913 /*
aoqi@1 914 __ lw(AT, SP, ld_off);
aoqi@1 915 __ sw(AT, SP, next_off);
aoqi@1 916 __ lw(AT, SP, ld_off + wordSize);
aoqi@1 917 __ sw(AT, SP, st_off);
aoqi@1 918 */
aoqi@1 919 __ ld_ptr(AT, SP, ld_off);
aoqi@1 920 __ st_ptr(AT, SP, st_off);
aoqi@1 921
aoqi@1 922 /* Ref to is_Register condition */
aoqi@1 923 if(sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE)
aoqi@1 924 __ st_ptr(AT,SP,st_off - 8);
aoqi@1 925 //tag_stack(sig_bt[i], next_off);
aoqi@1 926 }
aoqi@1 927 } else if (r_1->is_Register()) {
aoqi@1 928 Register r = r_1->as_Register();
aoqi@1 929 if (!r_2->is_valid()) {
aoqi@1 930 #ifdef aoqi_test
aoqi@1 931 tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_Register, !r_2->is_valid, st_off: %lx", __func__, __LINE__, st_off);
aoqi@1 932 #endif
aoqi@1 933 // __ movl(Address(esp, st_off), r);
aoqi@1 934 __ sd(r,SP, st_off); //aoqi_test FIXME
aoqi@1 935 //tag_stack(sig_bt[i], st_off);
aoqi@1 936 } else {
aoqi@1 937 #ifdef aoqi_test
aoqi@1 938 tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_Register, r_2->is_valid, st_off: %lx", __func__, __LINE__, st_off);
aoqi@1 939 #endif
aoqi@1 940 //FIXME, mips will not enter here
aoqi@1 941 // long/double in gpr
aoqi@1 942 __ sd(r,SP, st_off); //aoqi_test FIXME
aoqi@1 943 /* Jin: In [java/util/zip/ZipFile.java]
aoqi@1 944
aoqi@1 945 private static native long open(String name, int mode, long lastModified);
aoqi@1 946 private static native int getTotal(long jzfile);
aoqi@1 947 *
aoqi@1 948 * We need to transfer T_LONG paramenters from a compiled method to a native method.
aoqi@1 949 * It's a complex process:
aoqi@1 950 *
aoqi@1 951 * Caller -> lir_static_call -> gen_resolve_stub
aoqi@1 952 -> -- resolve_static_call_C
aoqi@1 953 `- gen_c2i_adapter() [*]
aoqi@1 954 |
aoqi@1 955 `- AdapterHandlerLibrary::get_create_apapter_index
aoqi@1 956 -> generate_native_entry
aoqi@1 957 -> InterpreterRuntime::SignatureHandlerGenerator::pass_long [**]
aoqi@1 958
aoqi@1 959 * In [**], T_Long parameter is stored in stack as:
aoqi@1 960
aoqi@1 961 (high)
aoqi@1 962 | |
aoqi@1 963 -----------
aoqi@1 964 | 8 bytes |
aoqi@1 965 | (void) |
aoqi@1 966 -----------
aoqi@1 967 | 8 bytes |
aoqi@1 968 | (long) |
aoqi@1 969 -----------
aoqi@1 970 | |
aoqi@1 971 (low)
aoqi@1 972 *
aoqi@1 973 * However, the sequence is reversed here:
aoqi@1 974 *
aoqi@1 975 (high)
aoqi@1 976 | |
aoqi@1 977 -----------
aoqi@1 978 | 8 bytes |
aoqi@1 979 | (long) |
aoqi@1 980 -----------
aoqi@1 981 | 8 bytes |
aoqi@1 982 | (void) |
aoqi@1 983 -----------
aoqi@1 984 | |
aoqi@1 985 (low)
aoqi@1 986 *
aoqi@1 987 * So I stored another 8 bytes in the T_VOID slot. It then can be accessed from generate_native_entry().
aoqi@1 988 */
aoqi@1 989 if (sig_bt[i] == T_LONG)
aoqi@1 990 __ sd(r,SP, st_off - 8);
aoqi@1 991 // ShouldNotReachHere();
aoqi@1 992 // int next_off = st_off - Interpreter::stackElementSize;
aoqi@1 993 // __ sw(r_2->as_Register(),SP, st_off);
aoqi@1 994 // __ sw(r,SP, next_off);
aoqi@1 995 // tag_stack(masm, sig_bt[i], next_off);
aoqi@1 996 }
aoqi@1 997 } else if (r_1->is_FloatRegister()) {
aoqi@1 998 assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register");
aoqi@1 999
aoqi@1 1000 FloatRegister fr = r_1->as_FloatRegister();
aoqi@1 1001 if (sig_bt[i] == T_FLOAT)
aoqi@1 1002 __ swc1(fr,SP, st_off);
aoqi@1 1003 else
aoqi@1 1004 {
aoqi@1 1005 __ sdc1(fr,SP, st_off);
aoqi@1 1006 __ sdc1(fr,SP, st_off - 8); /* T_DOUBLE needs two slots */
aoqi@1 1007 }
aoqi@1 1008 }
aoqi@1 1009 }
aoqi@1 1010
aoqi@1 1011 // Schedule the branch target address early.
aoqi@1 1012 __ ld_ptr(AT, Rmethod,in_bytes(Method::interpreter_entry_offset()) );
aoqi@1 1013 // And repush original return address
aoqi@1 1014 __ move(RA, V0);
aoqi@1 1015 __ jr (AT);
aoqi@1 1016 __ delayed()->nop();
aoqi@1 1017 }
aoqi@1 1018
aoqi@1 1019 void AdapterGenerator::gen_i2c_adapter(
aoqi@1 1020 int total_args_passed,
aoqi@1 1021 // VMReg max_arg,
aoqi@1 1022 int comp_args_on_stack, // VMRegStackSlots
aoqi@1 1023 const BasicType *sig_bt,
aoqi@1 1024 const VMRegPair *regs) {
aoqi@1 1025
aoqi@1 1026 // Generate an I2C adapter: adjust the I-frame to make space for the C-frame
aoqi@1 1027 // layout. Lesp was saved by the calling I-frame and will be restored on
aoqi@1 1028 // return. Meanwhile, outgoing arg space is all owned by the callee
aoqi@1 1029 // C-frame, so we can mangle it at will. After adjusting the frame size,
aoqi@1 1030 // hoist register arguments and repack other args according to the compiled
aoqi@1 1031 // code convention. Finally, end in a jump to the compiled code. The entry
aoqi@1 1032 // point address is the start of the buffer.
aoqi@1 1033
aoqi@1 1034 // We will only enter here from an interpreted frame and never from after
aoqi@1 1035 // passing thru a c2i. Azul allowed this but we do not. If we lose the
aoqi@1 1036 // race and use a c2i we will remain interpreted for the race loser(s).
aoqi@1 1037 // This removes all sorts of headaches on the mips side and also eliminates
aoqi@1 1038 // the possibility of having c2i -> i2c -> c2i -> ... endless transitions.
aoqi@1 1039
aoqi@1 1040
aoqi@1 1041 __ move(T9, SP);
aoqi@1 1042
aoqi@1 1043 // Cut-out for having no stack args. Since up to 2 int/oop args are passed
aoqi@1 1044 // in registers, we will occasionally have no stack args.
aoqi@1 1045 int comp_words_on_stack = 0;
aoqi@1 1046 if (comp_args_on_stack) {
aoqi@1 1047 // Sig words on the stack are greater-than VMRegImpl::stack0. Those in
aoqi@1 1048 // registers are below. By subtracting stack0, we either get a negative
aoqi@1 1049 // number (all values in registers) or the maximum stack slot accessed.
aoqi@1 1050 // int comp_args_on_stack = VMRegImpl::reg2stack(max_arg);
aoqi@1 1051 // Convert 4-byte stack slots to words.
aoqi@1 1052 // did mips need round? FIXME aoqi
aoqi@1 1053 comp_words_on_stack = round_to(comp_args_on_stack*4, wordSize)>>LogBytesPerWord;
aoqi@1 1054 // Round up to miminum stack alignment, in wordSize
aoqi@1 1055 comp_words_on_stack = round_to(comp_words_on_stack, 2);
aoqi@1 1056 __ daddi(SP, SP, -comp_words_on_stack * wordSize);
aoqi@1 1057 }
aoqi@1 1058
aoqi@1 1059 // Align the outgoing SP
aoqi@1 1060 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 1061 __ andr(SP, SP, AT);
aoqi@1 1062 // push the return address on the stack (note that pushing, rather
aoqi@1 1063 // than storing it, yields the correct frame alignment for the callee)
aoqi@1 1064 // Put saved SP in another register
aoqi@1 1065 // const Register saved_sp = eax;
aoqi@1 1066 const Register saved_sp = V0;
aoqi@1 1067 __ move(saved_sp, T9);
aoqi@1 1068
aoqi@1 1069
aoqi@1 1070 // Will jump to the compiled code just as if compiled code was doing it.
aoqi@1 1071 // Pre-load the register-jump target early, to schedule it better.
aoqi@1 1072 __ ld(T9, Rmethod, in_bytes(Method::from_compiled_offset()));
aoqi@1 1073
aoqi@1 1074 // Now generate the shuffle code. Pick up all register args and move the
aoqi@1 1075 // rest through the floating point stack top.
aoqi@1 1076 for (int i = 0; i < total_args_passed; i++) {
aoqi@1 1077 if (sig_bt[i] == T_VOID) {
aoqi@1 1078 // Longs and doubles are passed in native word order, but misaligned
aoqi@1 1079 // in the 32-bit build.
aoqi@1 1080 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
aoqi@1 1081 continue;
aoqi@1 1082 }
aoqi@1 1083
aoqi@1 1084 // Pick up 0, 1 or 2 words from SP+offset.
aoqi@1 1085
aoqi@1 1086 //FIXME. aoqi. just delete the assert
aoqi@1 1087 //assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), "scrambled load targets?");
aoqi@1 1088 // Load in argument order going down.
aoqi@1 1089 int ld_off = (total_args_passed -1 - i)*Interpreter::stackElementSize;
aoqi@1 1090 // Point to interpreter value (vs. tag)
aoqi@1 1091 int next_off = ld_off - Interpreter::stackElementSize;
aoqi@1 1092 //
aoqi@1 1093 //
aoqi@1 1094 //
aoqi@1 1095 VMReg r_1 = regs[i].first();
aoqi@1 1096 VMReg r_2 = regs[i].second();
aoqi@1 1097 if (!r_1->is_valid()) {
aoqi@1 1098 assert(!r_2->is_valid(), "");
aoqi@1 1099 continue;
aoqi@1 1100 }
aoqi@1 1101 #ifdef aoqi_test
aoqi@1 1102 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d, ld_off:%d, next_off: %d", __func__, __LINE__, i, sig_bt[i], total_args_passed, ld_off, next_off);
aoqi@1 1103 #endif
aoqi@1 1104 if (r_1->is_stack()) {
aoqi@1 1105 // Convert stack slot to an SP offset (+ wordSize to
aoqi@1 1106 // account for return address )
aoqi@1 1107 //NOTICE HERE!!!! I sub a wordSize here
aoqi@1 1108 int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size;
aoqi@1 1109 //+ wordSize;
aoqi@1 1110
aoqi@1 1111 // We can use esi as a temp here because compiled code doesn't
aoqi@1 1112 // need esi as an input
aoqi@1 1113 // and if we end up going thru a c2i because of a miss a reasonable
aoqi@1 1114 // value of esi
aoqi@1 1115 // we be generated.
aoqi@1 1116 if (!r_2->is_valid()) {
aoqi@1 1117 #ifdef aoqi_test
aoqi@1 1118 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_stack() !r_2->is_valid(), st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off);
aoqi@1 1119 #endif
aoqi@1 1120 __ ld(AT, saved_sp, ld_off);
aoqi@1 1121 __ sd(AT, SP, st_off);
aoqi@1 1122 } else {
aoqi@1 1123 #ifdef aoqi_test
aoqi@1 1124 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_stack() r_2->is_valid(), st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off);
aoqi@1 1125 #endif
aoqi@1 1126 // Interpreter local[n] == MSW, local[n+1] == LSW however locals
aoqi@1 1127 // are accessed as negative so LSW is at LOW address
aoqi@1 1128
aoqi@1 1129 // ld_off is MSW so get LSW
aoqi@1 1130 // st_off is LSW (i.e. reg.first())
aoqi@1 1131 /*
aoqi@1 1132 __ ld(AT, saved_sp, next_off);
aoqi@1 1133 __ sd(AT, SP, st_off);
aoqi@1 1134 __ ld(AT, saved_sp, ld_off);
aoqi@1 1135 __ sd(AT, SP, st_off + wordSize);
aoqi@1 1136 */
aoqi@1 1137
aoqi@1 1138 /* 2012/4/9 Jin
aoqi@1 1139 * [./org/eclipse/swt/graphics/GC.java]
aoqi@1 1140 * void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
aoqi@1 1141 int destX, int destY, int destWidth, int destHeight,
aoqi@1 1142 boolean simple,
aoqi@1 1143 int imgWidth, int imgHeight,
aoqi@1 1144 long maskPixmap, <-- Pass T_LONG in stack
aoqi@1 1145 int maskType);
aoqi@1 1146 * Before this modification, Eclipse displays icons with solid black background.
aoqi@1 1147 */
aoqi@1 1148 __ ld(AT, saved_sp, ld_off);
aoqi@1 1149 if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE)
aoqi@1 1150 __ ld(AT, saved_sp, ld_off - 8);
aoqi@1 1151 __ sd(AT, SP, st_off);
aoqi@1 1152 //__ ld(AT, saved_sp, next_off);
aoqi@1 1153 //__ sd(AT, SP, st_off + wordSize);
aoqi@1 1154 }
aoqi@1 1155 } else if (r_1->is_Register()) { // Register argument
aoqi@1 1156 Register r = r_1->as_Register();
aoqi@1 1157 // assert(r != eax, "must be different");
aoqi@1 1158 if (r_2->is_valid()) {
aoqi@1 1159 #ifdef aoqi_test
aoqi@1 1160 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_Register() r_2->is_valid()", __func__, __LINE__, i, sig_bt[i], total_args_passed);
aoqi@1 1161 #endif
aoqi@1 1162 // assert(r_2->as_Register() != eax, "need another temporary register");
aoqi@1 1163 // Remember r_1 is low address (and LSB on mips)
aoqi@1 1164 // So r_2 gets loaded from high address regardless of the platform
aoqi@1 1165 //aoqi
aoqi@1 1166 assert(r_2->as_Register() == r_1->as_Register(), "");
aoqi@1 1167 //__ ld(r_2->as_Register(), saved_sp, ld_off);
aoqi@1 1168 //__ ld(r, saved_sp, next_off);
aoqi@1 1169 __ ld(r, saved_sp, ld_off);
aoqi@1 1170
aoqi@1 1171 /* Jin:
aoqi@1 1172 *
aoqi@1 1173 * For T_LONG type, the real layout is as below:
aoqi@1 1174
aoqi@1 1175 (high)
aoqi@1 1176 | |
aoqi@1 1177 -----------
aoqi@1 1178 | 8 bytes |
aoqi@1 1179 | (void) |
aoqi@1 1180 -----------
aoqi@1 1181 | 8 bytes |
aoqi@1 1182 | (long) |
aoqi@1 1183 -----------
aoqi@1 1184 | |
aoqi@1 1185 (low)
aoqi@1 1186 *
aoqi@1 1187 * We should load the low-8 bytes.
aoqi@1 1188 */
aoqi@1 1189 if (sig_bt[i] == T_LONG)
aoqi@1 1190 __ ld(r, saved_sp, ld_off - 8);
aoqi@1 1191 } else {
aoqi@1 1192 #ifdef aoqi_test
aoqi@1 1193 tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_Register() !r_2->is_valid()", __func__, __LINE__, i, sig_bt[i], total_args_passed);
aoqi@1 1194 #endif
aoqi@1 1195 __ lw(r, saved_sp, ld_off);
aoqi@1 1196 }
aoqi@1 1197 } else if (r_1->is_FloatRegister()) { // Float Register
aoqi@1 1198 assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register");
aoqi@1 1199
aoqi@1 1200 FloatRegister fr = r_1->as_FloatRegister();
aoqi@1 1201 if (sig_bt[i] == T_FLOAT)
aoqi@1 1202 __ lwc1(fr, saved_sp, ld_off);
aoqi@1 1203 else
aoqi@1 1204 {
aoqi@1 1205 __ ldc1(fr, saved_sp, ld_off);
aoqi@1 1206 __ ldc1(fr, saved_sp, ld_off - 8);
aoqi@1 1207 }
aoqi@1 1208 }
aoqi@1 1209 }
aoqi@1 1210
aoqi@1 1211 // 6243940 We might end up in handle_wrong_method if
aoqi@1 1212 // the callee is deoptimized as we race thru here. If that
aoqi@1 1213 // happens we don't want to take a safepoint because the
aoqi@1 1214 // caller frame will look interpreted and arguments are now
aoqi@1 1215 // "compiled" so it is much better to make this transition
aoqi@1 1216 // invisible to the stack walking code. Unfortunately if
aoqi@1 1217 // we try and find the callee by normal means a safepoint
aoqi@1 1218 // is possible. So we stash the desired callee in the thread
aoqi@1 1219 // and the vm will find there should this case occur.
aoqi@1 1220 __ get_thread(T8);
aoqi@1 1221 __ sd(Rmethod, T8, in_bytes(JavaThread::callee_target_offset()));
aoqi@1 1222
aoqi@1 1223 // move methodOop to eax in case we end up in an c2i adapter.
aoqi@1 1224 // the c2i adapters expect methodOop in eax (c2) because c2's
aoqi@1 1225 // resolve stubs return the result (the method) in eax.
aoqi@1 1226 // I'd love to fix this.
aoqi@1 1227 __ move(V0, Rmethod);
aoqi@1 1228 __ jr(T9);
aoqi@1 1229 __ delayed()->nop();
aoqi@1 1230 }
aoqi@1 1231
aoqi@1 1232 // ---------------------------------------------------------------
aoqi@1 1233 AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
aoqi@1 1234 int total_args_passed,
aoqi@1 1235 // VMReg max_arg,
aoqi@1 1236 int comp_args_on_stack, // VMRegStackSlots
aoqi@1 1237 const BasicType *sig_bt,
aoqi@1 1238 const VMRegPair *regs,
aoqi@1 1239 AdapterFingerPrint* fingerprint) {
aoqi@1 1240 address i2c_entry = __ pc();
aoqi@1 1241
aoqi@1 1242 AdapterGenerator agen(masm);
aoqi@1 1243
aoqi@1 1244 agen.gen_i2c_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs);
aoqi@1 1245
aoqi@1 1246
aoqi@1 1247 // -------------------------------------------------------------------------
aoqi@1 1248 // Generate a C2I adapter. On entry we know G5 holds the methodOop. The
aoqi@1 1249 // args start out packed in the compiled layout. They need to be unpacked
aoqi@1 1250 // into the interpreter layout. This will almost always require some stack
aoqi@1 1251 // space. We grow the current (compiled) stack, then repack the args. We
aoqi@1 1252 // finally end in a jump to the generic interpreter entry point. On exit
aoqi@1 1253 // from the interpreter, the interpreter will restore our SP (lest the
aoqi@1 1254 // compiled code, which relys solely on SP and not FP, get sick).
aoqi@1 1255
aoqi@1 1256 address c2i_unverified_entry = __ pc();
aoqi@1 1257 Label skip_fixup;
aoqi@1 1258 {
aoqi@1 1259 Register holder = T1;
aoqi@1 1260 Register receiver = T0;
aoqi@1 1261 Register temp = T8;
aoqi@1 1262 address ic_miss = SharedRuntime::get_ic_miss_stub();
aoqi@1 1263
aoqi@1 1264 Label missed;
aoqi@1 1265
aoqi@1 1266 __ verify_oop(holder);
aoqi@1 1267 // __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
aoqi@1 1268 //__ ld_ptr(temp, receiver, oopDesc::klass_offset_in_bytes());
aoqi@1 1269 //add for compressedoops
aoqi@1 1270 __ load_klass(temp, receiver);
aoqi@1 1271 __ verify_oop(temp);
aoqi@1 1272
aoqi@1 1273 // __ cmpl(temp, Address(holder, CompiledICHolder::holder_klass_offset()));
aoqi@1 1274 __ ld_ptr(AT, holder, CompiledICHolder::holder_klass_offset());
aoqi@1 1275 //__ movl(ebx, Address(holder, CompiledICHolder::holder_method_offset()));
aoqi@1 1276 __ ld_ptr(Rmethod, holder, CompiledICHolder::holder_method_offset());
aoqi@1 1277 //__ jcc(Assembler::notEqual, missed);
aoqi@1 1278 __ bne(AT, temp, missed);
aoqi@1 1279 __ delayed()->nop();
aoqi@1 1280 // Method might have been compiled since the call site was patched to
aoqi@1 1281 // interpreted if that is the case treat it as a miss so we can get
aoqi@1 1282 // the call site corrected.
aoqi@1 1283 //__ cmpl(Address(ebx, in_bytes(Method::code_offset())), NULL_WORD);
aoqi@1 1284 //__ jcc(Assembler::equal, skip_fixup);
aoqi@1 1285 __ ld_ptr(AT, Rmethod, in_bytes(Method::code_offset()));
aoqi@1 1286 __ beq(AT, R0, skip_fixup);
aoqi@1 1287 __ delayed()->nop();
aoqi@1 1288 __ bind(missed);
aoqi@1 1289 // __ move(AT, (int)&jerome7);
aoqi@1 1290 // __ sw(RA, AT, 0);
aoqi@1 1291
aoqi@1 1292 __ jmp(ic_miss, relocInfo::runtime_call_type);
aoqi@1 1293 __ delayed()->nop();
aoqi@1 1294 }
aoqi@1 1295
aoqi@1 1296 address c2i_entry = __ pc();
aoqi@1 1297
aoqi@1 1298 agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
aoqi@1 1299
aoqi@1 1300 __ flush();
aoqi@1 1301 return AdapterHandlerLibrary::new_entry(fingerprint,i2c_entry, c2i_entry, c2i_unverified_entry);
aoqi@1 1302
aoqi@1 1303 }
aoqi@1 1304 /*
aoqi@1 1305 // Helper function for native calling conventions
aoqi@1 1306 static VMReg int_stk_helper( int i ) {
aoqi@1 1307 // Bias any stack based VMReg we get by ignoring the window area
aoqi@1 1308 // but not the register parameter save area.
aoqi@1 1309 //
aoqi@1 1310 // This is strange for the following reasons. We'd normally expect
aoqi@1 1311 // the calling convention to return an VMReg for a stack slot
aoqi@1 1312 // completely ignoring any abi reserved area. C2 thinks of that
aoqi@1 1313 // abi area as only out_preserve_stack_slots. This does not include
aoqi@1 1314 // the area allocated by the C abi to store down integer arguments
aoqi@1 1315 // because the java calling convention does not use it. So
aoqi@1 1316 // since c2 assumes that there are only out_preserve_stack_slots
aoqi@1 1317 // to bias the optoregs (which impacts VMRegs) when actually referencing any actual stack
aoqi@1 1318 // location the c calling convention must add in this bias amount
aoqi@1 1319 // to make up for the fact that the out_preserve_stack_slots is
aoqi@1 1320 // insufficient for C calls. What a mess. I sure hope those 6
aoqi@1 1321 // stack words were worth it on every java call!
aoqi@1 1322
aoqi@1 1323 // Another way of cleaning this up would be for out_preserve_stack_slots
aoqi@1 1324 // to take a parameter to say whether it was C or java calling conventions.
aoqi@1 1325 // Then things might look a little better (but not much).
aoqi@1 1326
aoqi@1 1327 int mem_parm_offset = i - SPARC_ARGS_IN_REGS_NUM;
aoqi@1 1328 if( mem_parm_offset < 0 ) {
aoqi@1 1329 return as_oRegister(i)->as_VMReg();
aoqi@1 1330 } else {
aoqi@1 1331 int actual_offset = (mem_parm_offset + frame::memory_parameter_word_sp_offset) * VMRegImpl::slots_per_word;
aoqi@1 1332 // Now return a biased offset that will be correct when out_preserve_slots is added back in
aoqi@1 1333 return VMRegImpl::stack2reg(actual_offset - SharedRuntime::out_preserve_stack_slots());
aoqi@1 1334 }
aoqi@1 1335 }
aoqi@1 1336 */
aoqi@1 1337
aoqi@1 1338
aoqi@1 1339 int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
aoqi@1 1340 VMRegPair *regs,
aoqi@1 1341 VMRegPair *regs2,
aoqi@1 1342 int total_args_passed) {
aoqi@1 1343 assert(regs2 == NULL, "not needed on MIPS");
aoqi@1 1344 #ifdef aoqi_test
aoqi@1 1345 tty->print_cr(" SharedRuntime::%s :%d total_args_passed:%d", __func__, __LINE__, total_args_passed);
aoqi@1 1346 #endif
aoqi@1 1347 // Return the number of VMReg stack_slots needed for the args.
aoqi@1 1348 // This value does not include an abi space (like register window
aoqi@1 1349 // save area).
aoqi@1 1350
aoqi@1 1351 // The native convention is V8 if !LP64
aoqi@1 1352 // The LP64 convention is the V9 convention which is slightly more sane.
aoqi@1 1353
aoqi@1 1354 // We return the amount of VMReg stack slots we need to reserve for all
aoqi@1 1355 // the arguments NOT counting out_preserve_stack_slots. Since we always
aoqi@1 1356 // have space for storing at least 6 registers to memory we start with that.
aoqi@1 1357 // See int_stk_helper for a further discussion.
aoqi@1 1358 // We return the amount of VMRegImpl stack slots we need to reserve for all
aoqi@1 1359 // the arguments NOT counting out_preserve_stack_slots.
aoqi@1 1360 static const Register INT_ArgReg[Argument::n_register_parameters] = {
aoqi@1 1361 A0, A1, A2, A3, A4, A5, A6, A7
aoqi@1 1362 };
aoqi@1 1363 static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters] = {
aoqi@1 1364 F12, F13, F14, F15, F16, F17, F18, F19
aoqi@1 1365 };
aoqi@1 1366 uint args = 0;
aoqi@1 1367 uint stk_args = 0; // inc by 2 each time
aoqi@1 1368
aoqi@1 1369 /* Example:
aoqi@1 1370 --- n java.lang.UNIXProcess::forkAndExec
aoqi@1 1371 private native int forkAndExec(byte[] prog,
aoqi@1 1372 byte[] argBlock, int argc,
aoqi@1 1373 byte[] envBlock, int envc,
aoqi@1 1374 byte[] dir,
aoqi@1 1375 boolean redirectErrorStream,
aoqi@1 1376 FileDescriptor stdin_fd,
aoqi@1 1377 FileDescriptor stdout_fd,
aoqi@1 1378 FileDescriptor stderr_fd)
aoqi@1 1379 JNIEXPORT jint JNICALL
aoqi@1 1380 Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
aoqi@1 1381 jobject process,
aoqi@1 1382 jbyteArray prog,
aoqi@1 1383 jbyteArray argBlock, jint argc,
aoqi@1 1384 jbyteArray envBlock, jint envc,
aoqi@1 1385 jbyteArray dir,
aoqi@1 1386 jboolean redirectErrorStream,
aoqi@1 1387 jobject stdin_fd,
aoqi@1 1388 jobject stdout_fd,
aoqi@1 1389 jobject stderr_fd)
aoqi@1 1390
aoqi@1 1391 ::c_calling_convention
aoqi@1 1392 0: // env <-- a0
aoqi@1 1393 1: L // klass/obj <-- t0 => a1
aoqi@1 1394 2: [ // prog[] <-- a0 => a2
aoqi@1 1395 3: [ // argBlock[] <-- a1 => a3
aoqi@1 1396 4: I // argc
aoqi@1 1397 5: [ // envBlock[] <-- a3 => a5
aoqi@1 1398 6: I // envc
aoqi@1 1399 7: [ // dir[] <-- a5 => a7
aoqi@1 1400 8: Z // redirectErrorStream a6 => sp[0]
aoqi@1 1401 9: L // stdin a7 => sp[8]
aoqi@1 1402 10: L // stdout fp[16] => sp[16]
aoqi@1 1403 11: L // stderr fp[24] => sp[24]
aoqi@1 1404 */
aoqi@1 1405 for (int i = 0; i < total_args_passed; i++) {
aoqi@1 1406 switch (sig_bt[i]) {
aoqi@1 1407 case T_VOID: // Halves of longs and doubles
aoqi@1 1408 assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
aoqi@1 1409 regs[i].set_bad();
aoqi@1 1410 break;
aoqi@1 1411 case T_BOOLEAN:
aoqi@1 1412 case T_CHAR:
aoqi@1 1413 case T_BYTE:
aoqi@1 1414 case T_SHORT:
aoqi@1 1415 case T_INT:
aoqi@1 1416 if (args < Argument::n_register_parameters) {
aoqi@1 1417 regs[i].set1(INT_ArgReg[args++]->as_VMReg());
aoqi@1 1418 } else {
aoqi@1 1419 regs[i].set1(VMRegImpl::stack2reg(stk_args));
aoqi@1 1420 stk_args += 2;
aoqi@1 1421 }
aoqi@1 1422 break;
aoqi@1 1423 case T_LONG:
aoqi@1 1424 assert(sig_bt[i + 1] == T_VOID, "expecting half");
aoqi@1 1425 // fall through
aoqi@1 1426 case T_OBJECT:
aoqi@1 1427 case T_ARRAY:
aoqi@1 1428 case T_ADDRESS:
aoqi@1 1429 case T_METADATA:
aoqi@1 1430 if (args < Argument::n_register_parameters) {
aoqi@1 1431 regs[i].set2(INT_ArgReg[args++]->as_VMReg());
aoqi@1 1432 } else {
aoqi@1 1433 regs[i].set2(VMRegImpl::stack2reg(stk_args));
aoqi@1 1434 stk_args += 2;
aoqi@1 1435 }
aoqi@1 1436 break;
aoqi@1 1437 case T_FLOAT:
aoqi@1 1438 if (args < Argument::n_float_register_parameters) {
aoqi@1 1439 regs[i].set1(FP_ArgReg[args++]->as_VMReg());
aoqi@1 1440 } else {
aoqi@1 1441 regs[i].set1(VMRegImpl::stack2reg(stk_args));
aoqi@1 1442 stk_args += 2;
aoqi@1 1443 }
aoqi@1 1444 break;
aoqi@1 1445 case T_DOUBLE:
aoqi@1 1446 assert(sig_bt[i + 1] == T_VOID, "expecting half");
aoqi@1 1447 if (args < Argument::n_float_register_parameters) {
aoqi@1 1448 regs[i].set2(FP_ArgReg[args++]->as_VMReg());
aoqi@1 1449 } else {
aoqi@1 1450 regs[i].set2(VMRegImpl::stack2reg(stk_args));
aoqi@1 1451 stk_args += 2;
aoqi@1 1452 }
aoqi@1 1453 break;
aoqi@1 1454 default:
aoqi@1 1455 ShouldNotReachHere();
aoqi@1 1456 break;
aoqi@1 1457 }
aoqi@1 1458 }
aoqi@1 1459
aoqi@1 1460 return round_to(stk_args, 2);
aoqi@1 1461 }
aoqi@1 1462 /*
aoqi@1 1463 int SharedRuntime::c_calling_convention_jni(const BasicType *sig_bt,
aoqi@1 1464 VMRegPair *regs,
aoqi@1 1465 int total_args_passed) {
aoqi@1 1466 // We return the amount of VMRegImpl stack slots we need to reserve for all
aoqi@1 1467 // the arguments NOT counting out_preserve_stack_slots.
aoqi@1 1468 bool unalign = 0;
aoqi@1 1469 uint stack = 0; // All arguments on stack
aoqi@1 1470 #ifdef aoqi_test
aoqi@1 1471 tty->print_cr(" SharedRuntime::%s :%d total_args_passed:%d", __func__, __LINE__, total_args_passed);
aoqi@1 1472 #endif
aoqi@1 1473
aoqi@1 1474 for( int i = 0; i < total_args_passed; i++) {
aoqi@1 1475 // From the type and the argument number (count) compute the location
aoqi@1 1476 switch( sig_bt[i] ) {
aoqi@1 1477 case T_BOOLEAN:
aoqi@1 1478 case T_CHAR:
aoqi@1 1479 case T_FLOAT:
aoqi@1 1480 case T_BYTE:
aoqi@1 1481 case T_SHORT:
aoqi@1 1482 case T_INT:
aoqi@1 1483 case T_OBJECT:
aoqi@1 1484 case T_ARRAY:
aoqi@1 1485 case T_ADDRESS:
aoqi@1 1486 regs[i].set1(VMRegImpl::stack2reg(stack++));
aoqi@1 1487 unalign = !unalign;
aoqi@1 1488 break;
aoqi@1 1489 case T_LONG:
aoqi@1 1490 case T_DOUBLE: // The stack numbering is reversed from Java
aoqi@1 1491 // Since C arguments do not get reversed, the ordering for
aoqi@1 1492 // doubles on the stack must be opposite the Java convention
aoqi@1 1493 assert(sig_bt[i+1] == T_VOID, "missing Half" );
aoqi@1 1494 if(unalign){
aoqi@1 1495 stack += 1;
aoqi@1 1496 unalign = ! unalign;
aoqi@1 1497 }
aoqi@1 1498 regs[i].set2(VMRegImpl::stack2reg(stack));
aoqi@1 1499 stack += 2;
aoqi@1 1500 break;
aoqi@1 1501 case T_VOID: regs[i].set_bad(); break;
aoqi@1 1502 default:
aoqi@1 1503 ShouldNotReachHere();
aoqi@1 1504 break;
aoqi@1 1505 }
aoqi@1 1506 }
aoqi@1 1507 return stack;
aoqi@1 1508 }
aoqi@1 1509 */
aoqi@1 1510
aoqi@1 1511 // ---------------------------------------------------------------------------
aoqi@1 1512 void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
aoqi@1 1513 // We always ignore the frame_slots arg and just use the space just below frame pointer
aoqi@1 1514 // which by this time is free to use
aoqi@1 1515 switch (ret_type) {
aoqi@1 1516 case T_FLOAT:
aoqi@1 1517 __ swc1(FSF, FP, -wordSize);
aoqi@1 1518 break;
aoqi@1 1519 case T_DOUBLE:
aoqi@1 1520 __ sdc1(FSF, FP, -wordSize );
aoqi@1 1521 break;
aoqi@1 1522 case T_VOID: break;
aoqi@1 1523 case T_LONG:
aoqi@1 1524 __ sd(V0, FP, -wordSize);
aoqi@1 1525 break;
aoqi@1 1526 case T_OBJECT:
aoqi@1 1527 case T_ARRAY:
aoqi@1 1528 __ sd(V0, FP, -wordSize);
aoqi@1 1529 break;
aoqi@1 1530 default: {
aoqi@1 1531 __ sw(V0, FP, -wordSize);
aoqi@1 1532 }
aoqi@1 1533 }
aoqi@1 1534 }
aoqi@1 1535
aoqi@1 1536 void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) {
aoqi@1 1537 // We always ignore the frame_slots arg and just use the space just below frame pointer
aoqi@1 1538 // which by this time is free to use
aoqi@1 1539 switch (ret_type) {
aoqi@1 1540 case T_FLOAT:
aoqi@1 1541 __ lwc1(FSF, FP, -wordSize);
aoqi@1 1542 break;
aoqi@1 1543 case T_DOUBLE:
aoqi@1 1544 __ ldc1(FSF, FP, -wordSize );
aoqi@1 1545 break;
aoqi@1 1546 case T_LONG:
aoqi@1 1547 __ ld(V0, FP, -wordSize);
aoqi@1 1548 break;
aoqi@1 1549 case T_VOID: break;
aoqi@1 1550 case T_OBJECT:
aoqi@1 1551 case T_ARRAY:
aoqi@1 1552 __ ld(V0, FP, -wordSize);
aoqi@1 1553 break;
aoqi@1 1554 default: {
aoqi@1 1555 __ lw(V0, FP, -wordSize);
aoqi@1 1556 }
aoqi@1 1557 }
aoqi@1 1558 }
aoqi@1 1559
aoqi@1 1560 static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) {
aoqi@1 1561 for ( int i = first_arg ; i < arg_count ; i++ ) {
aoqi@1 1562 if (args[i].first()->is_Register()) {
aoqi@1 1563 __ push(args[i].first()->as_Register());
aoqi@1 1564 } else if (args[i].first()->is_FloatRegister()) {
aoqi@1 1565 __ push(args[i].first()->as_FloatRegister());
aoqi@1 1566 }
aoqi@1 1567 }
aoqi@1 1568 }
aoqi@1 1569
aoqi@1 1570 static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) {
aoqi@1 1571 for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) {
aoqi@1 1572 if (args[i].first()->is_Register()) {
aoqi@1 1573 __ pop(args[i].first()->as_Register());
aoqi@1 1574 } else if (args[i].first()->is_FloatRegister()) {
aoqi@1 1575 __ pop(args[i].first()->as_FloatRegister());
aoqi@1 1576 }
aoqi@1 1577 }
aoqi@1 1578 }
aoqi@1 1579
aoqi@1 1580 // A simple move of integer like type
aoqi@1 1581 static void simple_move32(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1582 if (src.first()->is_stack()) {
aoqi@1 1583 if (dst.first()->is_stack()) {
aoqi@1 1584 // stack to stack
aoqi@1 1585 __ lw(AT, FP, reg2offset_in(src.first()));
aoqi@1 1586 __ sd(AT,SP, reg2offset_out(dst.first()));
aoqi@1 1587 } else {
aoqi@1 1588 // stack to reg
aoqi@1 1589 //__ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
aoqi@1 1590 __ lw(dst.first()->as_Register(), FP, reg2offset_in(src.first()));
aoqi@1 1591 }
aoqi@1 1592 } else if (dst.first()->is_stack()) {
aoqi@1 1593 // reg to stack
aoqi@1 1594 __ sd(src.first()->as_Register(), SP, reg2offset_out(dst.first()));
aoqi@1 1595 } else {
aoqi@1 1596 //__ mov(src.first()->as_Register(), dst.first()->as_Register());
aoqi@1 1597 if (dst.first() != src.first()){
aoqi@1 1598 __ move(dst.first()->as_Register(), src.first()->as_Register()); // fujie error:dst.first()
aoqi@1 1599 }
aoqi@1 1600 }
aoqi@1 1601 }
aoqi@1 1602 /*
aoqi@1 1603 // On 64 bit we will store integer like items to the stack as
aoqi@1 1604 // 64 bits items (sparc abi) even though java would only store
aoqi@1 1605 // 32bits for a parameter. On 32bit it will simply be 32 bits
aoqi@1 1606 // So this routine will do 32->32 on 32bit and 32->64 on 64bit
aoqi@1 1607 static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1608 if (src.first()->is_stack()) {
aoqi@1 1609 if (dst.first()->is_stack()) {
aoqi@1 1610 // stack to stack
aoqi@1 1611 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5);
aoqi@1 1612 __ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 1613 } else {
aoqi@1 1614 // stack to reg
aoqi@1 1615 __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
aoqi@1 1616 }
aoqi@1 1617 } else if (dst.first()->is_stack()) {
aoqi@1 1618 // reg to stack
aoqi@1 1619 __ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 1620 } else {
aoqi@1 1621 __ mov(src.first()->as_Register(), dst.first()->as_Register());
aoqi@1 1622 }
aoqi@1 1623 }
aoqi@1 1624 */
aoqi@1 1625
aoqi@1 1626 // An oop arg. Must pass a handle not the oop itself
aoqi@1 1627 static void object_move(MacroAssembler* masm,
aoqi@1 1628 OopMap* map,
aoqi@1 1629 int oop_handle_offset,
aoqi@1 1630 int framesize_in_slots,
aoqi@1 1631 VMRegPair src,
aoqi@1 1632 VMRegPair dst,
aoqi@1 1633 bool is_receiver,
aoqi@1 1634 int* receiver_offset) {
aoqi@1 1635
aoqi@1 1636 // must pass a handle. First figure out the location we use as a handle
aoqi@1 1637
aoqi@1 1638 //FIXME, for mips, dst can be register
aoqi@1 1639 if (src.first()->is_stack()) {
aoqi@1 1640 // Oop is already on the stack as an argument
aoqi@1 1641 Register rHandle = V0;
aoqi@1 1642 Label nil;
aoqi@1 1643 //__ xorl(rHandle, rHandle);
aoqi@1 1644 __ xorr(rHandle, rHandle, rHandle);
aoqi@1 1645 //__ cmpl(Address(ebp, reg2offset_in(src.first())), NULL_WORD);
aoqi@1 1646 __ ld(AT, FP, reg2offset_in(src.first()));
aoqi@1 1647 //__ jcc(Assembler::equal, nil);
aoqi@1 1648 __ beq(AT,R0, nil);
aoqi@1 1649 __ delayed()->nop();
aoqi@1 1650 // __ leal(rHandle, Address(ebp, reg2offset_in(src.first())));
aoqi@1 1651 __ lea(rHandle, Address(FP, reg2offset_in(src.first())));
aoqi@1 1652 __ bind(nil);
aoqi@1 1653 //__ movl(Address(esp, reg2offset_out(dst.first())), rHandle);
aoqi@1 1654 if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first()));
aoqi@1 1655 else __ move( (dst.first())->as_Register(),rHandle);
aoqi@1 1656 //if dst is register
aoqi@1 1657 //FIXME, do mips need out preserve stack slots?
aoqi@1 1658 int offset_in_older_frame = src.first()->reg2stack()
aoqi@1 1659 + SharedRuntime::out_preserve_stack_slots();
aoqi@1 1660 map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots));
aoqi@1 1661 if (is_receiver) {
aoqi@1 1662 *receiver_offset = (offset_in_older_frame
aoqi@1 1663 + framesize_in_slots) * VMRegImpl::stack_slot_size;
aoqi@1 1664 }
aoqi@1 1665 } else {
aoqi@1 1666 // Oop is in an a register we must store it to the space we reserve
aoqi@1 1667 // on the stack for oop_handles
aoqi@1 1668 const Register rOop = src.first()->as_Register();
aoqi@1 1669 assert( (rOop->encoding() >= A0->encoding()) && (rOop->encoding() <= T0->encoding()),"wrong register");
aoqi@1 1670 // const Register rHandle = eax;
aoqi@1 1671 const Register rHandle = V0;
aoqi@1 1672 //Important: refer to java_calling_convertion
aoqi@1 1673 int oop_slot = (rOop->encoding() - A0->encoding()) * VMRegImpl::slots_per_word + oop_handle_offset;
aoqi@1 1674 int offset = oop_slot*VMRegImpl::stack_slot_size;
aoqi@1 1675 Label skip;
aoqi@1 1676 // __ movl(Address(esp, offset), rOop);
aoqi@1 1677 __ sd( rOop , SP, offset );
aoqi@1 1678 map->set_oop(VMRegImpl::stack2reg(oop_slot));
aoqi@1 1679 // __ xorl(rHandle, rHandle);
aoqi@1 1680 __ xorr( rHandle, rHandle, rHandle);
aoqi@1 1681 //__ cmpl(rOop, NULL_WORD);
aoqi@1 1682 // __ jcc(Assembler::equal, skip);
aoqi@1 1683 __ beq(rOop, R0, skip);
aoqi@1 1684 __ delayed()->nop();
aoqi@1 1685 // __ leal(rHandle, Address(esp, offset));
aoqi@1 1686 __ lea(rHandle, Address(SP, offset));
aoqi@1 1687 __ bind(skip);
aoqi@1 1688 // Store the handle parameter
aoqi@1 1689 //__ movl(Address(esp, reg2offset_out(dst.first())), rHandle);
aoqi@1 1690 if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first()));
aoqi@1 1691 else __ move((dst.first())->as_Register(), rHandle);
aoqi@1 1692 //if dst is register
aoqi@1 1693
aoqi@1 1694 if (is_receiver) {
aoqi@1 1695 *receiver_offset = offset;
aoqi@1 1696 }
aoqi@1 1697 }
aoqi@1 1698 }
aoqi@1 1699
aoqi@1 1700 // A float arg may have to do float reg int reg conversion
aoqi@1 1701 static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1702 assert(!src.second()->is_valid() && !dst.second()->is_valid(), "bad float_move");
aoqi@1 1703
aoqi@1 1704 if (src.first()->is_stack()) {
aoqi@1 1705 if(dst.first()->is_stack()){
aoqi@1 1706 // __ movl(eax, Address(ebp, reg2offset_in(src.first())));
aoqi@1 1707 __ lwc1(F12 , FP, reg2offset_in(src.first()));
aoqi@1 1708 // __ movl(Address(esp, reg2offset_out(dst.first())), eax);
aoqi@1 1709 __ swc1(F12 ,SP, reg2offset_out(dst.first()));
aoqi@1 1710 }
aoqi@1 1711 else
aoqi@1 1712 __ lwc1( dst.first()->as_FloatRegister(), FP, reg2offset_in(src.first()));
aoqi@1 1713 } else {
aoqi@1 1714 // reg to stack
aoqi@1 1715 // __ movss(Address(esp, reg2offset_out(dst.first())),
aoqi@1 1716 // src.first()->as_XMMRegister());
aoqi@1 1717 // __ movl(Address(esp, reg2offset_out(dst.first())), eax);
aoqi@1 1718 if(dst.first()->is_stack())
aoqi@1 1719 __ swc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first()));
aoqi@1 1720 else
aoqi@1 1721 __ mov_s( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
aoqi@1 1722 }
aoqi@1 1723 }
aoqi@1 1724 /*
aoqi@1 1725 static void split_long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1726 VMRegPair src_lo(src.first());
aoqi@1 1727 VMRegPair src_hi(src.second());
aoqi@1 1728 VMRegPair dst_lo(dst.first());
aoqi@1 1729 VMRegPair dst_hi(dst.second());
aoqi@1 1730 simple_move32(masm, src_lo, dst_lo);
aoqi@1 1731 simple_move32(masm, src_hi, dst_hi);
aoqi@1 1732 }
aoqi@1 1733 */
aoqi@1 1734 // A long move
aoqi@1 1735 static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1736
aoqi@1 1737 // The only legal possibility for a long_move VMRegPair is:
aoqi@1 1738 // 1: two stack slots (possibly unaligned)
aoqi@1 1739 // as neither the java or C calling convention will use registers
aoqi@1 1740 // for longs.
aoqi@1 1741
aoqi@1 1742 if (src.first()->is_stack()) {
aoqi@1 1743 assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack");
aoqi@1 1744 // __ movl(eax, Address(ebp, reg2offset_in(src.first())));
aoqi@1 1745 if( dst.first()->is_stack()){
aoqi@1 1746 __ ld(AT, FP, reg2offset_in(src.first()));
aoqi@1 1747 // __ movl(ebx, address(ebp, reg2offset_in(src.second())));
aoqi@1 1748 //__ lw(V0, FP, reg2offset_in(src.second()));
aoqi@1 1749 // __ movl(address(esp, reg2offset_out(dst.first())), eax);
aoqi@1 1750 __ sd(AT, SP, reg2offset_out(dst.first()));
aoqi@1 1751 // __ movl(address(esp, reg2offset_out(dst.second())), ebx);
aoqi@1 1752 //__ sw(V0, SP, reg2offset_out(dst.second()));
aoqi@1 1753 } else{
aoqi@1 1754 __ ld( (dst.first())->as_Register() , FP, reg2offset_in(src.first()));
aoqi@1 1755 //__ lw( (dst.second())->as_Register(), FP, reg2offset_in(src.second()));
aoqi@1 1756 }
aoqi@1 1757 } else {
aoqi@1 1758 if( dst.first()->is_stack()){
aoqi@1 1759 __ sd( (src.first())->as_Register(), SP, reg2offset_out(dst.first()));
aoqi@1 1760 //__ sw( (src.second())->as_Register(), SP, reg2offset_out(dst.second()));
aoqi@1 1761 } else{
aoqi@1 1762 __ move( (dst.first())->as_Register() , (src.first())->as_Register());
aoqi@1 1763 //__ move( (dst.second())->as_Register(), (src.second())->as_Register());
aoqi@1 1764 }
aoqi@1 1765 }
aoqi@1 1766 }
aoqi@1 1767
aoqi@1 1768 // A double move
aoqi@1 1769 static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
aoqi@1 1770
aoqi@1 1771 // The only legal possibilities for a double_move VMRegPair are:
aoqi@1 1772 // The painful thing here is that like long_move a VMRegPair might be
aoqi@1 1773
aoqi@1 1774 // Because of the calling convention we know that src is either
aoqi@1 1775 // 1: a single physical register (xmm registers only)
aoqi@1 1776 // 2: two stack slots (possibly unaligned)
aoqi@1 1777 // dst can only be a pair of stack slots.
aoqi@1 1778
aoqi@1 1779 // assert(dst.first()->is_stack() && (src.first()->is_XMMRegister() ||
aoqi@1 1780 // src.first()->is_stack()), "bad args");
aoqi@1 1781 // assert(dst.first()->is_stack() || src.first()->is_stack()), "bad args");
aoqi@1 1782
aoqi@1 1783 if (src.first()->is_stack()) {
aoqi@1 1784 // source is all stack
aoqi@1 1785 // __ movl(eax, Address(ebp, reg2offset_in(src.first())));
aoqi@1 1786 if( dst.first()->is_stack()){
aoqi@1 1787 __ ldc1(F12, FP, reg2offset_in(src.first()));
aoqi@1 1788 //__ movl(ebx, Address(ebp, reg2offset_in(src.second())));
aoqi@1 1789 //__ lwc1(F14, FP, reg2offset_in(src.second()));
aoqi@1 1790
aoqi@1 1791 // __ movl(Address(esp, reg2offset_out(dst.first())), eax);
aoqi@1 1792 __ sdc1(F12, SP, reg2offset_out(dst.first()));
aoqi@1 1793 // __ movl(Address(esp, reg2offset_out(dst.second())), ebx);
aoqi@1 1794 //__ swc1(F14, SP, reg2offset_out(dst.second()));
aoqi@1 1795 } else{
aoqi@1 1796 __ ldc1( (dst.first())->as_FloatRegister(), FP, reg2offset_in(src.first()));
aoqi@1 1797 //__ lwc1( (dst.second())->as_FloatRegister(), FP, reg2offset_in(src.second()));
aoqi@1 1798 }
aoqi@1 1799
aoqi@1 1800 } else {
aoqi@1 1801 // reg to stack
aoqi@1 1802 // No worries about stack alignment
aoqi@1 1803 // __ movsd(Address(esp, reg2offset_out(dst.first())), src.first()->as_XMMRegister());
aoqi@1 1804 if( dst.first()->is_stack()){
aoqi@1 1805 __ sdc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first()));
aoqi@1 1806 //__ swc1( src.second()->as_FloatRegister(),SP, reg2offset_out(dst.second()));
aoqi@1 1807 }
aoqi@1 1808 else
aoqi@1 1809 __ mov_d( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister());
aoqi@1 1810 //__ mov_s( dst.second()->as_FloatRegister(), src.second()->as_FloatRegister());
aoqi@1 1811
aoqi@1 1812 }
aoqi@1 1813 }
aoqi@1 1814
aoqi@1 1815 static void verify_oop_args(MacroAssembler* masm,
aoqi@1 1816 methodHandle method,
aoqi@1 1817 const BasicType* sig_bt,
aoqi@1 1818 const VMRegPair* regs) {
aoqi@1 1819 Register temp_reg = T9; // not part of any compiled calling seq
aoqi@1 1820 if (VerifyOops) {
aoqi@1 1821 for (int i = 0; i < method->size_of_parameters(); i++) {
aoqi@1 1822 if (sig_bt[i] == T_OBJECT ||
aoqi@1 1823 sig_bt[i] == T_ARRAY) {
aoqi@1 1824 VMReg r = regs[i].first();
aoqi@1 1825 assert(r->is_valid(), "bad oop arg");
aoqi@1 1826 if (r->is_stack()) {
aoqi@1 1827 // __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1828 __ ld(temp_reg, Address(SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1829 __ verify_oop(temp_reg);
aoqi@1 1830 } else {
aoqi@1 1831 __ verify_oop(r->as_Register());
aoqi@1 1832 }
aoqi@1 1833 }
aoqi@1 1834 }
aoqi@1 1835 }
aoqi@1 1836 }
aoqi@1 1837
aoqi@1 1838 static void gen_special_dispatch(MacroAssembler* masm,
aoqi@1 1839 methodHandle method,
aoqi@1 1840 const BasicType* sig_bt,
aoqi@1 1841 const VMRegPair* regs) {
aoqi@1 1842 verify_oop_args(masm, method, sig_bt, regs);
aoqi@1 1843 vmIntrinsics::ID iid = method->intrinsic_id();
aoqi@1 1844
aoqi@1 1845 // Now write the args into the outgoing interpreter space
aoqi@1 1846 bool has_receiver = false;
aoqi@1 1847 Register receiver_reg = noreg;
aoqi@1 1848 int member_arg_pos = -1;
aoqi@1 1849 Register member_reg = noreg;
aoqi@1 1850 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid);
aoqi@1 1851 if (ref_kind != 0) {
aoqi@1 1852 member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument
aoqi@1 1853 // member_reg = rbx; // known to be free at this point
aoqi@1 1854 member_reg = S3; // known to be free at this point
aoqi@1 1855 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
aoqi@1 1856 } else if (iid == vmIntrinsics::_invokeBasic) {
aoqi@1 1857 has_receiver = true;
aoqi@1 1858 } else {
aoqi@1 1859 fatal(err_msg_res("unexpected intrinsic id %d", iid));
aoqi@1 1860 }
aoqi@1 1861
aoqi@1 1862 if (member_reg != noreg) {
aoqi@1 1863 // Load the member_arg into register, if necessary.
aoqi@1 1864 SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs);
aoqi@1 1865 VMReg r = regs[member_arg_pos].first();
aoqi@1 1866 if (r->is_stack()) {
aoqi@1 1867 // __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1868 __ ld(member_reg, Address(SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1869 } else {
aoqi@1 1870 // no data motion is needed
aoqi@1 1871 member_reg = r->as_Register();
aoqi@1 1872 }
aoqi@1 1873 }
aoqi@1 1874
aoqi@1 1875 if (has_receiver) {
aoqi@1 1876 // Make sure the receiver is loaded into a register.
aoqi@1 1877 assert(method->size_of_parameters() > 0, "oob");
aoqi@1 1878 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
aoqi@1 1879 VMReg r = regs[0].first();
aoqi@1 1880 assert(r->is_valid(), "bad receiver arg");
aoqi@1 1881 if (r->is_stack()) {
aoqi@1 1882 // Porting note: This assumes that compiled calling conventions always
aoqi@1 1883 // pass the receiver oop in a register. If this is not true on some
aoqi@1 1884 // platform, pick a temp and load the receiver from stack.
aoqi@1 1885 fatal("receiver always in a register");
aoqi@1 1886 // receiver_reg = j_rarg0; // known to be free at this point
aoqi@1 1887 receiver_reg = SSR; // known to be free at this point
aoqi@1 1888 // __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1889 __ ld(receiver_reg, Address(SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
aoqi@1 1890 } else {
aoqi@1 1891 // no data motion is needed
aoqi@1 1892 receiver_reg = r->as_Register();
aoqi@1 1893 }
aoqi@1 1894 }
aoqi@1 1895
aoqi@1 1896 // Figure out which address we are really jumping to:
aoqi@1 1897 MethodHandles::generate_method_handle_dispatch(masm, iid,
aoqi@1 1898 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
aoqi@1 1899 }
aoqi@1 1900
aoqi@1 1901 // ---------------------------------------------------------------------------
aoqi@1 1902 // Generate a native wrapper for a given method. The method takes arguments
aoqi@1 1903 // in the Java compiled code convention, marshals them to the native
aoqi@1 1904 // convention (handlizes oops, etc), transitions to native, makes the call,
aoqi@1 1905 // returns to java state (possibly blocking), unhandlizes any result and
aoqi@1 1906 // returns.
aoqi@1 1907 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
aoqi@1 1908 methodHandle method,
aoqi@1 1909 int compile_id,
aoqi@1 1910 BasicType *in_sig_bt,
aoqi@1 1911 VMRegPair *in_regs,
aoqi@1 1912 BasicType ret_type) {
aoqi@1 1913
aoqi@1 1914 if (method->is_method_handle_intrinsic()) {
aoqi@1 1915 vmIntrinsics::ID iid = method->intrinsic_id();
aoqi@1 1916 intptr_t start = (intptr_t)__ pc();
aoqi@1 1917 int vep_offset = ((intptr_t)__ pc()) - start;
aoqi@1 1918
aoqi@1 1919 gen_special_dispatch(masm,
aoqi@1 1920 method,
aoqi@1 1921 in_sig_bt,
aoqi@1 1922 in_regs);
aoqi@1 1923
aoqi@1 1924 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period
aoqi@1 1925 __ flush();
aoqi@1 1926 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually
aoqi@1 1927 return nmethod::new_native_nmethod(method,
aoqi@1 1928 compile_id,
aoqi@1 1929 masm->code(),
aoqi@1 1930 vep_offset,
aoqi@1 1931 frame_complete,
aoqi@1 1932 stack_slots / VMRegImpl::slots_per_word,
aoqi@1 1933 in_ByteSize(-1),
aoqi@1 1934 in_ByteSize(-1),
aoqi@1 1935 (OopMapSet*)NULL);
aoqi@1 1936 }
aoqi@1 1937 bool is_critical_native = true;
aoqi@1 1938 address native_func = method->critical_native_function();
aoqi@1 1939 if (native_func == NULL) {
aoqi@1 1940 native_func = method->native_function();
aoqi@1 1941 is_critical_native = false;
aoqi@1 1942 }
aoqi@1 1943 assert(native_func != NULL, "must have function");
aoqi@1 1944
aoqi@1 1945 // Native nmethod wrappers never take possesion of the oop arguments.
aoqi@1 1946 // So the caller will gc the arguments. The only thing we need an
aoqi@1 1947 // oopMap for is if the call is static
aoqi@1 1948 //
aoqi@1 1949 // An OopMap for lock (and class if static), and one for the VM call itself
aoqi@1 1950 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 1951
aoqi@1 1952 // We have received a description of where all the java arg are located
aoqi@1 1953 // on entry to the wrapper. We need to convert these args to where
aoqi@1 1954 // the jni function will expect them. To figure out where they go
aoqi@1 1955 // we convert the java signature to a C signature by inserting
aoqi@1 1956 // the hidden arguments as arg[0] and possibly arg[1] (static method)
aoqi@1 1957
aoqi@1 1958 const int total_in_args = method->size_of_parameters();
aoqi@1 1959 int total_c_args = total_in_args;
aoqi@1 1960 if (!is_critical_native) {
aoqi@1 1961 total_c_args += 1;
aoqi@1 1962 if (method->is_static()) {
aoqi@1 1963 total_c_args++;
aoqi@1 1964 }
aoqi@1 1965 } else {
aoqi@1 1966 for (int i = 0; i < total_in_args; i++) {
aoqi@1 1967 if (in_sig_bt[i] == T_ARRAY) {
aoqi@1 1968 total_c_args++;
aoqi@1 1969 }
aoqi@1 1970 }
aoqi@1 1971 }
aoqi@1 1972
aoqi@1 1973 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
aoqi@1 1974 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args);
aoqi@1 1975 BasicType* in_elem_bt = NULL;
aoqi@1 1976
aoqi@1 1977 int argc = 0;
aoqi@1 1978 if (!is_critical_native) {
aoqi@1 1979 out_sig_bt[argc++] = T_ADDRESS;
aoqi@1 1980 if (method->is_static()) {
aoqi@1 1981 out_sig_bt[argc++] = T_OBJECT;
aoqi@1 1982 }
aoqi@1 1983
aoqi@1 1984 for (int i = 0; i < total_in_args ; i++ ) {
aoqi@1 1985 out_sig_bt[argc++] = in_sig_bt[i];
aoqi@1 1986 }
aoqi@1 1987 } else {
aoqi@1 1988 Thread* THREAD = Thread::current();
aoqi@1 1989 in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
aoqi@1 1990 SignatureStream ss(method->signature());
aoqi@1 1991 for (int i = 0; i < total_in_args ; i++ ) {
aoqi@1 1992 if (in_sig_bt[i] == T_ARRAY) {
aoqi@1 1993 // Arrays are passed as int, elem* pair
aoqi@1 1994 out_sig_bt[argc++] = T_INT;
aoqi@1 1995 out_sig_bt[argc++] = T_ADDRESS;
aoqi@1 1996 Symbol* atype = ss.as_symbol(CHECK_NULL);
aoqi@1 1997 const char* at = atype->as_C_string();
aoqi@1 1998 if (strlen(at) == 2) {
aoqi@1 1999 assert(at[0] == '[', "must be");
aoqi@1 2000 switch (at[1]) {
aoqi@1 2001 case 'B': in_elem_bt[i] = T_BYTE; break;
aoqi@1 2002 case 'C': in_elem_bt[i] = T_CHAR; break;
aoqi@1 2003 case 'D': in_elem_bt[i] = T_DOUBLE; break;
aoqi@1 2004 case 'F': in_elem_bt[i] = T_FLOAT; break;
aoqi@1 2005 case 'I': in_elem_bt[i] = T_INT; break;
aoqi@1 2006 case 'J': in_elem_bt[i] = T_LONG; break;
aoqi@1 2007 case 'S': in_elem_bt[i] = T_SHORT; break;
aoqi@1 2008 case 'Z': in_elem_bt[i] = T_BOOLEAN; break;
aoqi@1 2009 default: ShouldNotReachHere();
aoqi@1 2010 }
aoqi@1 2011 }
aoqi@1 2012 } else {
aoqi@1 2013 out_sig_bt[argc++] = in_sig_bt[i];
aoqi@1 2014 in_elem_bt[i] = T_VOID;
aoqi@1 2015 }
aoqi@1 2016 if (in_sig_bt[i] != T_VOID) {
aoqi@1 2017 assert(in_sig_bt[i] == ss.type(), "must match");
aoqi@1 2018 ss.next();
aoqi@1 2019 }
aoqi@1 2020 }
aoqi@1 2021 }
aoqi@1 2022
aoqi@1 2023 // Now figure out where the args must be stored and how much stack space
aoqi@1 2024 // they require (neglecting out_preserve_stack_slots but space for storing
aoqi@1 2025 // the 1st six register arguments). It's weird see int_stk_helper.
aoqi@1 2026 //
aoqi@1 2027 int out_arg_slots;
aoqi@1 2028 //out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args);
aoqi@1 2029 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args);
aoqi@1 2030
aoqi@1 2031 // Compute framesize for the wrapper. We need to handlize all oops in
aoqi@1 2032 // registers. We must create space for them here that is disjoint from
aoqi@1 2033 // the windowed save area because we have no control over when we might
aoqi@1 2034 // flush the window again and overwrite values that gc has since modified.
aoqi@1 2035 // (The live window race)
aoqi@1 2036 //
aoqi@1 2037 // We always just allocate 6 word for storing down these object. This allow
aoqi@1 2038 // us to simply record the base and use the Ireg number to decide which
aoqi@1 2039 // slot to use. (Note that the reg number is the inbound number not the
aoqi@1 2040 // outbound number).
aoqi@1 2041 // We must shuffle args to match the native convention, and include var-args space.
aoqi@1 2042
aoqi@1 2043 // Calculate the total number of stack slots we will need.
aoqi@1 2044
aoqi@1 2045 // First count the abi requirement plus all of the outgoing args
aoqi@1 2046 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
aoqi@1 2047
aoqi@1 2048 // Now the space for the inbound oop handle area
aoqi@1 2049 int total_save_slots = 9 * VMRegImpl::slots_per_word; // 9 arguments passed in registers
aoqi@1 2050 if (is_critical_native) {
aoqi@1 2051 // Critical natives may have to call out so they need a save area
aoqi@1 2052 // for register arguments.
aoqi@1 2053 int double_slots = 0;
aoqi@1 2054 int single_slots = 0;
aoqi@1 2055 for ( int i = 0; i < total_in_args; i++) {
aoqi@1 2056 if (in_regs[i].first()->is_Register()) {
aoqi@1 2057 const Register reg = in_regs[i].first()->as_Register();
aoqi@1 2058 switch (in_sig_bt[i]) {
aoqi@1 2059 case T_BOOLEAN:
aoqi@1 2060 case T_BYTE:
aoqi@1 2061 case T_SHORT:
aoqi@1 2062 case T_CHAR:
aoqi@1 2063 case T_INT: single_slots++; break;
aoqi@1 2064 case T_ARRAY: // specific to LP64 (7145024)
aoqi@1 2065 case T_LONG: double_slots++; break;
aoqi@1 2066 default: ShouldNotReachHere();
aoqi@1 2067 }
aoqi@1 2068 } else if (in_regs[i].first()->is_FloatRegister()) {
aoqi@1 2069 switch (in_sig_bt[i]) {
aoqi@1 2070 case T_FLOAT: single_slots++; break;
aoqi@1 2071 case T_DOUBLE: double_slots++; break;
aoqi@1 2072 default: ShouldNotReachHere();
aoqi@1 2073 }
aoqi@1 2074 }
aoqi@1 2075 }
aoqi@1 2076 total_save_slots = double_slots * 2 + single_slots;
aoqi@1 2077 // align the save area
aoqi@1 2078 if (double_slots != 0) {
aoqi@1 2079 stack_slots = round_to(stack_slots, 2);
aoqi@1 2080 }
aoqi@1 2081 }
aoqi@1 2082
aoqi@1 2083 int oop_handle_offset = stack_slots;
aoqi@1 2084 // stack_slots += 9*VMRegImpl::slots_per_word; // T0, A0 ~ A7
aoqi@1 2085 stack_slots += total_save_slots;
aoqi@1 2086
aoqi@1 2087 // Now any space we need for handlizing a klass if static method
aoqi@1 2088
aoqi@1 2089 int klass_slot_offset = 0;
aoqi@1 2090 int klass_offset = -1;
aoqi@1 2091 int lock_slot_offset = 0;
aoqi@1 2092 bool is_static = false;
aoqi@1 2093 //int oop_temp_slot_offset = 0;
aoqi@1 2094
aoqi@1 2095 if (method->is_static()) {
aoqi@1 2096 klass_slot_offset = stack_slots;
aoqi@1 2097 stack_slots += VMRegImpl::slots_per_word;
aoqi@1 2098 klass_offset = klass_slot_offset * VMRegImpl::stack_slot_size;
aoqi@1 2099 is_static = true;
aoqi@1 2100 }
aoqi@1 2101
aoqi@1 2102 // Plus a lock if needed
aoqi@1 2103
aoqi@1 2104 if (method->is_synchronized()) {
aoqi@1 2105 lock_slot_offset = stack_slots;
aoqi@1 2106 stack_slots += VMRegImpl::slots_per_word;
aoqi@1 2107 }
aoqi@1 2108
aoqi@1 2109 // Now a place to save return value or as a temporary for any gpr -> fpr moves
aoqi@1 2110 // + 2 for return address (which we own) and saved ebp
aoqi@1 2111 //stack_slots += 2;
aoqi@1 2112 stack_slots += 2 + 9 * VMRegImpl::slots_per_word; // (T0, A0, A1, A2, A3, A4, A5, A6, A7)
aoqi@1 2113
aoqi@1 2114 // Ok The space we have allocated will look like:
aoqi@1 2115 //
aoqi@1 2116 //
aoqi@1 2117 // FP-> | |
aoqi@1 2118 // |---------------------|
aoqi@1 2119 // | 2 slots for moves |
aoqi@1 2120 // |---------------------|
aoqi@1 2121 // | lock box (if sync) |
aoqi@1 2122 // |---------------------| <- lock_slot_offset
aoqi@1 2123 // | klass (if static) |
aoqi@1 2124 // |---------------------| <- klass_slot_offset
aoqi@1 2125 // | oopHandle area |
aoqi@1 2126 // |---------------------| <- oop_handle_offset
aoqi@1 2127 // | outbound memory |
aoqi@1 2128 // | based arguments |
aoqi@1 2129 // | |
aoqi@1 2130 // |---------------------|
aoqi@1 2131 // | vararg area |
aoqi@1 2132 // |---------------------|
aoqi@1 2133 // | |
aoqi@1 2134 // SP-> | out_preserved_slots |
aoqi@1 2135 //
aoqi@1 2136 //
aoqi@1 2137
aoqi@1 2138
aoqi@1 2139 // Now compute actual number of stack words we need rounding to make
aoqi@1 2140 // stack properly aligned.
aoqi@1 2141 stack_slots = round_to(stack_slots, StackAlignmentInSlots);
aoqi@1 2142
aoqi@1 2143 int stack_size = stack_slots * VMRegImpl::stack_slot_size;
aoqi@1 2144
aoqi@1 2145 intptr_t start = (intptr_t)__ pc();
aoqi@1 2146
aoqi@1 2147
aoqi@1 2148
aoqi@1 2149 // First thing make an ic check to see if we should even be here
aoqi@1 2150 address ic_miss = SharedRuntime::get_ic_miss_stub();
aoqi@1 2151
aoqi@1 2152 // We are free to use all registers as temps without saving them and
aoqi@1 2153 // restoring them except ebp. ebp is the only callee save register
aoqi@1 2154 // as far as the interpreter and the compiler(s) are concerned.
aoqi@1 2155
aoqi@1 2156 //refer to register_mips.hpp:IC_Klass
aoqi@1 2157 const Register ic_reg = T1;
aoqi@1 2158 const Register receiver = T0;
aoqi@1 2159 Label hit;
aoqi@1 2160 Label exception_pending;
aoqi@1 2161
aoqi@1 2162 __ verify_oop(receiver);
aoqi@1 2163 //__ lw(AT, receiver, oopDesc::klass_offset_in_bytes());
aoqi@1 2164 //add for compressedoops
aoqi@1 2165 __ load_klass(AT, receiver);
aoqi@1 2166 __ beq(AT, ic_reg, hit);
aoqi@1 2167 __ delayed()->nop();
aoqi@1 2168 __ jmp(ic_miss, relocInfo::runtime_call_type);
aoqi@1 2169 __ delayed()->nop();
aoqi@1 2170 // verified entry must be aligned for code patching.
aoqi@1 2171 // and the first 5 bytes must be in the same cache line
aoqi@1 2172 // if we align at 8 then we will be sure 5 bytes are in the same line
aoqi@1 2173 __ align(8);
aoqi@1 2174
aoqi@1 2175 __ bind(hit);
aoqi@1 2176
aoqi@1 2177
aoqi@1 2178 int vep_offset = ((intptr_t)__ pc()) - start;
aoqi@1 2179 #ifdef COMPILER1
aoqi@1 2180 if (InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) {
aoqi@1 2181 // Object.hashCode can pull the hashCode from the header word
aoqi@1 2182 // instead of doing a full VM transition once it's been computed.
aoqi@1 2183 // Since hashCode is usually polymorphic at call sites we can't do
aoqi@1 2184 // this optimization at the call site without a lot of work.
aoqi@1 2185 Label slowCase;
aoqi@1 2186 Register receiver = T0;
aoqi@1 2187 Register result = V0;
aoqi@1 2188 __ ld ( result, receiver, oopDesc::mark_offset_in_bytes());
aoqi@1 2189 // check if locked
aoqi@1 2190 __ andi(AT, result, markOopDesc::unlocked_value);
aoqi@1 2191 __ beq(AT, R0, slowCase);
aoqi@1 2192 __ delayed()->nop();
aoqi@1 2193 if (UseBiasedLocking) {
aoqi@1 2194 // Check if biased and fall through to runtime if so
aoqi@1 2195 __ andi (AT, result, markOopDesc::biased_lock_bit_in_place);
aoqi@1 2196 __ bne(AT,R0, slowCase);
aoqi@1 2197 __ delayed()->nop();
aoqi@1 2198 }
aoqi@1 2199 // get hash
aoqi@1 2200 __ li(AT, markOopDesc::hash_mask_in_place);
aoqi@1 2201 __ andr (AT, result, AT);
aoqi@1 2202 // test if hashCode exists
aoqi@1 2203 __ beq (AT, R0, slowCase);
aoqi@1 2204 __ delayed()->nop();
aoqi@1 2205 __ shr(result, markOopDesc::hash_shift);
aoqi@1 2206 __ jr(RA);
aoqi@1 2207 __ delayed()->nop();
aoqi@1 2208 __ bind (slowCase);
aoqi@1 2209 }
aoqi@1 2210 #endif // COMPILER1
aoqi@1 2211
aoqi@1 2212 // The instruction at the verified entry point must be 5 bytes or longer
aoqi@1 2213 // because it can be patched on the fly by make_non_entrant. The stack bang
aoqi@1 2214 // instruction fits that requirement.
aoqi@1 2215
aoqi@1 2216 // Generate stack overflow check
aoqi@1 2217
aoqi@1 2218 if (UseStackBanging) {
aoqi@1 2219 //this function will modify the value in A0
aoqi@1 2220 __ push(A0);
aoqi@1 2221 __ bang_stack_with_offset(StackShadowPages*os::vm_page_size());
aoqi@1 2222 __ pop(A0);
aoqi@1 2223 } else {
aoqi@1 2224 // need a 5 byte instruction to allow MT safe patching to non-entrant
aoqi@1 2225 __ nop();
aoqi@1 2226 __ nop();
aoqi@1 2227 __ nop();
aoqi@1 2228 __ nop();
aoqi@1 2229 __ nop();
aoqi@1 2230 }
aoqi@1 2231 // Generate a new frame for the wrapper.
aoqi@1 2232 // do mips need this ?
aoqi@1 2233 #ifndef OPT_THREAD
aoqi@1 2234 __ get_thread(TREG);
aoqi@1 2235 #endif
aoqi@1 2236 //FIXME here
aoqi@1 2237 __ st_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 2238 // -2 because return address is already present and so is saved ebp
aoqi@1 2239 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 2240 __ andr(SP, SP, AT);
aoqi@1 2241
aoqi@1 2242 __ enter();
aoqi@1 2243 __ addiu(SP, SP, -1 * (stack_size - 2*wordSize));
aoqi@1 2244
aoqi@1 2245 // Frame is now completed as far a size and linkage.
aoqi@1 2246
aoqi@1 2247 int frame_complete = ((intptr_t)__ pc()) - start;
aoqi@1 2248
aoqi@1 2249 // Calculate the difference between esp and ebp. We need to know it
aoqi@1 2250 // after the native call because on windows Java Natives will pop
aoqi@1 2251 // the arguments and it is painful to do esp relative addressing
aoqi@1 2252 // in a platform independent way. So after the call we switch to
aoqi@1 2253 // ebp relative addressing.
aoqi@1 2254 //FIXME actually , the fp_adjustment may not be the right, because andr(sp,sp,at)may change
aoqi@1 2255 //the SP
aoqi@1 2256 int fp_adjustment = stack_size - 2*wordSize;
aoqi@1 2257
aoqi@1 2258 #ifdef COMPILER2
aoqi@1 2259 // C2 may leave the stack dirty if not in SSE2+ mode
aoqi@1 2260 // if (UseSSE >= 2) {
aoqi@1 2261 // __ verify_FPU(0, "c2i transition should have clean FPU stack");
aoqi@1 2262 //} else {
aoqi@1 2263 __ empty_FPU_stack();
aoqi@1 2264 //}
aoqi@1 2265 #endif /* COMPILER2 */
aoqi@1 2266
aoqi@1 2267 // Compute the ebp offset for any slots used after the jni call
aoqi@1 2268
aoqi@1 2269 int lock_slot_ebp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment;
aoqi@1 2270 // We use edi as a thread pointer because it is callee save and
aoqi@1 2271 // if we load it once it is usable thru the entire wrapper
aoqi@1 2272 // const Register thread = edi;
aoqi@1 2273 const Register thread = TREG;
aoqi@1 2274
aoqi@1 2275 // We use esi as the oop handle for the receiver/klass
aoqi@1 2276 // It is callee save so it survives the call to native
aoqi@1 2277
aoqi@1 2278 // const Register oop_handle_reg = esi;
aoqi@1 2279 const Register oop_handle_reg = S4;
aoqi@1 2280 if (is_critical_native) {
aoqi@1 2281 __ stop("generate_native_wrapper in sharedRuntime <2>");
aoqi@1 2282 //TODO:Fu
aoqi@1 2283 /*
aoqi@1 2284 check_needs_gc_for_critical_native(masm, stack_slots, total_c_args, total_in_args,
aoqi@1 2285 oop_handle_offset, oop_maps, in_regs, in_sig_bt);
aoqi@1 2286 */
aoqi@1 2287 }
aoqi@1 2288
aoqi@1 2289 #ifndef OPT_THREAD
aoqi@1 2290 __ get_thread(thread);
aoqi@1 2291 #endif
aoqi@1 2292
aoqi@1 2293 //
aoqi@1 2294 // We immediately shuffle the arguments so that any vm call we have to
aoqi@1 2295 // make from here on out (sync slow path, jvmpi, etc.) we will have
aoqi@1 2296 // captured the oops from our caller and have a valid oopMap for
aoqi@1 2297 // them.
aoqi@1 2298
aoqi@1 2299 // -----------------
aoqi@1 2300 // The Grand Shuffle
aoqi@1 2301 //
aoqi@1 2302 // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv*
aoqi@1 2303 // and, if static, the class mirror instead of a receiver. This pretty much
aoqi@1 2304 // guarantees that register layout will not match (and mips doesn't use reg
aoqi@1 2305 // parms though amd does). Since the native abi doesn't use register args
aoqi@1 2306 // and the java conventions does we don't have to worry about collisions.
aoqi@1 2307 // All of our moved are reg->stack or stack->stack.
aoqi@1 2308 // We ignore the extra arguments during the shuffle and handle them at the
aoqi@1 2309 // last moment. The shuffle is described by the two calling convention
aoqi@1 2310 // vectors we have in our possession. We simply walk the java vector to
aoqi@1 2311 // get the source locations and the c vector to get the destinations.
aoqi@1 2312
aoqi@1 2313 int c_arg = method->is_static() ? 2 : 1 ;
aoqi@1 2314
aoqi@1 2315 // Record esp-based slot for receiver on stack for non-static methods
aoqi@1 2316 int receiver_offset = -1;
aoqi@1 2317
aoqi@1 2318 // This is a trick. We double the stack slots so we can claim
aoqi@1 2319 // the oops in the caller's frame. Since we are sure to have
aoqi@1 2320 // more args than the caller doubling is enough to make
aoqi@1 2321 // sure we can capture all the incoming oop args from the
aoqi@1 2322 // caller.
aoqi@1 2323 //
aoqi@1 2324 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/);
aoqi@1 2325
aoqi@1 2326 // Mark location of rbp (someday)
aoqi@1 2327 // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, vmreg(rbp));
aoqi@1 2328
aoqi@1 2329 // Use eax, ebx as temporaries during any memory-memory moves we have to do
aoqi@1 2330 // All inbound args are referenced based on rbp and all outbound args via rsp.
aoqi@1 2331
aoqi@1 2332
aoqi@1 2333
aoqi@1 2334 #ifdef ASSERT
aoqi@1 2335 bool reg_destroyed[RegisterImpl::number_of_registers];
aoqi@1 2336 bool freg_destroyed[FloatRegisterImpl::number_of_registers];
aoqi@1 2337 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
aoqi@1 2338 reg_destroyed[r] = false;
aoqi@1 2339 }
aoqi@1 2340 for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
aoqi@1 2341 freg_destroyed[f] = false;
aoqi@1 2342 }
aoqi@1 2343
aoqi@1 2344 #endif /* ASSERT */
aoqi@1 2345
aoqi@1 2346 // We know that we only have args in at most two integer registers (ecx, edx). So eax, ebx
aoqi@1 2347 // Are free to temporaries if we have to do stack to steck moves.
aoqi@1 2348 // All inbound args are referenced based on ebp and all outbound args via esp.
aoqi@1 2349
aoqi@1 2350 // This may iterate in two different directions depending on the
aoqi@1 2351 // kind of native it is. The reason is that for regular JNI natives
aoqi@1 2352 // the incoming and outgoing registers are offset upwards and for
aoqi@1 2353 // critical natives they are offset down.
aoqi@1 2354 GrowableArray<int> arg_order(2 * total_in_args);
aoqi@1 2355 VMRegPair tmp_vmreg;
aoqi@1 2356 // tmp_vmreg.set1(rbx->as_VMReg());
aoqi@1 2357 tmp_vmreg.set1(T8->as_VMReg());
aoqi@1 2358
aoqi@1 2359 if (!is_critical_native) {
aoqi@1 2360 for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) {
aoqi@1 2361 arg_order.push(i);
aoqi@1 2362 arg_order.push(c_arg);
aoqi@1 2363 }
aoqi@1 2364 } else {
aoqi@1 2365 // Compute a valid move order, using tmp_vmreg to break any cycles
aoqi@1 2366 __ stop("generate_native_wrapper in sharedRuntime <2>");
aoqi@1 2367 //TODO:Fu
aoqi@1 2368 // ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg);
aoqi@1 2369 }
aoqi@1 2370
aoqi@1 2371 int temploc = -1;
aoqi@1 2372 for (int ai = 0; ai < arg_order.length(); ai += 2) {
aoqi@1 2373 int i = arg_order.at(ai);
aoqi@1 2374 int c_arg = arg_order.at(ai + 1);
aoqi@1 2375 __ block_comment(err_msg("move %d -> %d", i, c_arg));
aoqi@1 2376 if (c_arg == -1) {
aoqi@1 2377 assert(is_critical_native, "should only be required for critical natives");
aoqi@1 2378 // This arg needs to be moved to a temporary
aoqi@1 2379 __ move(tmp_vmreg.first()->as_Register(), in_regs[i].first()->as_Register());
aoqi@1 2380 in_regs[i] = tmp_vmreg;
aoqi@1 2381 temploc = i;
aoqi@1 2382 continue;
aoqi@1 2383 } else if (i == -1) {
aoqi@1 2384 assert(is_critical_native, "should only be required for critical natives");
aoqi@1 2385 // Read from the temporary location
aoqi@1 2386 assert(temploc != -1, "must be valid");
aoqi@1 2387 i = temploc;
aoqi@1 2388 temploc = -1;
aoqi@1 2389 }
aoqi@1 2390 #ifdef ASSERT
aoqi@1 2391 if (in_regs[i].first()->is_Register()) {
aoqi@1 2392 assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!");
aoqi@1 2393 } else if (in_regs[i].first()->is_FloatRegister()) {
aoqi@1 2394 assert(!freg_destroyed[in_regs[i].first()->as_FloatRegister()->encoding()], "destroyed reg!");
aoqi@1 2395 }
aoqi@1 2396 if (out_regs[c_arg].first()->is_Register()) {
aoqi@1 2397 reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
aoqi@1 2398 } else if (out_regs[c_arg].first()->is_FloatRegister()) {
aoqi@1 2399 freg_destroyed[out_regs[c_arg].first()->as_FloatRegister()->encoding()] = true;
aoqi@1 2400 }
aoqi@1 2401 #endif /* ASSERT */
aoqi@1 2402 switch (in_sig_bt[i]) {
aoqi@1 2403 case T_ARRAY:
aoqi@1 2404 if (is_critical_native) {
aoqi@1 2405 __ stop("generate_native_wrapper in sharedRuntime <2>");
aoqi@1 2406 //TODO:Fu
aoqi@1 2407 // unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]);
aoqi@1 2408 c_arg++;
aoqi@1 2409 #ifdef ASSERT
aoqi@1 2410 if (out_regs[c_arg].first()->is_Register()) {
aoqi@1 2411 reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true;
aoqi@1 2412 } else if (out_regs[c_arg].first()->is_FloatRegister()) {
aoqi@1 2413 freg_destroyed[out_regs[c_arg].first()->as_FloatRegister()->encoding()] = true;
aoqi@1 2414 }
aoqi@1 2415 #endif
aoqi@1 2416 break;
aoqi@1 2417 }
aoqi@1 2418 case T_OBJECT:
aoqi@1 2419 assert(!is_critical_native, "no oop arguments");
aoqi@1 2420 object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg],
aoqi@1 2421 ((i == 0) && (!is_static)),
aoqi@1 2422 &receiver_offset);
aoqi@1 2423 break;
aoqi@1 2424 case T_VOID:
aoqi@1 2425 break;
aoqi@1 2426
aoqi@1 2427 case T_FLOAT:
aoqi@1 2428 float_move(masm, in_regs[i], out_regs[c_arg]);
aoqi@1 2429 break;
aoqi@1 2430
aoqi@1 2431 case T_DOUBLE:
aoqi@1 2432 assert( i + 1 < total_in_args &&
aoqi@1 2433 in_sig_bt[i + 1] == T_VOID &&
aoqi@1 2434 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
aoqi@1 2435 double_move(masm, in_regs[i], out_regs[c_arg]);
aoqi@1 2436 break;
aoqi@1 2437
aoqi@1 2438 case T_LONG :
aoqi@1 2439 long_move(masm, in_regs[i], out_regs[c_arg]);
aoqi@1 2440 break;
aoqi@1 2441
aoqi@1 2442 case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
aoqi@1 2443
aoqi@1 2444 default:
aoqi@1 2445 // move32_64(masm, in_regs[i], out_regs[c_arg]);
aoqi@1 2446 simple_move32(masm, in_regs[i], out_regs[c_arg]);
aoqi@1 2447 }
aoqi@1 2448 }
aoqi@1 2449
aoqi@1 2450 // point c_arg at the first arg that is already loaded in case we
aoqi@1 2451 // need to spill before we call out
aoqi@1 2452 c_arg = total_c_args - total_in_args;
aoqi@1 2453 // Pre-load a static method's oop into esi. Used both by locking code and
aoqi@1 2454 // the normal JNI call code.
aoqi@1 2455
aoqi@1 2456 __ move(oop_handle_reg, A1);
aoqi@1 2457
aoqi@1 2458 if (method->is_static() && !is_critical_native) {
aoqi@1 2459
aoqi@1 2460 // load opp into a register
aoqi@1 2461 int oop_index = __ oop_recorder()->find_index(JNIHandles::make_local(
aoqi@1 2462 (method->method_holder())->java_mirror()));
aoqi@1 2463
aoqi@1 2464
aoqi@1 2465 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@1 2466 __ relocate(rspec);
aoqi@1 2467 //__ lui(oop_handle_reg, Assembler::split_high((int)JNIHandles::make_local(
aoqi@1 2468 // Klass::cast(method->method_holder())->java_mirror())));
aoqi@1 2469 //__ addiu(oop_handle_reg, oop_handle_reg, Assembler::split_low((int)
aoqi@1 2470 // JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())));
fujie@368 2471 __ patchable_set48(oop_handle_reg, (long)JNIHandles::make_local((method->method_holder())->java_mirror()));
aoqi@1 2472 // __ verify_oop(oop_handle_reg);
aoqi@1 2473 // Now handlize the static class mirror it's known not-null.
aoqi@1 2474 __ sd( oop_handle_reg, SP, klass_offset);
aoqi@1 2475 map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
aoqi@1 2476
aoqi@1 2477 // Now get the handle
aoqi@1 2478 __ lea(oop_handle_reg, Address(SP, klass_offset));
aoqi@1 2479 // store the klass handle as second argument
aoqi@1 2480 __ move(A1, oop_handle_reg);
aoqi@1 2481 // and protect the arg if we must spill
aoqi@1 2482 c_arg--;
aoqi@1 2483 }
aoqi@1 2484 // Change state to native (we save the return address in the thread, since it might not
aoqi@1 2485 // be pushed on the stack when we do a a stack traversal). It is enough that the pc()
aoqi@1 2486 // points into the right code segment. It does not have to be the correct return pc.
aoqi@1 2487 // We use the same pc/oopMap repeatedly when we call out
aoqi@1 2488
aoqi@1 2489 intptr_t the_pc = (intptr_t) __ pc();
aoqi@1 2490
aoqi@1 2491 oop_maps->add_gc_map(the_pc - start, map);
aoqi@1 2492
aoqi@1 2493 //__ set_last_Java_frame(thread, esp, noreg, (address)the_pc);
aoqi@1 2494 __ set_last_Java_frame(SP, noreg, NULL);
aoqi@1 2495 __ relocate(relocInfo::internal_pc_type);
aoqi@1 2496 {
aoqi@1 2497 intptr_t save_pc = (intptr_t)the_pc ;
fujie@368 2498 __ patchable_set48(AT, save_pc);
aoqi@1 2499 }
aoqi@1 2500 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@1 2501
aoqi@1 2502
aoqi@1 2503 // We have all of the arguments setup at this point. We must not touch any register
aoqi@1 2504 // argument registers at this point (what if we save/restore them there are no oop?
aoqi@1 2505 {
aoqi@1 2506 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0);
aoqi@1 2507 int metadata_index = __ oop_recorder()->find_index(method());
aoqi@1 2508 RelocationHolder rspec = metadata_Relocation::spec(metadata_index);
aoqi@1 2509 __ relocate(rspec);
aoqi@1 2510 //__ lui(T6, Assembler::split_high((int)JNIHandles::make_local(method())));
aoqi@1 2511 //__ addiu(T6, T6, Assembler::split_low((int)JNIHandles::make_local(method())));
fujie@368 2512 __ patchable_set48(AT, (long)(method()));
aoqi@1 2513
aoqi@1 2514 __ call_VM_leaf(
aoqi@1 2515 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry),
aoqi@1 2516 thread, AT);
aoqi@1 2517
aoqi@1 2518 }
aoqi@1 2519
aoqi@1 2520 // These are register definitions we need for locking/unlocking
aoqi@1 2521 // const Register swap_reg = eax; // Must use eax for cmpxchg instruction
aoqi@1 2522 // const Register obj_reg = ecx; // Will contain the oop
aoqi@1 2523 // const Register lock_reg = edx; // Address of compiler lock object (BasicLock)
aoqi@1 2524 //FIXME, I hava no idea which register to use
aoqi@1 2525 const Register swap_reg = T8; // Must use eax for cmpxchg instruction
aoqi@1 2526 const Register obj_reg = T9; // Will contain the oop
aoqi@1 2527 //const Register lock_reg = T6; // Address of compiler lock object (BasicLock)
aoqi@1 2528 const Register lock_reg = c_rarg0; // Address of compiler lock object (BasicLock)
aoqi@1 2529
aoqi@1 2530
aoqi@1 2531
aoqi@1 2532 Label slow_path_lock;
aoqi@1 2533 Label lock_done;
aoqi@1 2534
aoqi@1 2535 // Lock a synchronized method
aoqi@1 2536 if (method->is_synchronized()) {
aoqi@1 2537 assert(!is_critical_native, "unhandled");
aoqi@1 2538
aoqi@1 2539 const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
aoqi@1 2540
aoqi@1 2541 // Get the handle (the 2nd argument)
aoqi@1 2542 __ move(oop_handle_reg, A1);
aoqi@1 2543
aoqi@1 2544 // Get address of the box
aoqi@1 2545 __ lea(lock_reg, Address(FP, lock_slot_ebp_offset));
aoqi@1 2546
aoqi@1 2547 // Load the oop from the handle
aoqi@1 2548 __ ld(obj_reg, oop_handle_reg, 0);
aoqi@1 2549
aoqi@1 2550 if (UseBiasedLocking) {
aoqi@1 2551 // Note that oop_handle_reg is trashed during this call
aoqi@1 2552 __ biased_locking_enter(lock_reg, obj_reg, swap_reg, A1,
aoqi@1 2553 false, lock_done, &slow_path_lock);
aoqi@1 2554 }
aoqi@1 2555
aoqi@1 2556 // Load immediate 1 into swap_reg %eax
aoqi@1 2557 __ move(swap_reg, 1);
aoqi@1 2558
aoqi@1 2559 __ ld(AT, obj_reg, 0);
aoqi@1 2560 __ orr(swap_reg, swap_reg, AT);
aoqi@1 2561
aoqi@1 2562 __ sd( swap_reg, lock_reg, mark_word_offset);
aoqi@1 2563 __ cmpxchg(lock_reg, Address(obj_reg, 0), swap_reg);
aoqi@1 2564 __ bne(AT, R0, lock_done);
aoqi@1 2565 __ delayed()->nop();
aoqi@1 2566 // Test if the oopMark is an obvious stack pointer, i.e.,
aoqi@1 2567 // 1) (mark & 3) == 0, and
aoqi@1 2568 // 2) esp <= mark < mark + os::pagesize()
aoqi@1 2569 // These 3 tests can be done by evaluating the following
aoqi@1 2570 // expression: ((mark - esp) & (3 - os::vm_page_size())),
aoqi@1 2571 // assuming both stack pointer and pagesize have their
aoqi@1 2572 // least significant 2 bits clear.
aoqi@1 2573 // NOTE: the oopMark is in swap_reg %eax as the result of cmpxchg
aoqi@1 2574
aoqi@1 2575 __ dsub(swap_reg, swap_reg,SP);
aoqi@1 2576 __ move(AT, 3 - os::vm_page_size());
aoqi@1 2577 __ andr(swap_reg , swap_reg, AT);
aoqi@1 2578 // Save the test result, for recursive case, the result is zero
aoqi@1 2579 __ sd(swap_reg, lock_reg, mark_word_offset);
aoqi@1 2580 //FIXME here, Why notEqual?
aoqi@1 2581 __ bne(swap_reg,R0, slow_path_lock);
aoqi@1 2582 __ delayed()->nop();
aoqi@1 2583 // Slow path will re-enter here
aoqi@1 2584 __ bind(lock_done);
aoqi@1 2585
aoqi@1 2586 if (UseBiasedLocking) {
aoqi@1 2587 // Re-fetch oop_handle_reg as we trashed it above
aoqi@1 2588 __ move(A1, oop_handle_reg);
aoqi@1 2589 }
aoqi@1 2590 }
aoqi@1 2591
aoqi@1 2592
aoqi@1 2593 // Finally just about ready to make the JNI call
aoqi@1 2594
aoqi@1 2595
aoqi@1 2596 // get JNIEnv* which is first argument to native
aoqi@1 2597 if (!is_critical_native) {
aoqi@1 2598 __ addi(A0, thread, in_bytes(JavaThread::jni_environment_offset()));
aoqi@1 2599 }
aoqi@1 2600
aoqi@1 2601 // Example: Java_java_lang_ref_Finalizer_invokeFinalizeMethod(JNIEnv *env, jclass clazz, jobject ob)
aoqi@1 2602 /* Load the second arguments into A1 */
aoqi@1 2603 //__ ld(A1, SP , wordSize ); // klass
aoqi@1 2604
aoqi@1 2605 // Now set thread in native
aoqi@1 2606 __ addi(AT, R0, _thread_in_native);
aoqi@1 2607 __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset()));
aoqi@1 2608 /* Jin: do the call */
aoqi@1 2609 __ call(method->native_function(), relocInfo::runtime_call_type);
aoqi@1 2610 __ delayed()->nop();
aoqi@1 2611 // WARNING - on Windows Java Natives use pascal calling convention and pop the
aoqi@1 2612 // arguments off of the stack. We could just re-adjust the stack pointer here
aoqi@1 2613 // and continue to do SP relative addressing but we instead switch to FP
aoqi@1 2614 // relative addressing.
aoqi@1 2615
aoqi@1 2616 // Unpack native results.
aoqi@1 2617 switch (ret_type) {
aoqi@1 2618 case T_BOOLEAN: __ c2bool(V0); break;
aoqi@1 2619 case T_CHAR : __ andi(V0,V0, 0xFFFF); break;
aoqi@1 2620 case T_BYTE : __ sign_extend_byte (V0); break;
aoqi@1 2621 case T_SHORT : __ sign_extend_short(V0); break;
aoqi@1 2622 case T_INT : // nothing to do break;
aoqi@1 2623 case T_DOUBLE :
aoqi@1 2624 case T_FLOAT :
aoqi@1 2625 // Result is in st0 we'll save as needed
aoqi@1 2626 break;
aoqi@1 2627 case T_ARRAY: // Really a handle
aoqi@1 2628 case T_OBJECT: // Really a handle
aoqi@1 2629 break; // can't de-handlize until after safepoint check
aoqi@1 2630 case T_VOID: break;
aoqi@1 2631 case T_LONG: break;
aoqi@1 2632 default : ShouldNotReachHere();
aoqi@1 2633 }
aoqi@1 2634 // Switch thread to "native transition" state before reading the synchronization state.
aoqi@1 2635 // This additional state is necessary because reading and testing the synchronization
aoqi@1 2636 // state is not atomic w.r.t. GC, as this scenario demonstrates:
aoqi@1 2637 // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
aoqi@1 2638 // VM thread changes sync state to synchronizing and suspends threads for GC.
aoqi@1 2639 // Thread A is resumed to finish this native method, but doesn't block here since it
aoqi@1 2640 // didn't see any synchronization is progress, and escapes.
aoqi@1 2641 // __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans);
aoqi@1 2642 //__ sw(_thread_in_native_trans, thread, JavaThread::thread_state_offset());
aoqi@1 2643 // __ move(AT, (int)_thread_in_native_trans);
aoqi@1 2644 __ addi(AT, R0, _thread_in_native_trans);
aoqi@1 2645 __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset()));
aoqi@1 2646
aoqi@1 2647 Label after_transition;
aoqi@1 2648
aoqi@1 2649 // check for safepoint operation in progress and/or pending suspend requests
aoqi@1 2650 { Label Continue;
aoqi@1 2651 //FIXME here, which regiser should we use?
aoqi@1 2652 // SafepointSynchronize::_not_synchronized);
aoqi@1 2653 __ li(AT, SafepointSynchronize::address_of_state());
aoqi@1 2654 __ lw(A0, AT, 0);
aoqi@1 2655 __ addi(AT, A0, -SafepointSynchronize::_not_synchronized);
aoqi@1 2656 Label L;
aoqi@1 2657 __ bne(AT,R0, L);
aoqi@1 2658 __ delayed()->nop();
aoqi@1 2659 __ lw(AT, thread, in_bytes(JavaThread::suspend_flags_offset()));
aoqi@1 2660 __ beq(AT, R0, Continue);
aoqi@1 2661 __ delayed()->nop();
aoqi@1 2662 __ bind(L);
aoqi@1 2663
aoqi@1 2664 // Don't use call_VM as it will see a possible pending exception and forward it
aoqi@1 2665 // and never return here preventing us from clearing _last_native_pc down below.
aoqi@1 2666 // Also can't use call_VM_leaf either as it will check to see if esi & edi are
aoqi@1 2667 // preserved and correspond to the bcp/locals pointers. So we do a runtime call
aoqi@1 2668 // by hand.
aoqi@1 2669 //
aoqi@1 2670 save_native_result(masm, ret_type, stack_slots);
aoqi@1 2671 __ move (A0, thread);
aoqi@1 2672 __ addi(SP,SP, -wordSize);
aoqi@21 2673 __ push(S2);
aoqi@21 2674 __ move(AT, -(StackAlignmentInBytes));
aoqi@21 2675 __ move(S2, SP); // use S2 as a sender SP holder
aoqi@21 2676 __ andr(SP, SP, AT); // align stack as required by ABI
aoqi@1 2677 if (!is_critical_native) {
aoqi@1 2678 __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), relocInfo::runtime_call_type);
aoqi@1 2679 __ delayed()->nop();
aoqi@1 2680 } else {
aoqi@1 2681 __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition), relocInfo::runtime_call_type);
aoqi@1 2682 __ delayed()->nop();
aoqi@1 2683 }
aoqi@21 2684 __ move(SP, S2); // use S2 as a sender SP holder
aoqi@21 2685 __ pop(S2);
aoqi@1 2686 __ addi(SP,SP, wordSize);
aoqi@1 2687 //add for compressedoops
aoqi@1 2688 __ reinit_heapbase();
aoqi@1 2689 // Restore any method result value
aoqi@1 2690 restore_native_result(masm, ret_type, stack_slots);
aoqi@1 2691
aoqi@1 2692 if (is_critical_native) {
aoqi@1 2693 // The call above performed the transition to thread_in_Java so
aoqi@1 2694 // skip the transition logic below.
aoqi@1 2695 __ beq(R0, R0, after_transition);
aoqi@1 2696 __ delayed()->nop();
aoqi@1 2697 }
aoqi@1 2698
aoqi@1 2699 __ bind(Continue);
aoqi@1 2700 }
aoqi@1 2701
aoqi@1 2702 // change thread state
aoqi@1 2703 __ addi(AT, R0, _thread_in_Java);
aoqi@1 2704 __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset()));
aoqi@1 2705 __ bind(after_transition);
aoqi@1 2706 Label reguard;
aoqi@1 2707 Label reguard_done;
Jin@5 2708 __ lw(AT, thread, in_bytes(JavaThread::stack_guard_state_offset()));
aoqi@1 2709 __ addi(AT, AT, -JavaThread::stack_guard_yellow_disabled);
aoqi@1 2710 __ beq(AT, R0, reguard);
aoqi@1 2711 __ delayed()->nop();
aoqi@1 2712 // slow path reguard re-enters here
aoqi@1 2713 __ bind(reguard_done);
aoqi@1 2714
aoqi@1 2715 // Handle possible exception (will unlock if necessary)
aoqi@1 2716
aoqi@1 2717 // native result if any is live
aoqi@1 2718
aoqi@1 2719 // Unlock
aoqi@1 2720 Label slow_path_unlock;
aoqi@1 2721 Label unlock_done;
aoqi@1 2722 if (method->is_synchronized()) {
aoqi@1 2723
aoqi@1 2724 Label done;
aoqi@1 2725
aoqi@1 2726 // Get locked oop from the handle we passed to jni
aoqi@1 2727 __ ld( obj_reg, oop_handle_reg, 0);
aoqi@1 2728 //FIXME
aoqi@1 2729 if (UseBiasedLocking) {
aoqi@1 2730 __ biased_locking_exit(obj_reg, T8, done);
aoqi@1 2731
aoqi@1 2732 }
aoqi@1 2733
aoqi@1 2734 // Simple recursive lock?
aoqi@1 2735
aoqi@1 2736 __ ld(AT, FP, lock_slot_ebp_offset);
aoqi@1 2737 __ beq(AT, R0, done);
aoqi@1 2738 __ delayed()->nop();
aoqi@1 2739 // Must save eax if if it is live now because cmpxchg must use it
aoqi@1 2740 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
aoqi@1 2741 save_native_result(masm, ret_type, stack_slots);
aoqi@1 2742 }
aoqi@1 2743
aoqi@1 2744 // get old displaced header
aoqi@1 2745 __ ld (T8, FP, lock_slot_ebp_offset);
aoqi@1 2746 // get address of the stack lock
aoqi@1 2747 //FIXME aoqi
aoqi@1 2748 //__ addi (T6, FP, lock_slot_ebp_offset);
aoqi@1 2749 __ addi (c_rarg0, FP, lock_slot_ebp_offset);
aoqi@1 2750 // Atomic swap old header if oop still contains the stack lock
aoqi@1 2751 //FIXME aoqi
aoqi@1 2752 //__ cmpxchg(T8, Address(obj_reg, 0),T6 );
aoqi@1 2753 __ cmpxchg(T8, Address(obj_reg, 0), c_rarg0);
aoqi@1 2754
aoqi@1 2755 __ beq(AT, R0, slow_path_unlock);
aoqi@1 2756 __ delayed()->nop();
aoqi@1 2757 // slow path re-enters here
aoqi@1 2758 __ bind(unlock_done);
aoqi@1 2759 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) {
aoqi@1 2760 restore_native_result(masm, ret_type, stack_slots);
aoqi@1 2761 }
aoqi@1 2762
aoqi@1 2763 __ bind(done);
aoqi@1 2764
aoqi@1 2765 }
aoqi@1 2766 {
aoqi@1 2767 SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0);
aoqi@1 2768 // Tell dtrace about this method exit
aoqi@1 2769 save_native_result(masm, ret_type, stack_slots);
aoqi@1 2770 int metadata_index = __ oop_recorder()->find_index( (method()));
aoqi@1 2771 RelocationHolder rspec = metadata_Relocation::spec(metadata_index);
aoqi@1 2772 __ relocate(rspec);
aoqi@1 2773 //__ lui(T6, Assembler::split_high((int)JNIHandles::make_local(method())));
aoqi@1 2774 //__ addiu(T6, T6, Assembler::split_low((int)JNIHandles::make_local(method())));
fujie@368 2775 __ patchable_set48(AT, (long)(method()));
aoqi@1 2776
aoqi@1 2777 __ call_VM_leaf(
aoqi@1 2778 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit),
aoqi@1 2779 thread, AT);
aoqi@1 2780 restore_native_result(masm, ret_type, stack_slots);
aoqi@1 2781 }
aoqi@1 2782
aoqi@1 2783 // We can finally stop using that last_Java_frame we setup ages ago
aoqi@1 2784
aoqi@1 2785 __ reset_last_Java_frame(false, true);
aoqi@1 2786
aoqi@1 2787 // Unpack oop result
aoqi@1 2788 if (ret_type == T_OBJECT || ret_type == T_ARRAY) {
aoqi@1 2789 Label L;
aoqi@1 2790 // __ cmpl(eax, NULL_WORD);
aoqi@1 2791 // __ jcc(Assembler::equal, L);
aoqi@1 2792 __ beq(V0, R0,L );
aoqi@1 2793 __ delayed()->nop();
aoqi@1 2794 // __ movl(eax, Address(eax));
aoqi@1 2795 __ ld(V0, V0, 0);
aoqi@1 2796 __ bind(L);
aoqi@1 2797 // __ verify_oop(eax);
aoqi@1 2798 __ verify_oop(V0);
aoqi@1 2799 }
aoqi@1 2800
aoqi@1 2801 if (!is_critical_native) {
aoqi@1 2802 // reset handle block
aoqi@1 2803 __ ld(AT, thread, in_bytes(JavaThread::active_handles_offset()));
aoqi@1 2804 __ sw(R0, AT, JNIHandleBlock::top_offset_in_bytes());
aoqi@1 2805 }
aoqi@1 2806
aoqi@1 2807 if (!is_critical_native) {
aoqi@1 2808 // Any exception pending?
aoqi@1 2809 __ ld(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2810
aoqi@1 2811 __ bne(AT, R0, exception_pending);
aoqi@1 2812 __ delayed()->nop();
aoqi@1 2813 }
aoqi@1 2814 // no exception, we're almost done
aoqi@1 2815
aoqi@1 2816 // check that only result value is on FPU stack
aoqi@1 2817 __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit");
aoqi@1 2818
aoqi@1 2819 // Fixup floating pointer results so that result looks like a return from a compiled method
aoqi@1 2820 /* if (ret_type == T_FLOAT) {
aoqi@1 2821 if (UseSSE >= 1) {
aoqi@1 2822 // Pop st0 and store as float and reload into xmm register
aoqi@1 2823 __ fstp_s(Address(ebp, -4));
aoqi@1 2824 __ movss(xmm0, Address(ebp, -4));
aoqi@1 2825 }
aoqi@1 2826 } else if (ret_type == T_DOUBLE) {
aoqi@1 2827 if (UseSSE >= 2) {
aoqi@1 2828 // Pop st0 and store as double and reload into xmm register
aoqi@1 2829 __ fstp_d(Address(ebp, -8));
aoqi@1 2830 __ movsd(xmm0, Address(ebp, -8));
aoqi@1 2831 }
aoqi@1 2832 }
aoqi@1 2833 */
aoqi@1 2834 // Return
aoqi@1 2835 #ifndef OPT_THREAD
aoqi@1 2836 __ get_thread(TREG);
aoqi@1 2837 #endif
aoqi@1 2838 __ ld_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 2839 __ leave();
aoqi@1 2840
aoqi@1 2841 __ jr(RA);
aoqi@1 2842 __ delayed()->nop();
aoqi@1 2843 // Unexpected paths are out of line and go here
aoqi@1 2844 /*
aoqi@1 2845 if (!is_critical_native) {
aoqi@1 2846 // forward the exception
aoqi@1 2847 __ bind(exception_pending);
aoqi@1 2848
aoqi@1 2849 // and forward the exception
aoqi@1 2850 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
aoqi@1 2851 }
aoqi@1 2852 */
aoqi@1 2853 // Slow path locking & unlocking
aoqi@1 2854 if (method->is_synchronized()) {
aoqi@1 2855
aoqi@1 2856 // BEGIN Slow path lock
aoqi@1 2857
aoqi@1 2858 __ bind(slow_path_lock);
aoqi@1 2859
aoqi@1 2860 // protect the args we've loaded
aoqi@1 2861 save_args(masm, total_c_args, c_arg, out_regs);
aoqi@1 2862
aoqi@1 2863 // has last_Java_frame setup. No exceptions so do vanilla call not call_VM
aoqi@1 2864 // args are (oop obj, BasicLock* lock, JavaThread* thread)
aoqi@1 2865
aoqi@1 2866 __ move(A0, obj_reg);
aoqi@1 2867 __ move(A1, lock_reg);
aoqi@1 2868 __ move(A2, thread);
aoqi@1 2869 __ addi(SP, SP, - 3*wordSize);
aoqi@1 2870
aoqi@1 2871 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 2872 __ move(S2, SP); // use S2 as a sender SP holder
aoqi@1 2873 __ andr(SP, SP, AT); // align stack as required by ABI
aoqi@1 2874
aoqi@1 2875 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), relocInfo::runtime_call_type);
aoqi@1 2876 __ delayed()->nop();
aoqi@1 2877 __ move(SP, S2);
aoqi@1 2878 __ addi(SP, SP, 3*wordSize);
aoqi@1 2879
aoqi@1 2880 restore_args(masm, total_c_args, c_arg, out_regs);
aoqi@1 2881
aoqi@1 2882 #ifdef ASSERT
aoqi@1 2883 { Label L;
aoqi@1 2884 // __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD);
aoqi@1 2885 __ ld(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2886 //__ jcc(Assembler::equal, L);
aoqi@1 2887 __ beq(AT, R0, L);
aoqi@1 2888 __ delayed()->nop();
aoqi@1 2889 __ stop("no pending exception allowed on exit from monitorenter");
aoqi@1 2890 __ bind(L);
aoqi@1 2891 }
aoqi@1 2892 #endif
aoqi@1 2893 __ b(lock_done);
aoqi@1 2894 __ delayed()->nop();
aoqi@1 2895 // END Slow path lock
aoqi@1 2896
aoqi@1 2897 // BEGIN Slow path unlock
aoqi@1 2898 __ bind(slow_path_unlock);
aoqi@1 2899
aoqi@1 2900 // Slow path unlock
aoqi@1 2901
aoqi@1 2902 if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
aoqi@1 2903 save_native_result(masm, ret_type, stack_slots);
aoqi@1 2904 }
aoqi@1 2905 // Save pending exception around call to VM (which contains an EXCEPTION_MARK)
aoqi@1 2906
aoqi@1 2907 __ ld(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2908 __ push(AT);
aoqi@1 2909 __ sd(R0, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2910
aoqi@1 2911 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 2912 __ move(S2, SP); // use S2 as a sender SP holder
aoqi@1 2913 __ andr(SP, SP, AT); // align stack as required by ABI
aoqi@1 2914
aoqi@1 2915 // should be a peal
aoqi@1 2916 // +wordSize because of the push above
aoqi@1 2917 __ addi(A1, FP, lock_slot_ebp_offset);
aoqi@1 2918
aoqi@1 2919 __ move(A0, obj_reg);
aoqi@1 2920 __ addi(SP,SP, -2*wordSize);
aoqi@1 2921 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C),
aoqi@1 2922 relocInfo::runtime_call_type);
aoqi@1 2923 __ delayed()->nop();
aoqi@1 2924 __ addi(SP,SP, 2*wordSize);
aoqi@1 2925 __ move(SP, S2);
aoqi@1 2926 //add for compressedoops
aoqi@1 2927 __ reinit_heapbase();
aoqi@1 2928 #ifdef ASSERT
aoqi@1 2929 {
aoqi@1 2930 Label L;
aoqi@1 2931 // __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD);
aoqi@1 2932 __ lw( AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2933 //__ jcc(Assembler::equal, L);
aoqi@1 2934 __ beq(AT, R0, L);
aoqi@1 2935 __ delayed()->nop();
aoqi@1 2936 __ stop("no pending exception allowed on exit complete_monitor_unlocking_C");
aoqi@1 2937 __ bind(L);
aoqi@1 2938 }
aoqi@1 2939 #endif /* ASSERT */
aoqi@1 2940
aoqi@1 2941 __ pop(AT);
aoqi@1 2942 __ sd(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 2943 if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) {
aoqi@1 2944 restore_native_result(masm, ret_type, stack_slots);
aoqi@1 2945 }
aoqi@1 2946 __ b(unlock_done);
aoqi@1 2947 __ delayed()->nop();
aoqi@1 2948 // END Slow path unlock
aoqi@1 2949
aoqi@1 2950 }
aoqi@1 2951
aoqi@1 2952 // SLOW PATH Reguard the stack if needed
aoqi@1 2953
aoqi@1 2954 __ bind(reguard);
aoqi@1 2955 save_native_result(masm, ret_type, stack_slots);
aoqi@1 2956 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages),
aoqi@1 2957 relocInfo::runtime_call_type);
aoqi@1 2958 __ delayed()->nop();
aoqi@1 2959 //add for compressedoops
aoqi@1 2960 __ reinit_heapbase();
aoqi@1 2961 restore_native_result(masm, ret_type, stack_slots);
aoqi@1 2962 __ b(reguard_done);
aoqi@1 2963 __ delayed()->nop();
aoqi@1 2964
aoqi@1 2965 // BEGIN EXCEPTION PROCESSING
aoqi@1 2966 if (!is_critical_native) {
aoqi@1 2967 // Forward the exception
aoqi@1 2968 __ bind(exception_pending);
aoqi@1 2969
aoqi@1 2970 // remove possible return value from FPU register stack
aoqi@1 2971 __ empty_FPU_stack();
aoqi@1 2972
aoqi@1 2973 // pop our frame
aoqi@1 2974 //forward_exception_entry need return address on stack
aoqi@1 2975 __ addiu(SP, FP, wordSize);
aoqi@1 2976 __ ld(FP, SP, (-1) * wordSize);
aoqi@1 2977
aoqi@1 2978 // and forward the exception
aoqi@1 2979 __ jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
aoqi@1 2980 __ delayed()->nop();
aoqi@1 2981 }
aoqi@1 2982 __ flush();
aoqi@1 2983
aoqi@1 2984 nmethod *nm = nmethod::new_native_nmethod(method,
aoqi@1 2985 compile_id,
aoqi@1 2986 masm->code(),
aoqi@1 2987 vep_offset,
aoqi@1 2988 frame_complete,
aoqi@1 2989 stack_slots / VMRegImpl::slots_per_word,
aoqi@1 2990 (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)),
aoqi@1 2991 in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size),
aoqi@1 2992 oop_maps);
aoqi@1 2993
aoqi@1 2994 if (is_critical_native) {
aoqi@1 2995 nm->set_lazy_critical_native(true);
aoqi@1 2996 }
aoqi@1 2997 return nm;
aoqi@1 2998
aoqi@1 2999
aoqi@1 3000 }
aoqi@1 3001
aoqi@1 3002 #ifdef HAVE_DTRACE_H
aoqi@1 3003 // ---------------------------------------------------------------------------
aoqi@1 3004 // Generate a dtrace nmethod for a given signature. The method takes arguments
aoqi@1 3005 // in the Java compiled code convention, marshals them to the native
aoqi@1 3006 // abi and then leaves nops at the position you would expect to call a native
aoqi@1 3007 // function. When the probe is enabled the nops are replaced with a trap
aoqi@1 3008 // instruction that dtrace inserts and the trace will cause a notification
aoqi@1 3009 // to dtrace.
aoqi@1 3010 //
aoqi@1 3011 // The probes are only able to take primitive types and java/lang/String as
aoqi@1 3012 // arguments. No other java types are allowed. Strings are converted to utf8
aoqi@1 3013 // strings so that from dtrace point of view java strings are converted to C
aoqi@1 3014 // strings. There is an arbitrary fixed limit on the total space that a method
aoqi@1 3015 // can use for converting the strings. (256 chars per string in the signature).
aoqi@1 3016 // So any java string larger then this is truncated.
aoqi@1 3017
aoqi@1 3018 static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 };
aoqi@1 3019 static bool offsets_initialized = false;
aoqi@1 3020
aoqi@1 3021 static VMRegPair reg64_to_VMRegPair(Register r) {
aoqi@1 3022 VMRegPair ret;
aoqi@1 3023 if (wordSize == 8) {
aoqi@1 3024 ret.set2(r->as_VMReg());
aoqi@1 3025 } else {
aoqi@1 3026 ret.set_pair(r->successor()->as_VMReg(), r->as_VMReg());
aoqi@1 3027 }
aoqi@1 3028 return ret;
aoqi@1 3029 }
aoqi@1 3030
aoqi@1 3031
aoqi@1 3032 nmethod *SharedRuntime::generate_dtrace_nmethod(
aoqi@1 3033 MacroAssembler *masm, methodHandle method) {
aoqi@1 3034
aoqi@1 3035
aoqi@1 3036 // generate_dtrace_nmethod is guarded by a mutex so we are sure to
aoqi@1 3037 // be single threaded in this method.
aoqi@1 3038 assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be");
aoqi@1 3039
aoqi@1 3040 // Fill in the signature array, for the calling-convention call.
aoqi@1 3041 int total_args_passed = method->size_of_parameters();
aoqi@1 3042
aoqi@1 3043 BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
aoqi@1 3044 VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
aoqi@1 3045
aoqi@1 3046 // The signature we are going to use for the trap that dtrace will see
aoqi@1 3047 // java/lang/String is converted. We drop "this" and any other object
aoqi@1 3048 // is converted to NULL. (A one-slot java/lang/Long object reference
aoqi@1 3049 // is converted to a two-slot long, which is why we double the allocation).
aoqi@1 3050 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2);
aoqi@1 3051 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2);
aoqi@1 3052
aoqi@1 3053 int i=0;
aoqi@1 3054 int total_strings = 0;
aoqi@1 3055 int first_arg_to_pass = 0;
aoqi@1 3056 int total_c_args = 0;
aoqi@1 3057
aoqi@1 3058 // Skip the receiver as dtrace doesn't want to see it
aoqi@1 3059 if( !method->is_static() ) {
aoqi@1 3060 in_sig_bt[i++] = T_OBJECT;
aoqi@1 3061 first_arg_to_pass = 1;
aoqi@1 3062 }
aoqi@1 3063
aoqi@1 3064 SignatureStream ss(method->signature());
aoqi@1 3065 for ( ; !ss.at_return_type(); ss.next()) {
aoqi@1 3066 BasicType bt = ss.type();
aoqi@1 3067 in_sig_bt[i++] = bt; // Collect remaining bits of signature
aoqi@1 3068 out_sig_bt[total_c_args++] = bt;
aoqi@1 3069 if( bt == T_OBJECT) {
aoqi@1 3070 symbolOop s = ss.as_symbol_or_null();
aoqi@1 3071 if (s == vmSymbols::java_lang_String()) {
aoqi@1 3072 total_strings++;
aoqi@1 3073 out_sig_bt[total_c_args-1] = T_ADDRESS;
aoqi@1 3074 } else if (s == vmSymbols::java_lang_Boolean() ||
aoqi@1 3075 s == vmSymbols::java_lang_Byte()) {
aoqi@1 3076 out_sig_bt[total_c_args-1] = T_BYTE;
aoqi@1 3077 } else if (s == vmSymbols::java_lang_Character() ||
aoqi@1 3078 s == vmSymbols::java_lang_Short()) {
aoqi@1 3079 out_sig_bt[total_c_args-1] = T_SHORT;
aoqi@1 3080 } else if (s == vmSymbols::java_lang_Integer() ||
aoqi@1 3081 s == vmSymbols::java_lang_Float()) {
aoqi@1 3082 out_sig_bt[total_c_args-1] = T_INT;
aoqi@1 3083 } else if (s == vmSymbols::java_lang_Long() ||
aoqi@1 3084 s == vmSymbols::java_lang_Double()) {
aoqi@1 3085 out_sig_bt[total_c_args-1] = T_LONG;
aoqi@1 3086 out_sig_bt[total_c_args++] = T_VOID;
aoqi@1 3087 }
aoqi@1 3088 } else if ( bt == T_LONG || bt == T_DOUBLE ) {
aoqi@1 3089 in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots
aoqi@1 3090 // We convert double to long
aoqi@1 3091 out_sig_bt[total_c_args-1] = T_LONG;
aoqi@1 3092 out_sig_bt[total_c_args++] = T_VOID;
aoqi@1 3093 } else if ( bt == T_FLOAT) {
aoqi@1 3094 // We convert float to int
aoqi@1 3095 out_sig_bt[total_c_args-1] = T_INT;
aoqi@1 3096 }
aoqi@1 3097 }
aoqi@1 3098
aoqi@1 3099 assert(i==total_args_passed, "validly parsed signature");
aoqi@1 3100
aoqi@1 3101 // Now get the compiled-Java layout as input arguments
aoqi@1 3102 int comp_args_on_stack;
aoqi@1 3103 comp_args_on_stack = SharedRuntime::java_calling_convention(
aoqi@1 3104 in_sig_bt, in_regs, total_args_passed, false);
aoqi@1 3105
aoqi@1 3106 // We have received a description of where all the java arg are located
aoqi@1 3107 // on entry to the wrapper. We need to convert these args to where
aoqi@1 3108 // the a native (non-jni) function would expect them. To figure out
aoqi@1 3109 // where they go we convert the java signature to a C signature and remove
aoqi@1 3110 // T_VOID for any long/double we might have received.
aoqi@1 3111
aoqi@1 3112
aoqi@1 3113 // Now figure out where the args must be stored and how much stack space
aoqi@1 3114 // they require (neglecting out_preserve_stack_slots but space for storing
aoqi@1 3115 // the 1st six register arguments). It's weird see int_stk_helper.
aoqi@1 3116 //
aoqi@1 3117 int out_arg_slots;
aoqi@1 3118 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args);
aoqi@1 3119
aoqi@1 3120 // Calculate the total number of stack slots we will need.
aoqi@1 3121
aoqi@1 3122 // First count the abi requirement plus all of the outgoing args
aoqi@1 3123 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
aoqi@1 3124
aoqi@1 3125 // Plus a temp for possible converion of float/double/long register args
aoqi@1 3126
aoqi@1 3127 int conversion_temp = stack_slots;
aoqi@1 3128 stack_slots += 2;
aoqi@1 3129
aoqi@1 3130
aoqi@1 3131 // Now space for the string(s) we must convert
aoqi@1 3132
aoqi@1 3133 int string_locs = stack_slots;
aoqi@1 3134 stack_slots += total_strings *
aoqi@1 3135 (max_dtrace_string_size / VMRegImpl::stack_slot_size);
aoqi@1 3136
aoqi@1 3137 // Ok The space we have allocated will look like:
aoqi@1 3138 //
aoqi@1 3139 //
aoqi@1 3140 // FP-> | |
aoqi@1 3141 // |---------------------|
aoqi@1 3142 // | string[n] |
aoqi@1 3143 // |---------------------| <- string_locs[n]
aoqi@1 3144 // | string[n-1] |
aoqi@1 3145 // |---------------------| <- string_locs[n-1]
aoqi@1 3146 // | ... |
aoqi@1 3147 // | ... |
aoqi@1 3148 // |---------------------| <- string_locs[1]
aoqi@1 3149 // | string[0] |
aoqi@1 3150 // |---------------------| <- string_locs[0]
aoqi@1 3151 // | temp |
aoqi@1 3152 // |---------------------| <- conversion_temp
aoqi@1 3153 // | outbound memory |
aoqi@1 3154 // | based arguments |
aoqi@1 3155 // | |
aoqi@1 3156 // |---------------------|
aoqi@1 3157 // | |
aoqi@1 3158 // SP-> | out_preserved_slots |
aoqi@1 3159 //
aoqi@1 3160 //
aoqi@1 3161
aoqi@1 3162 // Now compute actual number of stack words we need rounding to make
aoqi@1 3163 // stack properly aligned.
aoqi@1 3164 stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word);
aoqi@1 3165
aoqi@1 3166 int stack_size = stack_slots * VMRegImpl::stack_slot_size;
aoqi@1 3167
aoqi@1 3168 intptr_t start = (intptr_t)__ pc();
aoqi@1 3169
aoqi@1 3170 // First thing make an ic check to see if we should even be here
aoqi@1 3171
aoqi@1 3172 {
aoqi@1 3173 Label L;
aoqi@1 3174 const Register temp_reg = G3_scratch;
aoqi@1 3175 Address ic_miss(temp_reg, SharedRuntime::get_ic_miss_stub());
aoqi@1 3176 __ verify_oop(O0);
aoqi@1 3177 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
aoqi@1 3178 __ cmp(temp_reg, G5_inline_cache_reg);
aoqi@1 3179 __ brx(Assembler::equal, true, Assembler::pt, L);
aoqi@1 3180 __ delayed()->nop();
aoqi@1 3181
aoqi@1 3182 __ jump_to(ic_miss, 0);
aoqi@1 3183 __ delayed()->nop();
aoqi@1 3184 __ align(CodeEntryAlignment);
aoqi@1 3185 __ bind(L);
aoqi@1 3186 }
aoqi@1 3187
aoqi@1 3188 int vep_offset = ((intptr_t)__ pc()) - start;
aoqi@1 3189
aoqi@1 3190
aoqi@1 3191 // The instruction at the verified entry point must be 5 bytes or longer
aoqi@1 3192 // because it can be patched on the fly by make_non_entrant. The stack bang
aoqi@1 3193 // instruction fits that requirement.
aoqi@1 3194
aoqi@1 3195 // Generate stack overflow check before creating frame
aoqi@1 3196 __ generate_stack_overflow_check(stack_size);
aoqi@1 3197
aoqi@1 3198 assert(((intptr_t)__ pc() - start - vep_offset) >= 5,
aoqi@1 3199 "valid size for make_non_entrant");
aoqi@1 3200
aoqi@1 3201 // Generate a new frame for the wrapper.
aoqi@1 3202 __ save(SP, -stack_size, SP);
aoqi@1 3203
aoqi@1 3204 // Frame is now completed as far a size and linkage.
aoqi@1 3205
aoqi@1 3206 int frame_complete = ((intptr_t)__ pc()) - start;
aoqi@1 3207
aoqi@1 3208 #ifdef ASSERT
aoqi@1 3209 bool reg_destroyed[RegisterImpl::number_of_registers];
aoqi@1 3210 bool freg_destroyed[FloatRegisterImpl::number_of_registers];
aoqi@1 3211 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
aoqi@1 3212 reg_destroyed[r] = false;
aoqi@1 3213 }
aoqi@1 3214 for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
aoqi@1 3215 freg_destroyed[f] = false;
aoqi@1 3216 }
aoqi@1 3217
aoqi@1 3218 #endif /* ASSERT */
aoqi@1 3219
aoqi@1 3220 VMRegPair zero;
aoqi@1 3221 const Register g0 = G0; // without this we get a compiler warning (why??)
aoqi@1 3222 zero.set2(g0->as_VMReg());
aoqi@1 3223
aoqi@1 3224 int c_arg, j_arg;
aoqi@1 3225
aoqi@1 3226 Register conversion_off = noreg;
aoqi@1 3227
aoqi@1 3228 for (j_arg = first_arg_to_pass, c_arg = 0 ;
aoqi@1 3229 j_arg < total_args_passed ; j_arg++, c_arg++ ) {
aoqi@1 3230
aoqi@1 3231 VMRegPair src = in_regs[j_arg];
aoqi@1 3232 VMRegPair dst = out_regs[c_arg];
aoqi@1 3233
aoqi@1 3234 #ifdef ASSERT
aoqi@1 3235 if (src.first()->is_Register()) {
aoqi@1 3236 assert(!reg_destroyed[src.first()->as_Register()->encoding()], "ack!");
aoqi@1 3237 } else if (src.first()->is_FloatRegister()) {
aoqi@1 3238 assert(!freg_destroyed[src.first()->as_FloatRegister()->encoding(
aoqi@1 3239 FloatRegisterImpl::S)], "ack!");
aoqi@1 3240 }
aoqi@1 3241 if (dst.first()->is_Register()) {
aoqi@1 3242 reg_destroyed[dst.first()->as_Register()->encoding()] = true;
aoqi@1 3243 } else if (dst.first()->is_FloatRegister()) {
aoqi@1 3244 freg_destroyed[dst.first()->as_FloatRegister()->encoding(
aoqi@1 3245 FloatRegisterImpl::S)] = true;
aoqi@1 3246 }
aoqi@1 3247 #endif /* ASSERT */
aoqi@1 3248
aoqi@1 3249 switch (in_sig_bt[j_arg]) {
aoqi@1 3250 case T_ARRAY:
aoqi@1 3251 case T_OBJECT:
aoqi@1 3252 {
aoqi@1 3253 if (out_sig_bt[c_arg] == T_BYTE || out_sig_bt[c_arg] == T_SHORT ||
aoqi@1 3254 out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) {
aoqi@1 3255 // need to unbox a one-slot value
aoqi@1 3256 Register in_reg = L0;
aoqi@1 3257 Register tmp = L2;
aoqi@1 3258 if ( src.first()->is_reg() ) {
aoqi@1 3259 in_reg = src.first()->as_Register();
aoqi@1 3260 } else {
aoqi@1 3261 assert(Assembler::is_simm13(reg2offset(src.first()) + STACK_BIAS),
aoqi@1 3262 "must be");
aoqi@1 3263 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, in_reg);
aoqi@1 3264 }
aoqi@1 3265 // If the final destination is an acceptable register
aoqi@1 3266 if ( dst.first()->is_reg() ) {
aoqi@1 3267 if ( dst.is_single_phys_reg() || out_sig_bt[c_arg] != T_LONG ) {
aoqi@1 3268 tmp = dst.first()->as_Register();
aoqi@1 3269 }
aoqi@1 3270 }
aoqi@1 3271
aoqi@1 3272 Label skipUnbox;
aoqi@1 3273 if ( wordSize == 4 && out_sig_bt[c_arg] == T_LONG ) {
aoqi@1 3274 __ mov(G0, tmp->successor());
aoqi@1 3275 }
aoqi@1 3276 __ br_null(in_reg, true, Assembler::pn, skipUnbox);
aoqi@1 3277 __ delayed()->mov(G0, tmp);
aoqi@1 3278
aoqi@1 3279 BasicType bt = out_sig_bt[c_arg];
aoqi@1 3280 int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
aoqi@1 3281 switch (bt) {
aoqi@1 3282 case T_BYTE:
aoqi@1 3283 __ ldub(in_reg, box_offset, tmp); break;
aoqi@1 3284 case T_SHORT:
aoqi@1 3285 __ lduh(in_reg, box_offset, tmp); break;
aoqi@1 3286 case T_INT:
aoqi@1 3287 __ ld(in_reg, box_offset, tmp); break;
aoqi@1 3288 case T_LONG:
aoqi@1 3289 __ ld_long(in_reg, box_offset, tmp); break;
aoqi@1 3290 default: ShouldNotReachHere();
aoqi@1 3291 }
aoqi@1 3292
aoqi@1 3293 __ bind(skipUnbox);
aoqi@1 3294 // If tmp wasn't final destination copy to final destination
aoqi@1 3295 if (tmp == L2) {
aoqi@1 3296 VMRegPair tmp_as_VM = reg64_to_VMRegPair(L2);
aoqi@1 3297 if (out_sig_bt[c_arg] == T_LONG) {
aoqi@1 3298 long_move(masm, tmp_as_VM, dst);
aoqi@1 3299 } else {
aoqi@1 3300 move32_64(masm, tmp_as_VM, out_regs[c_arg]);
aoqi@1 3301 }
aoqi@1 3302 }
aoqi@1 3303 if (out_sig_bt[c_arg] == T_LONG) {
aoqi@1 3304 assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
aoqi@1 3305 ++c_arg; // move over the T_VOID to keep the loop indices in sync
aoqi@1 3306 }
aoqi@1 3307 } else if (out_sig_bt[c_arg] == T_ADDRESS) {
aoqi@1 3308 Register s =
aoqi@1 3309 src.first()->is_reg() ? src.first()->as_Register() : L2;
aoqi@1 3310 Register d =
aoqi@1 3311 dst.first()->is_reg() ? dst.first()->as_Register() : L2;
aoqi@1 3312
aoqi@1 3313 // We store the oop now so that the conversion pass can reach
aoqi@1 3314 // while in the inner frame. This will be the only store if
aoqi@1 3315 // the oop is NULL.
aoqi@1 3316 if (s != L2) {
aoqi@1 3317 // src is register
aoqi@1 3318 if (d != L2) {
aoqi@1 3319 // dst is register
aoqi@1 3320 __ mov(s, d);
aoqi@1 3321 } else {
aoqi@1 3322 assert(Assembler::is_simm13(reg2offset(dst.first()) +
aoqi@1 3323 STACK_BIAS), "must be");
aoqi@1 3324 __ st_ptr(s, SP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 3325 }
aoqi@1 3326 } else {
aoqi@1 3327 // src not a register
aoqi@1 3328 assert(Assembler::is_simm13(reg2offset(src.first()) +
aoqi@1 3329 STACK_BIAS), "must be");
aoqi@1 3330 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, d);
aoqi@1 3331 if (d == L2) {
aoqi@1 3332 assert(Assembler::is_simm13(reg2offset(dst.first()) +
aoqi@1 3333 STACK_BIAS), "must be");
aoqi@1 3334 __ st_ptr(d, SP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 3335 }
aoqi@1 3336 }
aoqi@1 3337 } else if (out_sig_bt[c_arg] != T_VOID) {
aoqi@1 3338 // Convert the arg to NULL
aoqi@1 3339 if (dst.first()->is_reg()) {
aoqi@1 3340 __ mov(G0, dst.first()->as_Register());
aoqi@1 3341 } else {
aoqi@1 3342 assert(Assembler::is_simm13(reg2offset(dst.first()) +
aoqi@1 3343 STACK_BIAS), "must be");
aoqi@1 3344 __ st_ptr(G0, SP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 3345 }
aoqi@1 3346 }
aoqi@1 3347 }
aoqi@1 3348 break;
aoqi@1 3349 case T_VOID:
aoqi@1 3350 break;
aoqi@1 3351
aoqi@1 3352 case T_FLOAT:
aoqi@1 3353 if (src.first()->is_stack()) {
aoqi@1 3354 // Stack to stack/reg is simple
aoqi@1 3355 move32_64(masm, src, dst);
aoqi@1 3356 } else {
aoqi@1 3357 if (dst.first()->is_reg()) {
aoqi@1 3358 // freg -> reg
aoqi@1 3359 int off =
aoqi@1 3360 STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
aoqi@1 3361 Register d = dst.first()->as_Register();
aoqi@1 3362 if (Assembler::is_simm13(off)) {
aoqi@1 3363 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
aoqi@1 3364 SP, off);
aoqi@1 3365 __ ld(SP, off, d);
aoqi@1 3366 } else {
aoqi@1 3367 if (conversion_off == noreg) {
aoqi@1 3368 __ set(off, L6);
aoqi@1 3369 conversion_off = L6;
aoqi@1 3370 }
aoqi@1 3371 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
aoqi@1 3372 SP, conversion_off);
aoqi@1 3373 __ ld(SP, conversion_off , d);
aoqi@1 3374 }
aoqi@1 3375 } else {
aoqi@1 3376 // freg -> mem
aoqi@1 3377 int off = STACK_BIAS + reg2offset(dst.first());
aoqi@1 3378 if (Assembler::is_simm13(off)) {
aoqi@1 3379 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
aoqi@1 3380 SP, off);
aoqi@1 3381 } else {
aoqi@1 3382 if (conversion_off == noreg) {
aoqi@1 3383 __ set(off, L6);
aoqi@1 3384 conversion_off = L6;
aoqi@1 3385 }
aoqi@1 3386 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
aoqi@1 3387 SP, conversion_off);
aoqi@1 3388 }
aoqi@1 3389 }
aoqi@1 3390 }
aoqi@1 3391 break;
aoqi@1 3392
aoqi@1 3393 case T_DOUBLE:
aoqi@1 3394 assert( j_arg + 1 < total_args_passed &&
aoqi@1 3395 in_sig_bt[j_arg + 1] == T_VOID &&
aoqi@1 3396 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
aoqi@1 3397 if (src.first()->is_stack()) {
aoqi@1 3398 // Stack to stack/reg is simple
aoqi@1 3399 long_move(masm, src, dst);
aoqi@1 3400 } else {
aoqi@1 3401 Register d = dst.first()->is_reg() ? dst.first()->as_Register() : L2;
aoqi@1 3402
aoqi@1 3403 // Destination could be an odd reg on 32bit in which case
aoqi@1 3404 // we can't load direct to the destination.
aoqi@1 3405
aoqi@1 3406 if (!d->is_even() && wordSize == 4) {
aoqi@1 3407 d = L2;
aoqi@1 3408 }
aoqi@1 3409 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
aoqi@1 3410 if (Assembler::is_simm13(off)) {
aoqi@1 3411 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
aoqi@1 3412 SP, off);
aoqi@1 3413 __ ld_long(SP, off, d);
aoqi@1 3414 } else {
aoqi@1 3415 if (conversion_off == noreg) {
aoqi@1 3416 __ set(off, L6);
aoqi@1 3417 conversion_off = L6;
aoqi@1 3418 }
aoqi@1 3419 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
aoqi@1 3420 SP, conversion_off);
aoqi@1 3421 __ ld_long(SP, conversion_off, d);
aoqi@1 3422 }
aoqi@1 3423 if (d == L2) {
aoqi@1 3424 long_move(masm, reg64_to_VMRegPair(L2), dst);
aoqi@1 3425 }
aoqi@1 3426 }
aoqi@1 3427 break;
aoqi@1 3428
aoqi@1 3429 case T_LONG :
aoqi@1 3430 // 32bit can't do a split move of something like g1 -> O0, O1
aoqi@1 3431 // so use a memory temp
aoqi@1 3432 if (src.is_single_phys_reg() && wordSize == 4) {
aoqi@1 3433 Register tmp = L2;
aoqi@1 3434 if (dst.first()->is_reg() &&
aoqi@1 3435 (wordSize == 8 || dst.first()->as_Register()->is_even())) {
aoqi@1 3436 tmp = dst.first()->as_Register();
aoqi@1 3437 }
aoqi@1 3438
aoqi@1 3439 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
aoqi@1 3440 if (Assembler::is_simm13(off)) {
aoqi@1 3441 __ stx(src.first()->as_Register(), SP, off);
aoqi@1 3442 __ ld_long(SP, off, tmp);
aoqi@1 3443 } else {
aoqi@1 3444 if (conversion_off == noreg) {
aoqi@1 3445 __ set(off, L6);
aoqi@1 3446 conversion_off = L6;
aoqi@1 3447 }
aoqi@1 3448 __ stx(src.first()->as_Register(), SP, conversion_off);
aoqi@1 3449 __ ld_long(SP, conversion_off, tmp);
aoqi@1 3450 }
aoqi@1 3451
aoqi@1 3452 if (tmp == L2) {
aoqi@1 3453 long_move(masm, reg64_to_VMRegPair(L2), dst);
aoqi@1 3454 }
aoqi@1 3455 } else {
aoqi@1 3456 long_move(masm, src, dst);
aoqi@1 3457 }
aoqi@1 3458 break;
aoqi@1 3459
aoqi@1 3460 case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
aoqi@1 3461
aoqi@1 3462 default:
aoqi@1 3463 move32_64(masm, src, dst);
aoqi@1 3464 }
aoqi@1 3465 }
aoqi@1 3466
aoqi@1 3467
aoqi@1 3468 // If we have any strings we must store any register based arg to the stack
aoqi@1 3469 // This includes any still live xmm registers too.
aoqi@1 3470
aoqi@1 3471 if (total_strings > 0 ) {
aoqi@1 3472
aoqi@1 3473 // protect all the arg registers
aoqi@1 3474 __ save_frame(0);
aoqi@1 3475 __ mov(G2_thread, L7_thread_cache);
aoqi@1 3476 const Register L2_string_off = L2;
aoqi@1 3477
aoqi@1 3478 // Get first string offset
aoqi@1 3479 __ set(string_locs * VMRegImpl::stack_slot_size, L2_string_off);
aoqi@1 3480
aoqi@1 3481 for (c_arg = 0 ; c_arg < total_c_args ; c_arg++ ) {
aoqi@1 3482 if (out_sig_bt[c_arg] == T_ADDRESS) {
aoqi@1 3483
aoqi@1 3484 VMRegPair dst = out_regs[c_arg];
aoqi@1 3485 const Register d = dst.first()->is_reg() ?
aoqi@1 3486 dst.first()->as_Register()->after_save() : noreg;
aoqi@1 3487
aoqi@1 3488 // It's a string the oop and it was already copied to the out arg
aoqi@1 3489 // position
aoqi@1 3490 if (d != noreg) {
aoqi@1 3491 __ mov(d, O0);
aoqi@1 3492 } else {
aoqi@1 3493 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
aoqi@1 3494 "must be");
aoqi@1 3495 __ ld_ptr(FP, reg2offset(dst.first()) + STACK_BIAS, O0);
aoqi@1 3496 }
aoqi@1 3497 Label skip;
aoqi@1 3498
aoqi@1 3499 __ br_null(O0, false, Assembler::pn, skip);
aoqi@1 3500 __ delayed()->add(FP, L2_string_off, O1);
aoqi@1 3501
aoqi@1 3502 if (d != noreg) {
aoqi@1 3503 __ mov(O1, d);
aoqi@1 3504 } else {
aoqi@1 3505 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
aoqi@1 3506 "must be");
aoqi@1 3507 __ st_ptr(O1, FP, reg2offset(dst.first()) + STACK_BIAS);
aoqi@1 3508 }
aoqi@1 3509
aoqi@1 3510 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::get_utf),
aoqi@1 3511 relocInfo::runtime_call_type);
aoqi@1 3512 __ delayed()->add(L2_string_off, max_dtrace_string_size, L2_string_off);
aoqi@1 3513
aoqi@1 3514 __ bind(skip);
aoqi@1 3515
aoqi@1 3516 }
aoqi@1 3517
aoqi@1 3518 }
aoqi@1 3519 __ mov(L7_thread_cache, G2_thread);
aoqi@1 3520 __ restore();
aoqi@1 3521
aoqi@1 3522 }
aoqi@1 3523
aoqi@1 3524
aoqi@1 3525 // Ok now we are done. Need to place the nop that dtrace wants in order to
aoqi@1 3526 // patch in the trap
aoqi@1 3527
aoqi@1 3528 int patch_offset = ((intptr_t)__ pc()) - start;
aoqi@1 3529
aoqi@1 3530 __ nop();
aoqi@1 3531
aoqi@1 3532
aoqi@1 3533 // Return
aoqi@1 3534
aoqi@1 3535 __ ret();
aoqi@1 3536 __ delayed()->restore();
aoqi@1 3537
aoqi@1 3538 __ flush();
aoqi@1 3539
aoqi@1 3540 nmethod *nm = nmethod::new_dtrace_nmethod(
aoqi@1 3541 method, masm->code(), vep_offset, patch_offset, frame_complete,
aoqi@1 3542 stack_slots / VMRegImpl::slots_per_word);
aoqi@1 3543 return nm;
aoqi@1 3544
aoqi@1 3545 }
aoqi@1 3546
aoqi@1 3547 #endif // HAVE_DTRACE_H
aoqi@1 3548
aoqi@1 3549 // this function returns the adjust size (in number of words) to a c2i adapter
aoqi@1 3550 // activation for use during deoptimization
aoqi@1 3551 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
aoqi@1 3552 return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
aoqi@1 3553 }
aoqi@1 3554
aoqi@1 3555 // "Top of Stack" slots that may be unused by the calling convention but must
aoqi@1 3556 // otherwise be preserved.
aoqi@1 3557 // On Intel these are not necessary and the value can be zero.
aoqi@1 3558 // On Sparc this describes the words reserved for storing a register window
aoqi@1 3559 // when an interrupt occurs.
aoqi@1 3560 uint SharedRuntime::out_preserve_stack_slots() {
aoqi@1 3561 //return frame::register_save_words * VMRegImpl::slots_per_word;
aoqi@1 3562 return 0;
aoqi@1 3563 }
aoqi@1 3564 /*
aoqi@1 3565 static void gen_new_frame(MacroAssembler* masm, bool deopt) {
aoqi@1 3566 //
aoqi@1 3567 // Common out the new frame generation for deopt and uncommon trap
aoqi@1 3568 //
aoqi@1 3569 Register G3pcs = G3_scratch; // Array of new pcs (input)
aoqi@1 3570 Register Oreturn0 = O0;
aoqi@1 3571 Register Oreturn1 = O1;
aoqi@1 3572 Register O2UnrollBlock = O2;
aoqi@1 3573 Register O3array = O3; // Array of frame sizes (input)
aoqi@1 3574 Register O4array_size = O4; // number of frames (input)
aoqi@1 3575 Register O7frame_size = O7; // number of frames (input)
aoqi@1 3576
aoqi@1 3577 __ ld_ptr(O3array, 0, O7frame_size);
aoqi@1 3578 __ sub(G0, O7frame_size, O7frame_size);
aoqi@1 3579 __ save(SP, O7frame_size, SP);
aoqi@1 3580 __ ld_ptr(G3pcs, 0, I7); // load frame's new pc
aoqi@1 3581
aoqi@1 3582 #ifdef ASSERT
aoqi@1 3583 // make sure that the frames are aligned properly
aoqi@1 3584 #ifndef _LP64
aoqi@1 3585 __ btst(wordSize*2-1, SP);
aoqi@1 3586 __ breakpoint_trap(Assembler::notZero);
aoqi@1 3587 #endif
aoqi@1 3588 #endif
aoqi@1 3589
aoqi@1 3590 // Deopt needs to pass some extra live values from frame to frame
aoqi@1 3591
aoqi@1 3592 if (deopt) {
aoqi@1 3593 __ mov(Oreturn0->after_save(), Oreturn0);
aoqi@1 3594 __ mov(Oreturn1->after_save(), Oreturn1);
aoqi@1 3595 }
aoqi@1 3596
aoqi@1 3597 __ mov(O4array_size->after_save(), O4array_size);
aoqi@1 3598 __ sub(O4array_size, 1, O4array_size);
aoqi@1 3599 __ mov(O3array->after_save(), O3array);
aoqi@1 3600 __ mov(O2UnrollBlock->after_save(), O2UnrollBlock);
aoqi@1 3601 __ add(G3pcs, wordSize, G3pcs); // point to next pc value
aoqi@1 3602
aoqi@1 3603 #ifdef ASSERT
aoqi@1 3604 // trash registers to show a clear pattern in backtraces
aoqi@1 3605 __ set(0xDEAD0000, I0);
aoqi@1 3606 __ add(I0, 2, I1);
aoqi@1 3607 __ add(I0, 4, I2);
aoqi@1 3608 __ add(I0, 6, I3);
aoqi@1 3609 __ add(I0, 8, I4);
aoqi@1 3610 // Don't touch I5 could have valuable savedSP
aoqi@1 3611 __ set(0xDEADBEEF, L0);
aoqi@1 3612 __ mov(L0, L1);
aoqi@1 3613 __ mov(L0, L2);
aoqi@1 3614 __ mov(L0, L3);
aoqi@1 3615 __ mov(L0, L4);
aoqi@1 3616 __ mov(L0, L5);
aoqi@1 3617
aoqi@1 3618 // trash the return value as there is nothing to return yet
aoqi@1 3619 __ set(0xDEAD0001, O7);
aoqi@1 3620 #endif
aoqi@1 3621
aoqi@1 3622 __ mov(SP, O5_savedSP);
aoqi@1 3623 }
aoqi@1 3624
aoqi@1 3625
aoqi@1 3626 static void make_new_frames(MacroAssembler* masm, bool deopt) {
aoqi@1 3627 //
aoqi@1 3628 // loop through the UnrollBlock info and create new frames
aoqi@1 3629 //
aoqi@1 3630 Register G3pcs = G3_scratch;
aoqi@1 3631 Register Oreturn0 = O0;
aoqi@1 3632 Register Oreturn1 = O1;
aoqi@1 3633 Register O2UnrollBlock = O2;
aoqi@1 3634 Register O3array = O3;
aoqi@1 3635 Register O4array_size = O4;
aoqi@1 3636 Label loop;
aoqi@1 3637
aoqi@1 3638 // Before we make new frames, check to see if stack is available.
aoqi@1 3639 // Do this after the caller's return address is on top of stack
aoqi@1 3640 if (UseStackBanging) {
aoqi@1 3641 // Get total frame size for interpreted frames
aoqi@1 3642 __ ld(Address(O2UnrollBlock, 0,
aoqi@1 3643 Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()), O4);
aoqi@1 3644 __ bang_stack_size(O4, O3, G3_scratch);
aoqi@1 3645 }
aoqi@1 3646
aoqi@1 3647 __ ld(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()), O4array_size);
aoqi@1 3648 __ ld_ptr(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()), G3pcs);
aoqi@1 3649
aoqi@1 3650 __ ld_ptr(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()), O3array);
aoqi@1 3651
aoqi@1 3652 // Adjust old interpreter frame to make space for new frame's extra java locals
aoqi@1 3653 //
aoqi@1 3654 // We capture the original sp for the transition frame only because it is needed in
aoqi@1 3655 // order to properly calculate interpreter_sp_adjustment. Even though in real life
aoqi@1 3656 // every interpreter frame captures a savedSP it is only needed at the transition
aoqi@1 3657 // (fortunately). If we had to have it correct everywhere then we would need to
aoqi@1 3658 // be told the sp_adjustment for each frame we create. If the frame size array
aoqi@1 3659 // were to have twice the frame count entries then we could have pairs [sp_adjustment, frame_size]
aoqi@1 3660 // for each frame we create and keep up the illusion every where.
aoqi@1 3661 //
aoqi@1 3662
aoqi@1 3663 __ ld(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes()), O7);
aoqi@1 3664 __ mov(SP, O5_savedSP); // remember initial sender's original sp before adjustment
aoqi@1 3665 __ sub(SP, O7, SP);
aoqi@1 3666
aoqi@1 3667 #ifdef ASSERT
aoqi@1 3668 // make sure that there is at least one entry in the array
aoqi@1 3669 __ tst(O4array_size);
aoqi@1 3670 __ breakpoint_trap(Assembler::zero);
aoqi@1 3671 #endif
aoqi@1 3672
aoqi@1 3673 // Now push the new interpreter frames
aoqi@1 3674 __ bind(loop);
aoqi@1 3675
aoqi@1 3676 // allocate a new frame, filling the registers
aoqi@1 3677
aoqi@1 3678 gen_new_frame(masm, deopt); // allocate an interpreter frame
aoqi@1 3679
aoqi@1 3680 __ tst(O4array_size);
aoqi@1 3681 __ br(Assembler::notZero, false, Assembler::pn, loop);
aoqi@1 3682 __ delayed()->add(O3array, wordSize, O3array);
aoqi@1 3683 __ ld_ptr(G3pcs, 0, O7); // load final frame new pc
aoqi@1 3684
aoqi@1 3685 }
aoqi@1 3686 */
aoqi@1 3687
aoqi@1 3688 //------------------------------generate_deopt_blob----------------------------
aoqi@1 3689 // Ought to generate an ideal graph & compile, but here's some SPARC ASM
aoqi@1 3690 // instead.
aoqi@1 3691 void SharedRuntime::generate_deopt_blob() {
aoqi@1 3692 // allocate space for the code
aoqi@1 3693 ResourceMark rm;
aoqi@1 3694 // setup code generation tools
aoqi@1 3695 //CodeBuffer buffer ("deopt_blob", 4000, 2048);
aoqi@1 3696 CodeBuffer buffer ("deopt_blob", 8000, 2048);//aoqi FIXME for debug
aoqi@1 3697 MacroAssembler* masm = new MacroAssembler( & buffer);
aoqi@1 3698 int frame_size_in_words;
aoqi@1 3699 OopMap* map = NULL;
aoqi@1 3700 // Account for the extra args we place on the stack
aoqi@1 3701 // by the time we call fetch_unroll_info
aoqi@1 3702 const int additional_words = 2; // deopt kind, thread
aoqi@1 3703
aoqi@1 3704 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 3705
aoqi@1 3706 address start = __ pc();
aoqi@1 3707 Label cont;
aoqi@1 3708 // we use S3 for DeOpt reason register
aoqi@1 3709 Register reason = S3;
aoqi@1 3710 // use S6 for thread register
aoqi@1 3711 Register thread = TREG;
aoqi@1 3712 // use S7 for fetch_unroll_info returned UnrollBlock
aoqi@1 3713 Register unroll = S7;
aoqi@1 3714 // Prolog for non exception case!
aoqi@1 3715 // Correct the return address we were given.
aoqi@1 3716 //FIXME, return address is on the tos or Ra?
fujie@375 3717 __ addi(RA, RA, - (NativeCall::return_address_offset_long));
aoqi@1 3718 // Save everything in sight.
aoqi@1 3719 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
aoqi@1 3720 // Normal deoptimization
aoqi@1 3721 __ move(reason, Deoptimization::Unpack_deopt);
aoqi@1 3722 __ b(cont);
aoqi@1 3723 __ delayed()->nop();
aoqi@1 3724
aoqi@1 3725 int reexecute_offset = __ pc() - start;
aoqi@1 3726
aoqi@1 3727 // Reexecute case
aoqi@1 3728 // return address is the pc describes what bci to do re-execute at
aoqi@1 3729
aoqi@1 3730 // No need to update map as each call to save_live_registers will produce identical oopmap
aoqi@1 3731 //__ addi(RA, RA, - (NativeCall::return_address_offset));
aoqi@1 3732 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
aoqi@1 3733 __ move(reason, Deoptimization::Unpack_reexecute);
aoqi@1 3734 __ b(cont);
aoqi@1 3735 __ delayed()->nop();
aoqi@1 3736
aoqi@1 3737 int exception_offset = __ pc() - start;
aoqi@1 3738 // Prolog for exception case
aoqi@1 3739
aoqi@1 3740 // all registers are dead at this entry point, except for eax and
aoqi@1 3741 // edx which contain the exception oop and exception pc
aoqi@1 3742 // respectively. Set them in TLS and fall thru to the
aoqi@1 3743 // unpack_with_exception_in_tls entry point.
aoqi@1 3744
aoqi@1 3745 __ get_thread(thread);
aoqi@1 3746 __ st_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset()));
aoqi@1 3747 __ st_ptr(V0, thread, in_bytes(JavaThread::exception_oop_offset()));
aoqi@1 3748 int exception_in_tls_offset = __ pc() - start;
aoqi@1 3749 // new implementation because exception oop is now passed in JavaThread
aoqi@1 3750
aoqi@1 3751 // Prolog for exception case
aoqi@1 3752 // All registers must be preserved because they might be used by LinearScan
aoqi@1 3753 // Exceptiop oop and throwing PC are passed in JavaThread
aoqi@1 3754 // tos: stack at point of call to method that threw the exception (i.e. only
aoqi@1 3755 // args are on the stack, no return address)
aoqi@1 3756
aoqi@1 3757 // Return address will be patched later with the throwing pc. The correct value is not
aoqi@1 3758 // available now because loading it from memory would destroy registers.
aoqi@1 3759 // Save everything in sight.
aoqi@1 3760 // No need to update map as each call to save_live_registers will produce identical oopmap
fujie@375 3761 __ addi(RA, RA, - (NativeCall::return_address_offset_long));
aoqi@1 3762 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words);
aoqi@1 3763
aoqi@1 3764 // Now it is safe to overwrite any register
aoqi@1 3765 // store the correct deoptimization type
aoqi@1 3766 __ move(reason, Deoptimization::Unpack_exception);
aoqi@1 3767 // load throwing pc from JavaThread and patch it as the return address
aoqi@1 3768 // of the current frame. Then clear the field in JavaThread
aoqi@1 3769 __ get_thread(thread);
aoqi@1 3770 __ ld_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset()));
aoqi@1 3771 __ st_ptr(V1, SP, RegisterSaver::raOffset() * wordSize); //save ra
aoqi@1 3772 __ st_ptr(R0, thread, in_bytes(JavaThread::exception_pc_offset()));
aoqi@1 3773
aoqi@1 3774
aoqi@1 3775 #ifdef ASSERT
aoqi@1 3776 // verify that there is really an exception oop in JavaThread
aoqi@1 3777 __ ld_ptr(AT, thread, in_bytes(JavaThread::exception_oop_offset()));
aoqi@1 3778 __ verify_oop(AT);
aoqi@1 3779 // verify that there is no pending exception
aoqi@1 3780 Label no_pending_exception;
aoqi@1 3781 __ ld_ptr(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 3782 __ beq(AT, R0, no_pending_exception);
aoqi@1 3783 __ delayed()->nop();
aoqi@1 3784 __ stop("must not have pending exception here");
aoqi@1 3785 __ bind(no_pending_exception);
aoqi@1 3786 #endif
aoqi@1 3787 __ bind(cont);
aoqi@1 3788 // Compiled code leaves the floating point stack dirty, empty it.
aoqi@1 3789 __ empty_FPU_stack();
aoqi@1 3790
aoqi@1 3791
aoqi@1 3792 // Call C code. Need thread and this frame, but NOT official VM entry
aoqi@1 3793 // crud. We cannot block on this call, no GC can happen.
aoqi@1 3794 #ifndef OPT_THREAD
aoqi@1 3795 __ get_thread(thread);
aoqi@1 3796 #endif
aoqi@1 3797
aoqi@1 3798 __ move(A0, thread);
aoqi@1 3799 __ addi(SP, SP, -additional_words * wordSize);
aoqi@1 3800
aoqi@1 3801 __ set_last_Java_frame(NOREG, NOREG, NULL);
aoqi@1 3802
aoqi@1 3803 // Call fetch_unroll_info(). Need thread and this frame, but NOT official VM entry - cannot block on
aoqi@1 3804 // this call, no GC can happen. Call should capture return values.
aoqi@1 3805
aoqi@1 3806 __ relocate(relocInfo::internal_pc_type);
aoqi@1 3807 {
fujie@373 3808 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 28;
fujie@368 3809 __ patchable_set48(AT, save_pc);
aoqi@1 3810 }
aoqi@1 3811 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@1 3812
aoqi@1 3813 __ call((address)Deoptimization::fetch_unroll_info);
aoqi@1 3814 //__ call(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info), relocInfo::runtime_call_type);
aoqi@1 3815 __ delayed()->nop();
aoqi@1 3816 oop_maps->add_gc_map(__ pc() - start, map);
aoqi@1 3817 __ addiu(SP, SP, additional_words * wordSize);
aoqi@1 3818 __ get_thread(thread);
aoqi@1 3819 __ reset_last_Java_frame(false, true);
aoqi@1 3820
aoqi@1 3821 // Load UnrollBlock into S7
aoqi@1 3822 __ move(unroll, V0);
aoqi@1 3823
aoqi@1 3824
aoqi@1 3825 // Move the unpack kind to a safe place in the UnrollBlock because
aoqi@1 3826 // we are very short of registers
aoqi@1 3827
aoqi@1 3828 Address unpack_kind(unroll, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes());
aoqi@1 3829 //__ pop(reason);
aoqi@1 3830 __ sw(reason, unpack_kind);
aoqi@1 3831 // save the unpack_kind value
aoqi@1 3832 // Retrieve the possible live values (return values)
aoqi@1 3833 // All callee save registers representing jvm state
aoqi@1 3834 // are now in the vframeArray.
aoqi@1 3835
aoqi@1 3836 Label noException;
aoqi@1 3837 __ move(AT, Deoptimization::Unpack_exception);
aoqi@1 3838 __ bne(AT, reason, noException);// Was exception pending?
aoqi@1 3839 __ delayed()->nop();
aoqi@1 3840 __ ld_ptr(V0, thread, in_bytes(JavaThread::exception_oop_offset()));
aoqi@1 3841 __ ld_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset()));
aoqi@1 3842 __ st_ptr(R0, thread, in_bytes(JavaThread::exception_pc_offset()));
aoqi@1 3843 __ st_ptr(R0, thread, in_bytes(JavaThread::exception_oop_offset()));
aoqi@1 3844
aoqi@1 3845 __ verify_oop(V0);
aoqi@1 3846
aoqi@1 3847 // Overwrite the result registers with the exception results.
aoqi@1 3848 __ st_ptr(V0, SP, RegisterSaver::v0Offset()*wordSize);
aoqi@1 3849 __ st_ptr(V1, SP, RegisterSaver::v1Offset()*wordSize);
aoqi@1 3850
aoqi@1 3851 __ bind(noException);
aoqi@1 3852
aoqi@1 3853
aoqi@1 3854 // Stack is back to only having register save data on the stack.
aoqi@1 3855 // Now restore the result registers. Everything else is either dead or captured
aoqi@1 3856 // in the vframeArray.
aoqi@1 3857
aoqi@1 3858 RegisterSaver::restore_result_registers(masm);
aoqi@1 3859 // All of the register save area has been popped of the stack. Only the
aoqi@1 3860 // return address remains.
aoqi@1 3861 // Pop all the frames we must move/replace.
aoqi@1 3862 // Frame picture (youngest to oldest)
aoqi@1 3863 // 1: self-frame (no frame link)
aoqi@1 3864 // 2: deopting frame (no frame link)
aoqi@1 3865 // 3: caller of deopting frame (could be compiled/interpreted).
aoqi@1 3866 //
aoqi@1 3867 // Note: by leaving the return address of self-frame on the stack
aoqi@1 3868 // and using the size of frame 2 to adjust the stack
aoqi@1 3869 // when we are done the return to frame 3 will still be on the stack.
aoqi@1 3870
aoqi@1 3871 // register for the sender's sp
aoqi@1 3872 Register sender_sp = Rsender;
aoqi@1 3873 // register for frame pcs
aoqi@1 3874 Register pcs = T0;
aoqi@1 3875 // register for frame sizes
aoqi@1 3876 Register sizes = T1;
aoqi@1 3877 // register for frame count
aoqi@1 3878 Register count = T3;
aoqi@1 3879
aoqi@1 3880 // Pop deoptimized frame
aoqi@1 3881 __ lw(AT, unroll, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes());
aoqi@1 3882 __ add(SP, SP, AT);
aoqi@1 3883 // sp should be pointing at the return address to the caller (3)
aoqi@1 3884
aoqi@1 3885 // Load array of frame pcs into pcs
aoqi@1 3886 __ ld_ptr(pcs, unroll, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes());
aoqi@1 3887 __ addi(SP, SP, wordSize); // trash the old pc
aoqi@1 3888 // Load array of frame sizes into T6
aoqi@1 3889 __ ld_ptr(sizes, unroll, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes());
aoqi@1 3890
aoqi@1 3891
aoqi@1 3892
aoqi@1 3893 // Load count of frams into T3
aoqi@1 3894 __ lw(count, unroll, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes());
aoqi@1 3895 // Pick up the initial fp we should save
aoqi@1 3896 __ ld(FP, unroll, Deoptimization::UnrollBlock::initial_info_offset_in_bytes());
aoqi@1 3897 // Now adjust the caller's stack to make up for the extra locals
aoqi@1 3898 // but record the original sp so that we can save it in the skeletal interpreter
aoqi@1 3899 // frame and the stack walking of interpreter_sender will get the unextended sp
aoqi@1 3900 // value and not the "real" sp value.
aoqi@1 3901 __ move(sender_sp, SP);
aoqi@1 3902 __ lw(AT, unroll, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes());
aoqi@1 3903 __ sub(SP, SP, AT);
aoqi@1 3904
aoqi@1 3905 // Push interpreter frames in a loop
aoqi@1 3906 /*
aoqi@1 3907 *
aoqi@1 3908 Loop:
aoqi@1 3909 0x000000555bd82d18: lw t2, 0x0(t1) ; lw sizes[i] <--- error lw->ld
aoqi@1 3910 0x000000555bd82d1c: ld at, 0x0(t0) ; ld pcs[i]
aoqi@1 3911 0x000000555bd82d20: daddi t2, t2, 0xfffffff0 ; t2 -= 16
aoqi@1 3912 0x000000555bd82d24: daddi sp, sp, 0xfffffff0
aoqi@1 3913 0x000000555bd82d28: sd fp, 0x0(sp) ; push fp
aoqi@1 3914 0x000000555bd82d2c: sd at, 0x8(sp) ; push at
aoqi@1 3915 0x000000555bd82d30: dadd fp, sp, zero ; fp <- sp
aoqi@1 3916 0x000000555bd82d34: dsub sp, sp, t2 ; sp -= t2
aoqi@1 3917 0x000000555bd82d38: sd zero, 0xfffffff0(fp) ; __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize);
aoqi@1 3918 0x000000555bd82d3c: sd s4, 0xfffffff8(fp) ; __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize);
aoqi@1 3919 0x000000555bd82d40: dadd s4, sp, zero ; move(sender_sp, SP);
aoqi@1 3920 0x000000555bd82d44: daddi t3, t3, 0xffffffff ; count --
aoqi@1 3921 0x000000555bd82d48: daddi t1, t1, 0x4 ; sizes += 4
aoqi@1 3922 0x000000555bd82d4c: bne t3, zero, 0x000000555bd82d18
aoqi@1 3923 0x000000555bd82d50: daddi t0, t0, 0x4 ; <--- error t0 += 8
aoqi@1 3924 */
aoqi@1 3925
aoqi@1 3926 // pcs[0] = frame_pcs[0] = deopt_sender.raw_pc(); regex.split
aoqi@1 3927 Label loop;
aoqi@1 3928 __ bind(loop);
aoqi@1 3929 __ ld(T2, sizes, 0); // Load frame size
aoqi@1 3930 __ ld_ptr(AT, pcs, 0); // save return address
aoqi@1 3931 __ addi(T2, T2, -2*wordSize); // we'll push pc and rbp, by hand
aoqi@1 3932 __ push2(AT, FP);
aoqi@1 3933 __ move(FP, SP);
aoqi@1 3934 __ sub(SP, SP, T2); // Prolog!
aoqi@1 3935 // This value is corrected by layout_activation_impl
aoqi@1 3936 __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize);
aoqi@1 3937 __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize);// Make it walkable
aoqi@1 3938 __ move(sender_sp, SP); // pass to next frame
aoqi@1 3939 __ addi(count, count, -1); // decrement counter
aoqi@1 3940 __ addi(sizes, sizes, wordSize); // Bump array pointer (sizes)
aoqi@1 3941 __ bne(count, R0, loop);
aoqi@1 3942 __ delayed()->addi(pcs, pcs, wordSize); // Bump array pointer (pcs)
aoqi@1 3943 __ ld(AT, pcs, 0); // frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0);
aoqi@1 3944 // Re-push self-frame
aoqi@1 3945 __ push2(AT, FP);
aoqi@1 3946 __ move(FP, SP);
aoqi@1 3947 __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize);
aoqi@1 3948 __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize);
aoqi@1 3949 __ addi(SP, SP, -(frame_size_in_words - 2 - additional_words) * wordSize);
aoqi@1 3950
aoqi@1 3951 // Restore frame locals after moving the frame
aoqi@1 3952 __ sd(V0, SP, RegisterSaver::v0Offset() * wordSize);
aoqi@1 3953 __ sd(V1, SP, RegisterSaver::v1Offset() * wordSize);
aoqi@1 3954 __ sdc1(F0, SP, RegisterSaver::fpResultOffset()* wordSize);// Pop float stack and store in local
aoqi@1 3955 __ sdc1(F1, SP, (RegisterSaver::fpResultOffset() + 1) * wordSize);
aoqi@1 3956
aoqi@1 3957
aoqi@1 3958 // Call unpack_frames(). Need thread and this frame, but NOT official VM entry - cannot block on
aoqi@1 3959 // this call, no GC can happen.
aoqi@1 3960 __ move(A1, reason); // exec_mode
aoqi@1 3961 __ get_thread(thread);
aoqi@1 3962 __ move(A0, thread); // thread
aoqi@1 3963 __ addi(SP, SP, (-additional_words) *wordSize);
aoqi@1 3964
aoqi@1 3965 // set last_Java_sp, last_Java_fp
aoqi@1 3966 __ set_last_Java_frame(NOREG, FP, NULL);
aoqi@1 3967
aoqi@1 3968 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 3969 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI
aoqi@1 3970
aoqi@1 3971 __ relocate(relocInfo::internal_pc_type);
aoqi@1 3972 {
fujie@373 3973 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 28;
fujie@368 3974 __ patchable_set48(AT, save_pc);
aoqi@1 3975 }
aoqi@1 3976 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@1 3977
aoqi@1 3978 //__ call(Deoptimization::unpack_frames);
aoqi@1 3979 __ call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), relocInfo::runtime_call_type);
aoqi@1 3980 __ delayed()->nop();
aoqi@1 3981 // Revert SP alignment after call since we're going to do some SP relative addressing below
aoqi@1 3982 __ ld(SP, thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 3983 // Set an oopmap for the call site
aoqi@1 3984 oop_maps->add_gc_map(__ offset(), new OopMap( frame_size_in_words , 0));
aoqi@1 3985
aoqi@1 3986 __ push(V0);
aoqi@1 3987
aoqi@1 3988 __ get_thread(thread);
chenhaoxuan@361 3989 __ reset_last_Java_frame(true, true);
aoqi@1 3990
aoqi@1 3991 // Collect return values
aoqi@1 3992 __ ld(V0, SP, (RegisterSaver::v0Offset() + additional_words +1) * wordSize);
aoqi@1 3993 __ ld(V1, SP, (RegisterSaver::v1Offset() + additional_words +1) * wordSize);
aoqi@1 3994 __ ldc1(F0, SP, RegisterSaver::fpResultOffset()* wordSize);// Pop float stack and store in local
aoqi@1 3995 __ ldc1(F1, SP, (RegisterSaver::fpResultOffset() + 1) * wordSize);
aoqi@1 3996 //FIXME,
aoqi@1 3997 // Clear floating point stack before returning to interpreter
aoqi@1 3998 __ empty_FPU_stack();
aoqi@1 3999 //FIXME, we should consider about float and double
aoqi@1 4000 // Push a float or double return value if necessary.
aoqi@1 4001 __ leave();
aoqi@1 4002
aoqi@1 4003 // Jump to interpreter
aoqi@1 4004 __ jr(RA);
aoqi@1 4005 __ delayed()->nop();
aoqi@1 4006
aoqi@1 4007 masm->flush();
aoqi@1 4008 _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
aoqi@1 4009 _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
aoqi@1 4010 }
aoqi@1 4011
aoqi@1 4012 #ifdef COMPILER2
aoqi@1 4013
aoqi@1 4014 //------------------------------generate_uncommon_trap_blob--------------------
aoqi@1 4015 // Ought to generate an ideal graph & compile, but here's some SPARC ASM
aoqi@1 4016 // instead.
aoqi@1 4017 void SharedRuntime::generate_uncommon_trap_blob() {
aoqi@1 4018 // allocate space for the code
aoqi@1 4019 ResourceMark rm;
aoqi@1 4020 // setup code generation tools
aoqi@1 4021 CodeBuffer buffer ("uncommon_trap_blob", 512*80 , 512*40 );
aoqi@1 4022 MacroAssembler* masm = new MacroAssembler(&buffer);
aoqi@1 4023
aoqi@1 4024 enum frame_layout {
aoqi@1 4025 s0_off, s0_off2,
aoqi@1 4026 s1_off, s1_off2,
aoqi@1 4027 s2_off, s2_off2,
aoqi@1 4028 s3_off, s3_off2,
aoqi@1 4029 s4_off, s4_off2,
aoqi@1 4030 s5_off, s5_off2,
aoqi@1 4031 s6_off, s6_off2,
aoqi@1 4032 s7_off, s7_off2,
aoqi@1 4033 fp_off, fp_off2,
aoqi@1 4034 return_off, return_off2, // slot for return address sp + 9
aoqi@1 4035 framesize
aoqi@1 4036 };
aoqi@1 4037 assert(framesize % 4 == 0, "sp not 16-byte aligned");
aoqi@1 4038
aoqi@1 4039 address start = __ pc();
aoqi@1 4040
aoqi@1 4041 // Push self-frame.
aoqi@1 4042 __ daddiu(SP, SP, -framesize * BytesPerInt);
aoqi@1 4043
aoqi@1 4044 __ sd(RA, SP, return_off * BytesPerInt);
aoqi@1 4045 __ sd(FP, SP, fp_off * BytesPerInt);
aoqi@1 4046
aoqi@1 4047 // Save callee saved registers. None for UseSSE=0,
aoqi@1 4048 // floats-only for UseSSE=1, and doubles for UseSSE=2.
aoqi@1 4049 __ sd(S0, SP, s0_off * BytesPerInt);
aoqi@1 4050 __ sd(S1, SP, s1_off * BytesPerInt);
aoqi@1 4051 __ sd(S2, SP, s2_off * BytesPerInt);
aoqi@1 4052 __ sd(S3, SP, s3_off * BytesPerInt);
aoqi@1 4053 __ sd(S4, SP, s4_off * BytesPerInt);
aoqi@1 4054 __ sd(S5, SP, s5_off * BytesPerInt);
aoqi@1 4055 __ sd(S6, SP, s6_off * BytesPerInt);
aoqi@1 4056 __ sd(S7, SP, s7_off * BytesPerInt);
aoqi@1 4057
aoqi@1 4058 __ daddi(FP, SP, fp_off * BytesPerInt);
aoqi@1 4059
aoqi@1 4060 // Clear the floating point exception stack
aoqi@1 4061 __ empty_FPU_stack();
aoqi@1 4062
aoqi@1 4063 Register thread = TREG;
aoqi@1 4064
aoqi@1 4065 #ifndef OPT_THREAD
aoqi@1 4066 __ get_thread(thread);
aoqi@1 4067 #endif
aoqi@1 4068 // set last_Java_sp
aoqi@1 4069 __ set_last_Java_frame(NOREG, FP, NULL);
aoqi@1 4070 __ relocate(relocInfo::internal_pc_type);
aoqi@1 4071 {
fujie@373 4072 long save_pc = (long)__ pc() + 52;
fujie@368 4073 __ patchable_set48(AT, (long)save_pc);
aoqi@1 4074 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@1 4075 }
aoqi@1 4076 // Call C code. Need thread but NOT official VM entry
aoqi@1 4077 // crud. We cannot block on this call, no GC can happen. Call should
aoqi@1 4078 // capture callee-saved registers as well as return values.
aoqi@1 4079 __ move(A0, thread);
aoqi@1 4080 // argument already in T0
aoqi@1 4081 __ move(A1, T0);
fujie@373 4082 __ patchable_set48(T9, (long)Deoptimization::uncommon_trap);
aoqi@1 4083 __ jalr(T9);
aoqi@1 4084 __ delayed()->nop();
aoqi@1 4085
aoqi@1 4086 // Set an oopmap for the call site
aoqi@1 4087 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 4088 OopMap* map = new OopMap( framesize, 0 );
aoqi@1 4089
aoqi@1 4090 map->set_callee_saved( VMRegImpl::stack2reg(s0_off ), S0->as_VMReg() );
aoqi@1 4091 map->set_callee_saved( VMRegImpl::stack2reg(s1_off ), S1->as_VMReg() );
aoqi@1 4092 map->set_callee_saved( VMRegImpl::stack2reg(s2_off ), S2->as_VMReg() );
aoqi@1 4093 map->set_callee_saved( VMRegImpl::stack2reg(s3_off ), S3->as_VMReg() );
aoqi@1 4094 map->set_callee_saved( VMRegImpl::stack2reg(s4_off ), S4->as_VMReg() );
aoqi@1 4095 map->set_callee_saved( VMRegImpl::stack2reg(s5_off ), S5->as_VMReg() );
aoqi@1 4096 map->set_callee_saved( VMRegImpl::stack2reg(s6_off ), S6->as_VMReg() );
aoqi@1 4097 map->set_callee_saved( VMRegImpl::stack2reg(s7_off ), S7->as_VMReg() );
aoqi@1 4098
aoqi@1 4099 //oop_maps->add_gc_map( __ offset(), true, map);
aoqi@1 4100 oop_maps->add_gc_map( __ offset(), map);
aoqi@1 4101
aoqi@1 4102 #ifndef OPT_THREAD
aoqi@1 4103 __ get_thread(thread);
aoqi@1 4104 #endif
aoqi@1 4105 __ reset_last_Java_frame(false,false);
aoqi@1 4106
aoqi@1 4107 // Load UnrollBlock into S7
aoqi@1 4108 Register unroll = S7;
aoqi@1 4109 __ move(unroll, V0);
aoqi@1 4110
aoqi@1 4111 // Pop all the frames we must move/replace.
aoqi@1 4112 //
aoqi@1 4113 // Frame picture (youngest to oldest)
aoqi@1 4114 // 1: self-frame (no frame link)
aoqi@1 4115 // 2: deopting frame (no frame link)
aoqi@1 4116 // 3: possible-i2c-adapter-frame
aoqi@1 4117 // 4: caller of deopting frame (could be compiled/interpreted. If interpreted we will create an
aoqi@1 4118 // and c2i here)
aoqi@1 4119
aoqi@1 4120 // Pop self-frame. We have no frame, and must rely only on EAX and ESP.
aoqi@1 4121 __ daddiu(SP, SP, framesize * BytesPerInt);
aoqi@1 4122
aoqi@1 4123 // Pop deoptimized frame
aoqi@1 4124 __ lw(AT, unroll, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes());
aoqi@1 4125 __ dadd(SP, SP, AT);
aoqi@1 4126
aoqi@1 4127 // register for frame pcs
aoqi@1 4128 Register pcs = T8;
aoqi@1 4129 // register for frame sizes
aoqi@1 4130 Register sizes = T9;
aoqi@1 4131 // register for frame count
aoqi@1 4132 Register count = T3;
aoqi@1 4133 // register for the sender's sp
aoqi@1 4134 Register sender_sp = T1;
aoqi@1 4135
aoqi@1 4136 // sp should be pointing at the return address to the caller (4)
aoqi@1 4137 // Load array of frame pcs into ECX
aoqi@1 4138 __ ld(pcs, unroll, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes());
aoqi@1 4139
aoqi@1 4140 /* 2012/9/7 Not needed in MIPS
aoqi@1 4141 __ addiu(SP, SP, wordSize);
aoqi@1 4142 */
aoqi@1 4143
aoqi@1 4144 // Load array of frame sizes into ESI
aoqi@1 4145 __ ld(sizes, unroll, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes());
aoqi@1 4146 __ lwu(count, unroll, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes());
aoqi@1 4147
aoqi@1 4148 // Pick up the initial fp we should save
aoqi@1 4149 __ ld(FP, unroll, Deoptimization::UnrollBlock::initial_info_offset_in_bytes());
aoqi@1 4150 // Now adjust the caller's stack to make up for the extra locals
aoqi@1 4151 // but record the original sp so that we can save it in the skeletal interpreter
aoqi@1 4152 // frame and the stack walking of interpreter_sender will get the unextended sp
aoqi@1 4153 // value and not the "real" sp value.
aoqi@1 4154
aoqi@1 4155 __ move(sender_sp, SP);
aoqi@1 4156 __ lw(AT, unroll, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes());
aoqi@1 4157 __ dsub(SP, SP, AT);
aoqi@1 4158 // Push interpreter frames in a loop
aoqi@1 4159 Label loop;
aoqi@1 4160 __ bind(loop);
aoqi@1 4161 __ ld(T2, sizes, 0); // Load frame size
aoqi@1 4162 __ ld(AT, pcs, 0); // save return address
aoqi@1 4163 __ daddi(T2, T2, -2*wordSize); // we'll push pc and rbp, by hand
aoqi@1 4164 __ push2(AT, FP);
aoqi@1 4165 __ move(FP, SP);
aoqi@1 4166 __ dsub(SP, SP, T2); // Prolog!
aoqi@1 4167 // This value is corrected by layout_activation_impl
aoqi@1 4168 __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize);
aoqi@1 4169 __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize);// Make it walkable
aoqi@1 4170 __ move(sender_sp, SP); // pass to next frame
aoqi@1 4171 __ daddi(count, count, -1); // decrement counter
aoqi@1 4172 __ daddi(sizes, sizes, wordSize); // Bump array pointer (sizes)
aoqi@1 4173 __ addi(pcs, pcs, wordSize); // Bump array pointer (pcs)
aoqi@1 4174 __ bne(count, R0, loop);
aoqi@1 4175 __ delayed()->nop(); // Bump array pointer (pcs)
aoqi@1 4176
aoqi@1 4177 __ ld(RA, pcs, 0);
aoqi@1 4178
aoqi@1 4179 // Re-push self-frame
aoqi@1 4180 __ daddi(SP, SP, - 2 * wordSize); // save old & set new FP
aoqi@1 4181 __ sd(FP, SP, 0 * wordSize); // save final return address
aoqi@1 4182 __ sd(RA, SP, 1 * wordSize);
aoqi@1 4183 __ move(FP, SP);
aoqi@1 4184 __ daddi(SP, SP, -(framesize / 2 - 2) * wordSize);
aoqi@1 4185
aoqi@1 4186 // set last_Java_sp, last_Java_fp
aoqi@1 4187 __ set_last_Java_frame(NOREG, FP, NULL);
aoqi@1 4188
aoqi@1 4189 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 4190 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI
aoqi@1 4191
aoqi@1 4192 __ relocate(relocInfo::internal_pc_type);
aoqi@1 4193 {
fujie@373 4194 long save_pc = (long)__ pc() + 52;
fujie@368 4195 __ patchable_set48(AT, (long)save_pc);
aoqi@1 4196 }
aoqi@1 4197 __ sd(AT, thread,in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@1 4198
aoqi@1 4199 // Call C code. Need thread but NOT official VM entry
aoqi@1 4200 // crud. We cannot block on this call, no GC can happen. Call should
aoqi@1 4201 // restore return values to their stack-slots with the new SP.
aoqi@1 4202 __ move(A0, thread);
aoqi@1 4203 __ move(A1, Deoptimization::Unpack_uncommon_trap);
fujie@373 4204 __ patchable_set48(T9, (long)Deoptimization::unpack_frames);
aoqi@1 4205 __ jalr(T9);
aoqi@1 4206 __ delayed()->nop();
aoqi@1 4207 // Set an oopmap for the call site
aoqi@1 4208 //oop_maps->add_gc_map( __ offset(), true, new OopMap( framesize, 0 ) );
aoqi@1 4209 oop_maps->add_gc_map( __ offset(), new OopMap( framesize, 0 ) );//Fu
aoqi@1 4210
aoqi@1 4211 __ reset_last_Java_frame(true,true);
aoqi@1 4212
aoqi@1 4213 // Pop self-frame.
aoqi@1 4214 __ leave(); // Epilog!
aoqi@1 4215
aoqi@1 4216 // Jump to interpreter
aoqi@1 4217 __ jr(RA);
aoqi@1 4218 __ delayed()->nop();
aoqi@1 4219 // -------------
aoqi@1 4220 // make sure all code is generated
aoqi@1 4221 masm->flush();
aoqi@1 4222
aoqi@1 4223 _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, oop_maps, framesize / 2);
aoqi@1 4224 }
aoqi@1 4225
aoqi@1 4226 #endif // COMPILER2
aoqi@1 4227
aoqi@1 4228 //------------------------------generate_handler_blob-------------------
aoqi@1 4229 //
aoqi@1 4230 // Generate a special Compile2Runtime blob that saves all registers, and sets
aoqi@1 4231 // up an OopMap and calls safepoint code to stop the compiled code for
aoqi@1 4232 // a safepoint.
aoqi@1 4233 //
aoqi@1 4234 // This blob is jumped to (via a breakpoint and the signal handler) from a
aoqi@1 4235 // safepoint in compiled code.
aoqi@1 4236
aoqi@1 4237 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int pool_type) {
aoqi@1 4238
aoqi@1 4239 // Account for thread arg in our frame
aoqi@1 4240 const int additional_words = 0;
aoqi@1 4241 int frame_size_in_words;
aoqi@1 4242
aoqi@1 4243 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
aoqi@1 4244
aoqi@1 4245 ResourceMark rm;
aoqi@1 4246 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 4247 OopMap* map;
aoqi@1 4248
aoqi@1 4249 // allocate space for the code
aoqi@1 4250 // setup code generation tools
aoqi@1 4251 CodeBuffer buffer ("handler_blob", 2048, 512);
aoqi@1 4252 MacroAssembler* masm = new MacroAssembler( &buffer);
aoqi@1 4253
aoqi@1 4254 const Register thread = TREG;
aoqi@1 4255 address start = __ pc();
aoqi@1 4256 address call_pc = NULL;
aoqi@1 4257 bool cause_return = (pool_type == POLL_AT_RETURN);
aoqi@1 4258 bool save_vectors = (pool_type == POLL_AT_VECTOR_LOOP);
aoqi@1 4259
aoqi@1 4260 // If cause_return is true we are at a poll_return and there is
aoqi@1 4261 // the return address in RA to the caller on the nmethod
aoqi@1 4262 // that is safepoint. We can leave this return in RA and
aoqi@1 4263 // effectively complete the return and safepoint in the caller.
aoqi@1 4264 // Otherwise we load exception pc to RA.
aoqi@1 4265 __ push(thread);
aoqi@1 4266 #ifndef OPT_THREAD
aoqi@1 4267 __ get_thread(thread);
aoqi@1 4268 #endif
aoqi@1 4269
aoqi@1 4270 if(!cause_return) {
aoqi@1 4271 __ ld_ptr(RA, Address(thread, JavaThread::saved_exception_pc_offset()));
aoqi@1 4272 }
aoqi@1 4273
aoqi@1 4274 __ pop(thread);
aoqi@1 4275 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, save_vectors);
aoqi@1 4276
aoqi@1 4277 #ifndef OPT_THREAD
aoqi@1 4278 __ get_thread(thread);
aoqi@1 4279 #endif
aoqi@1 4280 // The following is basically a call_VM. However, we need the precise
aoqi@1 4281 // address of the call in order to generate an oopmap. Hence, we do all the
aoqi@1 4282 // work outselvs.
aoqi@1 4283
aoqi@1 4284 __ move(A0, thread);
aoqi@1 4285 __ set_last_Java_frame(NOREG, NOREG, NULL);
aoqi@1 4286
aoqi@1 4287 //__ relocate(relocInfo::internal_pc_type);
aoqi@1 4288 if (!cause_return)
aoqi@1 4289 {
aoqi@1 4290 /*
aoqi@1 4291 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + NativeCall::return_address_offset + 4;
aoqi@1 4292 __ li48(AT, save_pc);
aoqi@1 4293 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@1 4294 */
aoqi@1 4295 }
aoqi@1 4296
aoqi@1 4297
aoqi@1 4298 // do the call
aoqi@1 4299 //__ lui(T9, Assembler::split_high((int)call_ptr));
aoqi@1 4300 //__ addiu(T9, T9, Assembler::split_low((int)call_ptr));
aoqi@1 4301 __ call(call_ptr);
aoqi@1 4302 __ delayed()->nop();
aoqi@1 4303
aoqi@1 4304 // Set an oopmap for the call site. This oopmap will map all
aoqi@1 4305 // oop-registers and debug-info registers as callee-saved. This
aoqi@1 4306 // will allow deoptimization at this safepoint to find all possible
aoqi@1 4307 // debug-info recordings, as well as let GC find all oops.
aoqi@1 4308 oop_maps->add_gc_map(__ offset(), map);
aoqi@1 4309
aoqi@1 4310 Label noException;
aoqi@1 4311
aoqi@1 4312 // Clear last_Java_sp again
aoqi@1 4313 __ reset_last_Java_frame(false, false);
aoqi@1 4314
aoqi@1 4315 __ ld_ptr(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 4316 __ beq(AT, R0, noException);
aoqi@1 4317 __ delayed()->nop();
aoqi@1 4318
aoqi@1 4319 // Exception pending
aoqi@1 4320
aoqi@1 4321 RegisterSaver::restore_live_registers(masm, save_vectors);
aoqi@1 4322 //forward_exception_entry need return address on the stack
aoqi@1 4323 __ push(RA);
aoqi@1 4324 //__ lui(T9, Assembler::split_high((int)StubRoutines::forward_exception_entry()));
aoqi@1 4325 //__ addiu(T9, T9, Assembler::split_low((int)StubRoutines::forward_exception_entry()));
aoqi@1 4326 __ li(T9, StubRoutines::forward_exception_entry());
aoqi@1 4327 __ jr(T9);
aoqi@1 4328 __ delayed()->nop();
aoqi@1 4329
aoqi@1 4330 // No exception case
aoqi@1 4331 __ bind(noException);
aoqi@1 4332 // Normal exit, register restoring and exit
aoqi@1 4333 RegisterSaver::restore_live_registers(masm, save_vectors);
aoqi@1 4334 __ jr(RA);
aoqi@1 4335 __ delayed()->nop();
aoqi@1 4336
aoqi@1 4337 masm->flush();
aoqi@1 4338
aoqi@1 4339 // Fill-out other meta info
aoqi@1 4340 return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words);
aoqi@1 4341 }
aoqi@1 4342
aoqi@1 4343 //
aoqi@1 4344 // generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss
aoqi@1 4345 //
aoqi@1 4346 // Generate a stub that calls into vm to find out the proper destination
aoqi@1 4347 // of a java call. All the argument registers are live at this point
aoqi@1 4348 // but since this is generic code we don't know what they are and the caller
aoqi@1 4349 // must do any gc of the args.
aoqi@1 4350 //
aoqi@1 4351 RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) {
aoqi@1 4352 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
aoqi@1 4353
aoqi@1 4354 // allocate space for the code
aoqi@1 4355 ResourceMark rm;
aoqi@1 4356
aoqi@1 4357 //CodeBuffer buffer(name, 1000, 512);
aoqi@1 4358 //FIXME. aoqi. code_size
aoqi@1 4359 CodeBuffer buffer(name, 20000, 2048);
aoqi@1 4360 MacroAssembler* masm = new MacroAssembler(&buffer);
aoqi@1 4361
aoqi@1 4362 int frame_size_words;
aoqi@1 4363 //we put the thread in A0
aoqi@1 4364
aoqi@1 4365 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 4366 OopMap* map = NULL;
aoqi@1 4367
aoqi@1 4368 int start = __ offset();
aoqi@1 4369 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
aoqi@1 4370
aoqi@1 4371
aoqi@1 4372 int frame_complete = __ offset();
aoqi@1 4373
aoqi@1 4374 const Register thread = T8;
aoqi@1 4375 __ get_thread(thread);
aoqi@1 4376
aoqi@1 4377 __ move(A0, thread);
aoqi@1 4378 __ set_last_Java_frame(noreg, FP, NULL);
aoqi@1 4379 //__ addi(SP, SP, -wordSize);
aoqi@1 4380 //align the stack before invoke native
aoqi@1 4381 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 4382 __ andr(SP, SP, AT);
aoqi@1 4383 __ relocate(relocInfo::internal_pc_type);
aoqi@1 4384 {
fujie@373 4385 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 24 + 1 * BytesPerInstWord;
aoqi@1 4386 //tty->print_cr(" %s :%d, name:%s, pc: %lx, save_pc: %lx, frame_size_words: %lx", __func__, __LINE__, name, __ pc(), save_pc, frame_size_words); //aoqi_test
fujie@368 4387 __ patchable_set48(AT, save_pc);
aoqi@1 4388 }
aoqi@1 4389 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@1 4390
aoqi@1 4391 __ call(destination);
aoqi@1 4392 __ delayed()->nop();
aoqi@1 4393
aoqi@1 4394 // Set an oopmap for the call site.
aoqi@1 4395 // We need this not only for callee-saved registers, but also for volatile
aoqi@1 4396 // registers that the compiler might be keeping live across a safepoint.
aoqi@1 4397 oop_maps->add_gc_map( __ offset() - start, map);
aoqi@1 4398 // V0 contains the address we are going to jump to assuming no exception got installed
aoqi@1 4399 __ get_thread(thread);
aoqi@1 4400 __ ld_ptr(SP, thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@1 4401 // clear last_Java_sp
aoqi@1 4402 __ reset_last_Java_frame(true, true);
aoqi@1 4403 // check for pending exceptions
aoqi@1 4404 Label pending;
aoqi@1 4405 __ ld_ptr(AT, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 4406 __ bne(AT, R0, pending);
aoqi@1 4407 __ delayed()->nop();
aoqi@1 4408 // get the returned Method*
aoqi@1 4409 //FIXME, do mips need this ?
aoqi@1 4410 __ get_vm_result_2(Rmethod, thread); // Refer to OpenJDK8
aoqi@1 4411 __ st_ptr(Rmethod, SP, RegisterSaver::methodOffset() * wordSize);
aoqi@1 4412 __ st_ptr(V0, SP, RegisterSaver::v0Offset() * wordSize);
aoqi@1 4413 RegisterSaver::restore_live_registers(masm);
aoqi@1 4414
aoqi@1 4415 // We are back the the original state on entry and ready to go the callee method.
aoqi@1 4416 __ jr(V0);
aoqi@1 4417 __ delayed()->nop();
aoqi@1 4418 // Pending exception after the safepoint
aoqi@1 4419
aoqi@1 4420 __ bind(pending);
aoqi@1 4421
aoqi@1 4422 RegisterSaver::restore_live_registers(masm);
aoqi@1 4423
aoqi@1 4424 // exception pending => remove activation and forward to exception handler
aoqi@1 4425 //forward_exception_entry need return address on the stack
aoqi@1 4426 __ push(RA);
aoqi@1 4427 __ get_thread(thread);
aoqi@1 4428 __ st_ptr(R0, thread, in_bytes(JavaThread::vm_result_offset()));
aoqi@1 4429 __ ld_ptr(V0, thread, in_bytes(Thread::pending_exception_offset()));
aoqi@1 4430 __ jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
aoqi@1 4431 __ delayed() -> nop();
aoqi@1 4432 // -------------
aoqi@1 4433 // make sure all code is generated
aoqi@1 4434 masm->flush();
aoqi@1 4435
aoqi@1 4436 RuntimeStub* tmp= RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true);
aoqi@1 4437 return tmp;
aoqi@1 4438 }
aoqi@1 4439
aoqi@1 4440 /*void SharedRuntime::generate_stubs() {
aoqi@1 4441 _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4442 SharedRuntime::handle_wrong_method),"wrong_method_stub");
aoqi@1 4443 _ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4444 SharedRuntime::handle_wrong_method_ic_miss),"ic_miss_stub");
aoqi@1 4445 _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4446 SharedRuntime::resolve_opt_virtual_call_C),"resolve_opt_virtual_call");
aoqi@1 4447 _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4448 SharedRuntime::resolve_virtual_call_C),"resolve_virtual_call");
aoqi@1 4449 _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4450 SharedRuntime::resolve_static_call_C),"resolve_static_call");
aoqi@1 4451 _polling_page_safepoint_handler_blob =generate_handler_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4452 SafepointSynchronize::handle_polling_page_exception), false);
aoqi@1 4453 _polling_page_return_handler_blob =generate_handler_blob(CAST_FROM_FN_PTR(address,
aoqi@1 4454 SafepointSynchronize::handle_polling_page_exception), true);
aoqi@1 4455 generate_deopt_blob();
aoqi@1 4456 #ifdef COMPILER2
aoqi@1 4457 generate_uncommon_trap_blob();
aoqi@1 4458 #endif // COMPILER2
aoqi@1 4459 }*/
aoqi@1 4460
aoqi@1 4461 extern "C" int SpinPause() {return 0;}
aoqi@1 4462 // extern "C" int SafeFetch32 (int * adr, int errValue) {return 0;} ;
aoqi@1 4463 // extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) {return *adr; } ;

mercurial