src/cpu/mips/vm/macroAssembler_mips.cpp

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 10026
8c95980d0b66
parent 9932
86ea9a02a717
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset d3b4d62f391f

aoqi@6880 1 /*
aoqi@6880 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@9808 3 * Copyright (c) 2017, 2020, Loongson Technology. All rights reserved.
aoqi@6880 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@6880 5 *
aoqi@6880 6 * This code is free software; you can redistribute it and/or modify it
aoqi@6880 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@6880 8 * published by the Free Software Foundation.
aoqi@6880 9 *
aoqi@6880 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@6880 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@6880 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@6880 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@6880 14 * accompanied this code).
aoqi@6880 15 *
aoqi@6880 16 * You should have received a copy of the GNU General Public License version
aoqi@6880 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@6880 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@6880 19 *
aoqi@6880 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@6880 21 * or visit www.oracle.com if you need additional information or have any
aoqi@6880 22 * questions.
aoqi@6880 23 *
aoqi@6880 24 */
aoqi@6880 25
aoqi@6880 26 #include "precompiled.hpp"
aoqi@6880 27 #include "asm/assembler.hpp"
aoqi@6880 28 #include "asm/assembler.inline.hpp"
aoqi@6880 29 #include "asm/macroAssembler.inline.hpp"
aoqi@6880 30 #include "compiler/disassembler.hpp"
aoqi@6880 31 #include "gc_interface/collectedHeap.inline.hpp"
aoqi@6880 32 #include "interpreter/interpreter.hpp"
aoqi@6880 33 #include "memory/cardTableModRefBS.hpp"
aoqi@6880 34 #include "memory/resourceArea.hpp"
aoqi@6880 35 #include "memory/universe.hpp"
aoqi@6880 36 #include "prims/methodHandles.hpp"
aoqi@6880 37 #include "runtime/biasedLocking.hpp"
aoqi@6880 38 #include "runtime/interfaceSupport.hpp"
aoqi@6880 39 #include "runtime/objectMonitor.hpp"
aoqi@6880 40 #include "runtime/os.hpp"
aoqi@6880 41 #include "runtime/sharedRuntime.hpp"
aoqi@6880 42 #include "runtime/stubRoutines.hpp"
aoqi@6880 43 #include "utilities/macros.hpp"
aoqi@6880 44 #if INCLUDE_ALL_GCS
aoqi@6880 45 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
aoqi@6880 46 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
aoqi@6880 47 #include "gc_implementation/g1/heapRegion.hpp"
aoqi@6880 48 #endif // INCLUDE_ALL_GCS
aoqi@6880 49
aoqi@9932 50 #define A0 RA0
aoqi@9932 51 #define A1 RA1
aoqi@9932 52 #define A2 RA2
aoqi@9932 53 #define A3 RA3
aoqi@9932 54 #define A4 RA4
aoqi@9932 55 #define A5 RA5
aoqi@9932 56 #define A6 RA6
aoqi@9932 57 #define A7 RA7
aoqi@9932 58 #define T0 RT0
aoqi@9932 59 #define T1 RT1
aoqi@9932 60 #define T2 RT2
aoqi@9932 61 #define T3 RT3
aoqi@9932 62 #define T8 RT8
aoqi@9932 63 #define T9 RT9
aoqi@9932 64
aoqi@6880 65 // Implementation of MacroAssembler
aoqi@6880 66
aoqi@6880 67 intptr_t MacroAssembler::i[32] = {0};
aoqi@6880 68 float MacroAssembler::f[32] = {0.0};
aoqi@6880 69
aoqi@6880 70 void MacroAssembler::print(outputStream *s) {
aoqi@6880 71 unsigned int k;
aoqi@6880 72 for(k=0; k<sizeof(i)/sizeof(i[0]); k++) {
aoqi@6880 73 s->print_cr("i%d = 0x%.16lx", k, i[k]);
aoqi@6880 74 }
aoqi@6880 75 s->cr();
aoqi@6880 76
aoqi@6880 77 for(k=0; k<sizeof(f)/sizeof(f[0]); k++) {
aoqi@6880 78 s->print_cr("f%d = %f", k, f[k]);
aoqi@6880 79 }
aoqi@6880 80 s->cr();
aoqi@6880 81 }
aoqi@6880 82
aoqi@6880 83 int MacroAssembler::i_offset(unsigned int k) { return (intptr_t)&((MacroAssembler*)0)->i[k]; }
aoqi@6880 84 int MacroAssembler::f_offset(unsigned int k) { return (intptr_t)&((MacroAssembler*)0)->f[k]; }
aoqi@6880 85
aoqi@6880 86 void MacroAssembler::save_registers(MacroAssembler *masm) {
aoqi@6880 87 #define __ masm->
aoqi@6880 88 for(int k=0; k<32; k++) {
aoqi@6880 89 __ sw (as_Register(k), A0, i_offset(k));
aoqi@6880 90 }
aoqi@6880 91
aoqi@6880 92 for(int k=0; k<32; k++) {
aoqi@6880 93 __ swc1 (as_FloatRegister(k), A0, f_offset(k));
aoqi@6880 94 }
aoqi@6880 95 #undef __
aoqi@6880 96 }
aoqi@6880 97
aoqi@6880 98 void MacroAssembler::restore_registers(MacroAssembler *masm) {
aoqi@6880 99 #define __ masm->
aoqi@6880 100 for(int k=0; k<32; k++) {
aoqi@6880 101 __ lw (as_Register(k), A0, i_offset(k));
aoqi@6880 102 }
aoqi@6880 103
aoqi@6880 104 for(int k=0; k<32; k++) {
aoqi@6880 105 __ lwc1 (as_FloatRegister(k), A0, f_offset(k));
aoqi@6880 106 }
aoqi@6880 107 #undef __
aoqi@6880 108 }
aoqi@6880 109
aoqi@6880 110
aoqi@6880 111 void MacroAssembler::pd_patch_instruction(address branch, address target) {
aoqi@6880 112 jint& stub_inst = *(jint*) branch;
aoqi@8862 113 jint *pc = (jint *)branch;
aoqi@6880 114
aoqi@8862 115 if((opcode(stub_inst) == special_op) && (special(stub_inst) == dadd_op)) {
aoqi@9136 116 //b_far:
aoqi@9136 117 // move(AT, RA); // dadd
aoqi@9136 118 // emit_long(insn_ORRI(regimm_op, 0, bgezal_op, 1));
aoqi@9136 119 // nop();
aoqi@9136 120 // lui(T9, 0); // to be patched
aoqi@9136 121 // ori(T9, 0);
aoqi@9136 122 // daddu(T9, T9, RA);
aoqi@9136 123 // move(RA, AT);
aoqi@9136 124 // jr(T9);
aoqi@6880 125
aoqi@6880 126 assert(opcode(pc[3]) == lui_op
aoqi@9136 127 && opcode(pc[4]) == ori_op
aoqi@9136 128 && special(pc[5]) == daddu_op, "Not a branch label patch");
aoqi@6880 129 if(!(opcode(pc[3]) == lui_op
aoqi@6880 130 && opcode(pc[4]) == ori_op
aoqi@6880 131 && special(pc[5]) == daddu_op)) { tty->print_cr("Not a branch label patch"); }
aoqi@6880 132
aoqi@6880 133 int offset = target - branch;
aoqi@8009 134 if (!is_simm16(offset)) {
aoqi@6880 135 pc[3] = (pc[3] & 0xffff0000) | high16(offset - 12);
aoqi@6880 136 pc[4] = (pc[4] & 0xffff0000) | low16(offset - 12);
aoqi@8009 137 } else {
aoqi@9459 138 // revert to "beq + nop"
aoqi@6880 139 CodeBuffer cb(branch, 4 * 10);
aoqi@6880 140 MacroAssembler masm(&cb);
aoqi@6880 141 #define __ masm.
aoqi@6880 142 __ b(target);
zhaixiang@9144 143 __ delayed()->nop();
aoqi@6880 144 __ nop();
aoqi@6880 145 __ nop();
aoqi@6880 146 __ nop();
aoqi@6880 147 __ nop();
aoqi@6880 148 __ nop();
aoqi@6880 149 __ nop();
aoqi@6880 150 }
aoqi@6880 151 return;
aoqi@8862 152 } else if (special(pc[4]) == jr_op
aoqi@8862 153 && opcode(pc[4]) == special_op
aoqi@8862 154 && (((opcode(pc[0]) == lui_op) || opcode(pc[0]) == daddiu_op) || (opcode(pc[0]) == ori_op))) {
aoqi@9136 155 //jmp_far:
aoqi@9136 156 // patchable_set48(T9, target);
aoqi@9136 157 // jr(T9);
aoqi@9136 158 // nop();
aoqi@8867 159
aoqi@8862 160 CodeBuffer cb(branch, 4 * 4);
aoqi@8862 161 MacroAssembler masm(&cb);
aoqi@8862 162 masm.patchable_set48(T9, (long)(target));
aoqi@8862 163 return;
aoqi@6880 164 }
aoqi@6880 165
aoqi@6880 166 #ifndef PRODUCT
aoqi@8009 167 if (!is_simm16((target - branch - 4) >> 2)) {
fujie@9159 168 tty->print_cr("Illegal patching: branch = 0x%lx, target = 0x%lx", branch, target);
fujie@9159 169 tty->print_cr("======= Start decoding at branch = 0x%lx =======", branch);
fujie@9159 170 Disassembler::decode(branch - 4 * 16, branch + 4 * 16, tty);
fujie@9159 171 tty->print_cr("======= End of decoding =======");
aoqi@6880 172 }
aoqi@6880 173 #endif
aoqi@6880 174
aoqi@6880 175 stub_inst = patched_branch(target - branch, stub_inst, 0);
aoqi@6880 176 }
aoqi@6880 177
aoqi@6880 178 static inline address first_cache_address() {
aoqi@6880 179 return CodeCache::low_bound() + sizeof(HeapBlock::Header);
aoqi@6880 180 }
aoqi@6880 181
aoqi@6880 182 static inline address last_cache_address() {
aoqi@6880 183 return CodeCache::high_bound() - Assembler::InstructionSize;
aoqi@6880 184 }
aoqi@6880 185
aoqi@6880 186 int MacroAssembler::call_size(address target, bool far, bool patchable) {
aoqi@6880 187 if (patchable) return 6 << Assembler::LogInstructionSize;
aoqi@6880 188 if (!far) return 2 << Assembler::LogInstructionSize; // jal + nop
aoqi@6880 189 return (insts_for_set64((jlong)target) + 2) << Assembler::LogInstructionSize;
aoqi@6880 190 }
aoqi@6880 191
aoqi@6880 192 // Can we reach target using jal/j from anywhere
aoqi@6880 193 // in the code cache (because code can be relocated)?
aoqi@6880 194 bool MacroAssembler::reachable_from_cache(address target) {
aoqi@6880 195 address cl = first_cache_address();
aoqi@6880 196 address ch = last_cache_address();
aoqi@6880 197
fujie@9168 198 return (cl <= target) && (target <= ch) && fit_in_jal(cl, ch);
aoqi@6880 199 }
aoqi@6880 200
aoqi@6880 201 void MacroAssembler::general_jump(address target) {
aoqi@6880 202 if (reachable_from_cache(target)) {
aoqi@6880 203 j(target);
zhaixiang@9144 204 delayed()->nop();
aoqi@6880 205 } else {
aoqi@6880 206 set64(T9, (long)target);
aoqi@6880 207 jr(T9);
zhaixiang@9144 208 delayed()->nop();
aoqi@6880 209 }
aoqi@6880 210 }
aoqi@6880 211
aoqi@6880 212 int MacroAssembler::insts_for_general_jump(address target) {
aoqi@6880 213 if (reachable_from_cache(target)) {
aoqi@6880 214 //j(target);
aoqi@6880 215 //nop();
aoqi@6880 216 return 2;
aoqi@6880 217 } else {
aoqi@6880 218 //set64(T9, (long)target);
aoqi@6880 219 //jr(T9);
aoqi@6880 220 //nop();
aoqi@6880 221 return insts_for_set64((jlong)target) + 2;
aoqi@6880 222 }
aoqi@6880 223 }
aoqi@6880 224
aoqi@6880 225 void MacroAssembler::patchable_jump(address target) {
aoqi@6880 226 if (reachable_from_cache(target)) {
aoqi@6880 227 nop();
aoqi@6880 228 nop();
aoqi@6880 229 nop();
aoqi@6880 230 nop();
aoqi@6880 231 j(target);
zhaixiang@9144 232 delayed()->nop();
aoqi@6880 233 } else {
aoqi@6880 234 patchable_set48(T9, (long)target);
aoqi@6880 235 jr(T9);
zhaixiang@9144 236 delayed()->nop();
aoqi@6880 237 }
aoqi@6880 238 }
aoqi@6880 239
aoqi@6880 240 int MacroAssembler::insts_for_patchable_jump(address target) {
aoqi@6880 241 return 6;
aoqi@6880 242 }
aoqi@6880 243
aoqi@6880 244 void MacroAssembler::general_call(address target) {
aoqi@6880 245 if (reachable_from_cache(target)) {
aoqi@6880 246 jal(target);
zhaixiang@9144 247 delayed()->nop();
aoqi@6880 248 } else {
aoqi@6880 249 set64(T9, (long)target);
aoqi@6880 250 jalr(T9);
zhaixiang@9144 251 delayed()->nop();
aoqi@6880 252 }
aoqi@6880 253 }
aoqi@6880 254
aoqi@6880 255 int MacroAssembler::insts_for_general_call(address target) {
aoqi@6880 256 if (reachable_from_cache(target)) {
aoqi@6880 257 //jal(target);
aoqi@6880 258 //nop();
aoqi@6880 259 return 2;
aoqi@6880 260 } else {
aoqi@6880 261 //set64(T9, (long)target);
aoqi@6880 262 //jalr(T9);
aoqi@6880 263 //nop();
aoqi@6880 264 return insts_for_set64((jlong)target) + 2;
aoqi@6880 265 }
aoqi@6880 266 }
aoqi@6880 267
aoqi@6880 268 void MacroAssembler::patchable_call(address target) {
aoqi@6880 269 if (reachable_from_cache(target)) {
aoqi@6880 270 nop();
aoqi@6880 271 nop();
aoqi@6880 272 nop();
aoqi@6880 273 nop();
aoqi@6880 274 jal(target);
zhaixiang@9144 275 delayed()->nop();
aoqi@6880 276 } else {
aoqi@6880 277 patchable_set48(T9, (long)target);
aoqi@6880 278 jalr(T9);
zhaixiang@9144 279 delayed()->nop();
aoqi@6880 280 }
aoqi@6880 281 }
aoqi@6880 282
aoqi@6880 283 int MacroAssembler::insts_for_patchable_call(address target) {
aoqi@6880 284 return 6;
aoqi@6880 285 }
aoqi@6880 286
aoqi@8009 287 void MacroAssembler::beq_far(Register rs, Register rt, address entry) {
aoqi@6880 288 u_char * cur_pc = pc();
aoqi@6880 289
aoqi@9228 290 // Near/Far jump
aoqi@8009 291 if(is_simm16((entry - pc() - 4) / 4)) {
aoqi@6880 292 Assembler::beq(rs, rt, offset(entry));
aoqi@8009 293 } else {
aoqi@6880 294 Label not_jump;
aoqi@6880 295 bne(rs, rt, not_jump);
aoqi@6880 296 delayed()->nop();
aoqi@6880 297
aoqi@6880 298 b_far(entry);
aoqi@6880 299 delayed()->nop();
aoqi@6880 300
aoqi@6880 301 bind(not_jump);
aoqi@6880 302 has_delay_slot();
aoqi@6880 303 }
aoqi@6880 304 }
aoqi@6880 305
aoqi@8009 306 void MacroAssembler::beq_far(Register rs, Register rt, Label& L) {
aoqi@6880 307 if (L.is_bound()) {
aoqi@6880 308 beq_far(rs, rt, target(L));
aoqi@6880 309 } else {
aoqi@6880 310 u_char * cur_pc = pc();
aoqi@6880 311 Label not_jump;
aoqi@6880 312 bne(rs, rt, not_jump);
aoqi@6880 313 delayed()->nop();
aoqi@6880 314
aoqi@6880 315 b_far(L);
aoqi@6880 316 delayed()->nop();
aoqi@6880 317
aoqi@6880 318 bind(not_jump);
aoqi@6880 319 has_delay_slot();
aoqi@6880 320 }
aoqi@6880 321 }
aoqi@6880 322
aoqi@8009 323 void MacroAssembler::bne_far(Register rs, Register rt, address entry) {
aoqi@6880 324 u_char * cur_pc = pc();
aoqi@6880 325
aoqi@9228 326 //Near/Far jump
aoqi@8009 327 if(is_simm16((entry - pc() - 4) / 4)) {
aoqi@6880 328 Assembler::bne(rs, rt, offset(entry));
aoqi@8009 329 } else {
aoqi@6880 330 Label not_jump;
aoqi@6880 331 beq(rs, rt, not_jump);
aoqi@6880 332 delayed()->nop();
aoqi@6880 333
aoqi@6880 334 b_far(entry);
aoqi@6880 335 delayed()->nop();
aoqi@6880 336
aoqi@6880 337 bind(not_jump);
aoqi@6880 338 has_delay_slot();
aoqi@6880 339 }
aoqi@6880 340 }
aoqi@6880 341
aoqi@8009 342 void MacroAssembler::bne_far(Register rs, Register rt, Label& L) {
aoqi@6880 343 if (L.is_bound()) {
aoqi@6880 344 bne_far(rs, rt, target(L));
aoqi@6880 345 } else {
aoqi@6880 346 u_char * cur_pc = pc();
aoqi@6880 347 Label not_jump;
aoqi@6880 348 beq(rs, rt, not_jump);
aoqi@6880 349 delayed()->nop();
aoqi@6880 350
aoqi@6880 351 b_far(L);
aoqi@6880 352 delayed()->nop();
aoqi@6880 353
aoqi@6880 354 bind(not_jump);
aoqi@6880 355 has_delay_slot();
aoqi@6880 356 }
aoqi@6880 357 }
aoqi@6880 358
aoqi@8862 359 void MacroAssembler::beq_long(Register rs, Register rt, Label& L) {
aoqi@8862 360 Label not_taken;
aoqi@8862 361
aoqi@8862 362 bne(rs, rt, not_taken);
zhaixiang@9144 363 delayed()->nop();
aoqi@8862 364
aoqi@8862 365 jmp_far(L);
aoqi@8862 366
aoqi@8862 367 bind(not_taken);
aoqi@8862 368 }
aoqi@8862 369
aoqi@8862 370 void MacroAssembler::bne_long(Register rs, Register rt, Label& L) {
aoqi@8862 371 Label not_taken;
aoqi@8862 372
aoqi@8862 373 beq(rs, rt, not_taken);
zhaixiang@9144 374 delayed()->nop();
aoqi@8862 375
aoqi@8862 376 jmp_far(L);
aoqi@8862 377
aoqi@8862 378 bind(not_taken);
aoqi@8862 379 }
aoqi@8862 380
aoqi@8862 381 void MacroAssembler::bc1t_long(Label& L) {
aoqi@8862 382 Label not_taken;
aoqi@8862 383
aoqi@8862 384 bc1f(not_taken);
zhaixiang@9144 385 delayed()->nop();
aoqi@8862 386
aoqi@8862 387 jmp_far(L);
aoqi@8862 388
aoqi@8862 389 bind(not_taken);
aoqi@8862 390 }
aoqi@8862 391
aoqi@8862 392 void MacroAssembler::bc1f_long(Label& L) {
aoqi@8862 393 Label not_taken;
aoqi@8862 394
aoqi@8862 395 bc1t(not_taken);
zhaixiang@9144 396 delayed()->nop();
aoqi@8862 397
aoqi@8862 398 jmp_far(L);
aoqi@8862 399
aoqi@8862 400 bind(not_taken);
aoqi@8862 401 }
aoqi@8862 402
aoqi@8009 403 void MacroAssembler::b_far(Label& L) {
aoqi@6880 404 if (L.is_bound()) {
aoqi@6880 405 b_far(target(L));
aoqi@6880 406 } else {
aoqi@8009 407 volatile address dest = target(L);
aoqi@9459 408 //
aoqi@9459 409 // MacroAssembler::pd_patch_instruction branch=55651ed514, target=55651ef6d8
aoqi@9459 410 // 0x00000055651ed514: dadd at, ra, zero
aoqi@9459 411 // 0x00000055651ed518: [4110001]bgezal zero, 0x00000055651ed520
aoqi@9459 412 //
aoqi@9459 413 // 0x00000055651ed51c: sll zero, zero, 0
aoqi@9459 414 // 0x00000055651ed520: lui t9, 0x0
aoqi@9459 415 // 0x00000055651ed524: ori t9, t9, 0x21b8
aoqi@9459 416 // 0x00000055651ed528: daddu t9, t9, ra
aoqi@9459 417 // 0x00000055651ed52c: dadd ra, at, zero
aoqi@9459 418 // 0x00000055651ed530: jr t9
aoqi@9459 419 // 0x00000055651ed534: sll zero, zero, 0
aoqi@9459 420 //
aoqi@8009 421 move(AT, RA);
aoqi@8009 422 emit_long(insn_ORRI(regimm_op, 0, bgezal_op, 1));
aoqi@8009 423 nop();
aoqi@8009 424 lui(T9, 0); // to be patched
aoqi@8009 425 ori(T9, T9, 0);
aoqi@8009 426 daddu(T9, T9, RA);
aoqi@8009 427 move(RA, AT);
aoqi@8009 428 jr(T9);
aoqi@6880 429 }
aoqi@6880 430 }
aoqi@6880 431
aoqi@8009 432 void MacroAssembler::b_far(address entry) {
aoqi@6880 433 u_char * cur_pc = pc();
aoqi@6880 434
aoqi@9228 435 // Near/Far jump
aoqi@8009 436 if(is_simm16((entry - pc() - 4) / 4)) {
aoqi@6880 437 b(offset(entry));
aoqi@8009 438 } else {
aoqi@9228 439 // address must be bounded
aoqi@6880 440 move(AT, RA);
aoqi@8009 441 emit_long(insn_ORRI(regimm_op, 0, bgezal_op, 1));
aoqi@6880 442 nop();
aoqi@6880 443 li32(T9, entry - pc());
aoqi@6880 444 daddu(T9, T9, RA);
aoqi@6880 445 move(RA, AT);
aoqi@6880 446 jr(T9);
aoqi@6880 447 }
aoqi@6880 448 }
aoqi@6880 449
aoqi@6880 450 void MacroAssembler::ld_ptr(Register rt, Register offset, Register base) {
aoqi@6880 451 addu_long(AT, base, offset);
aoqi@6880 452 ld_ptr(rt, 0, AT);
aoqi@6880 453 }
aoqi@6880 454
aoqi@6880 455 void MacroAssembler::st_ptr(Register rt, Register offset, Register base) {
aoqi@6880 456 addu_long(AT, base, offset);
aoqi@6880 457 st_ptr(rt, 0, AT);
aoqi@6880 458 }
aoqi@6880 459
aoqi@6880 460 void MacroAssembler::ld_long(Register rt, Register offset, Register base) {
aoqi@6880 461 addu_long(AT, base, offset);
aoqi@6880 462 ld_long(rt, 0, AT);
aoqi@6880 463 }
aoqi@6880 464
aoqi@6880 465 void MacroAssembler::st_long(Register rt, Register offset, Register base) {
aoqi@6880 466 addu_long(AT, base, offset);
aoqi@6880 467 st_long(rt, 0, AT);
aoqi@6880 468 }
aoqi@6880 469
aoqi@6880 470 Address MacroAssembler::as_Address(AddressLiteral adr) {
aoqi@6880 471 return Address(adr.target(), adr.rspec());
aoqi@6880 472 }
aoqi@6880 473
aoqi@6880 474 Address MacroAssembler::as_Address(ArrayAddress adr) {
aoqi@6880 475 return Address::make_array(adr);
aoqi@6880 476 }
aoqi@6880 477
aoqi@6880 478 // tmp_reg1 and tmp_reg2 should be saved outside of atomic_inc32 (caller saved).
aoqi@6880 479 void MacroAssembler::atomic_inc32(address counter_addr, int inc, Register tmp_reg1, Register tmp_reg2) {
aoqi@6880 480 Label again;
aoqi@6880 481
aoqi@6880 482 li(tmp_reg1, counter_addr);
aoqi@6880 483 bind(again);
aoqi@9808 484 if (UseSyncLevel >= 10000 || UseSyncLevel == 1000 || UseSyncLevel == 4000) sync();
aoqi@6880 485 ll(tmp_reg2, tmp_reg1, 0);
aoqi@6880 486 addi(tmp_reg2, tmp_reg2, inc);
aoqi@6880 487 sc(tmp_reg2, tmp_reg1, 0);
aoqi@6880 488 beq(tmp_reg2, R0, again);
aoqi@6880 489 delayed()->nop();
aoqi@6880 490 }
aoqi@6880 491
aoqi@6880 492 int MacroAssembler::biased_locking_enter(Register lock_reg,
aoqi@6880 493 Register obj_reg,
aoqi@6880 494 Register swap_reg,
aoqi@6880 495 Register tmp_reg,
aoqi@6880 496 bool swap_reg_contains_mark,
aoqi@6880 497 Label& done,
aoqi@6880 498 Label* slow_case,
aoqi@6880 499 BiasedLockingCounters* counters) {
aoqi@6880 500 assert(UseBiasedLocking, "why call this otherwise?");
aoqi@6880 501 bool need_tmp_reg = false;
aoqi@6880 502 if (tmp_reg == noreg) {
aoqi@6880 503 need_tmp_reg = true;
aoqi@6880 504 tmp_reg = T9;
aoqi@6880 505 }
aoqi@6880 506 assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg, AT);
aoqi@6880 507 assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
aoqi@6880 508 Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes());
aoqi@6880 509 Address saved_mark_addr(lock_reg, 0);
aoqi@6880 510
aoqi@6880 511 // Biased locking
aoqi@6880 512 // See whether the lock is currently biased toward our thread and
aoqi@6880 513 // whether the epoch is still valid
aoqi@6880 514 // Note that the runtime guarantees sufficient alignment of JavaThread
aoqi@6880 515 // pointers to allow age to be placed into low bits
aoqi@6880 516 // First check to see whether biasing is even enabled for this object
aoqi@6880 517 Label cas_label;
aoqi@6880 518 int null_check_offset = -1;
aoqi@6880 519 if (!swap_reg_contains_mark) {
aoqi@6880 520 null_check_offset = offset();
aoqi@6880 521 ld_ptr(swap_reg, mark_addr);
aoqi@6880 522 }
aoqi@6880 523
aoqi@6880 524 if (need_tmp_reg) {
aoqi@6880 525 push(tmp_reg);
aoqi@6880 526 }
aoqi@6880 527 move(tmp_reg, swap_reg);
aoqi@6880 528 andi(tmp_reg, tmp_reg, markOopDesc::biased_lock_mask_in_place);
aoqi@6880 529 #ifdef _LP64
aoqi@6880 530 daddi(AT, R0, markOopDesc::biased_lock_pattern);
aoqi@6880 531 dsub(AT, AT, tmp_reg);
aoqi@6880 532 #else
aoqi@6880 533 addi(AT, R0, markOopDesc::biased_lock_pattern);
aoqi@6880 534 sub(AT, AT, tmp_reg);
aoqi@6880 535 #endif
aoqi@6880 536 if (need_tmp_reg) {
aoqi@6880 537 pop(tmp_reg);
aoqi@6880 538 }
aoqi@6880 539
aoqi@6880 540 bne(AT, R0, cas_label);
aoqi@6880 541 delayed()->nop();
aoqi@6880 542
aoqi@6880 543
aoqi@6880 544 // The bias pattern is present in the object's header. Need to check
aoqi@6880 545 // whether the bias owner and the epoch are both still current.
aoqi@6880 546 // Note that because there is no current thread register on MIPS we
aoqi@6880 547 // need to store off the mark word we read out of the object to
aoqi@6880 548 // avoid reloading it and needing to recheck invariants below. This
aoqi@6880 549 // store is unfortunate but it makes the overall code shorter and
aoqi@6880 550 // simpler.
aoqi@6880 551 st_ptr(swap_reg, saved_mark_addr);
aoqi@6880 552 if (need_tmp_reg) {
aoqi@6880 553 push(tmp_reg);
aoqi@6880 554 }
aoqi@6880 555 if (swap_reg_contains_mark) {
aoqi@6880 556 null_check_offset = offset();
aoqi@6880 557 }
aoqi@6880 558 load_prototype_header(tmp_reg, obj_reg);
aoqi@6880 559 xorr(tmp_reg, tmp_reg, swap_reg);
aoqi@6880 560 get_thread(swap_reg);
aoqi@6880 561 xorr(swap_reg, swap_reg, tmp_reg);
aoqi@6880 562
aoqi@6880 563 move(AT, ~((int) markOopDesc::age_mask_in_place));
aoqi@6880 564 andr(swap_reg, swap_reg, AT);
aoqi@6880 565
aoqi@6880 566 if (PrintBiasedLockingStatistics) {
aoqi@6880 567 Label L;
aoqi@6880 568 bne(swap_reg, R0, L);
aoqi@6880 569 delayed()->nop();
aoqi@6880 570 push(tmp_reg);
aoqi@6880 571 push(A0);
aoqi@6880 572 atomic_inc32((address)BiasedLocking::biased_lock_entry_count_addr(), 1, A0, tmp_reg);
aoqi@6880 573 pop(A0);
aoqi@6880 574 pop(tmp_reg);
aoqi@6880 575 bind(L);
aoqi@6880 576 }
aoqi@6880 577 if (need_tmp_reg) {
aoqi@6880 578 pop(tmp_reg);
aoqi@6880 579 }
aoqi@6880 580 beq(swap_reg, R0, done);
aoqi@6880 581 delayed()->nop();
aoqi@6880 582 Label try_revoke_bias;
aoqi@6880 583 Label try_rebias;
aoqi@6880 584
aoqi@6880 585 // At this point we know that the header has the bias pattern and
aoqi@6880 586 // that we are not the bias owner in the current epoch. We need to
aoqi@6880 587 // figure out more details about the state of the header in order to
aoqi@6880 588 // know what operations can be legally performed on the object's
aoqi@6880 589 // header.
aoqi@6880 590
aoqi@6880 591 // If the low three bits in the xor result aren't clear, that means
aoqi@6880 592 // the prototype header is no longer biased and we have to revoke
aoqi@6880 593 // the bias on this object.
aoqi@6880 594
aoqi@6880 595 move(AT, markOopDesc::biased_lock_mask_in_place);
aoqi@6880 596 andr(AT, swap_reg, AT);
aoqi@6880 597 bne(AT, R0, try_revoke_bias);
aoqi@6880 598 delayed()->nop();
aoqi@6880 599 // Biasing is still enabled for this data type. See whether the
aoqi@6880 600 // epoch of the current bias is still valid, meaning that the epoch
aoqi@6880 601 // bits of the mark word are equal to the epoch bits of the
aoqi@6880 602 // prototype header. (Note that the prototype header's epoch bits
aoqi@6880 603 // only change at a safepoint.) If not, attempt to rebias the object
aoqi@6880 604 // toward the current thread. Note that we must be absolutely sure
aoqi@6880 605 // that the current epoch is invalid in order to do this because
aoqi@6880 606 // otherwise the manipulations it performs on the mark word are
aoqi@6880 607 // illegal.
aoqi@6880 608
aoqi@6880 609 move(AT, markOopDesc::epoch_mask_in_place);
aoqi@6880 610 andr(AT,swap_reg, AT);
aoqi@6880 611 bne(AT, R0, try_rebias);
aoqi@6880 612 delayed()->nop();
aoqi@6880 613 // The epoch of the current bias is still valid but we know nothing
aoqi@6880 614 // about the owner; it might be set or it might be clear. Try to
aoqi@6880 615 // acquire the bias of the object using an atomic operation. If this
aoqi@6880 616 // fails we will go in to the runtime to revoke the object's bias.
aoqi@6880 617 // Note that we first construct the presumed unbiased header so we
aoqi@6880 618 // don't accidentally blow away another thread's valid bias.
aoqi@6880 619
aoqi@6880 620 ld_ptr(swap_reg, saved_mark_addr);
aoqi@6880 621
aoqi@6880 622 move(AT, markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place);
aoqi@6880 623 andr(swap_reg, swap_reg, AT);
aoqi@6880 624
aoqi@6880 625 if (need_tmp_reg) {
aoqi@6880 626 push(tmp_reg);
aoqi@6880 627 }
aoqi@6880 628 get_thread(tmp_reg);
aoqi@6880 629 orr(tmp_reg, tmp_reg, swap_reg);
aoqi@6880 630 //if (os::is_MP()) {
aoqi@6880 631 // sync();
aoqi@6880 632 //}
aoqi@6880 633 cmpxchg(tmp_reg, Address(obj_reg, 0), swap_reg);
aoqi@6880 634 if (need_tmp_reg) {
aoqi@6880 635 pop(tmp_reg);
aoqi@6880 636 }
aoqi@6880 637 // If the biasing toward our thread failed, this means that
aoqi@6880 638 // another thread succeeded in biasing it toward itself and we
aoqi@6880 639 // need to revoke that bias. The revocation will occur in the
aoqi@6880 640 // interpreter runtime in the slow case.
aoqi@6880 641 if (PrintBiasedLockingStatistics) {
aoqi@6880 642 Label L;
aoqi@6880 643 bne(AT, R0, L);
aoqi@6880 644 delayed()->nop();
aoqi@6880 645 push(tmp_reg);
aoqi@6880 646 push(A0);
aoqi@6880 647 atomic_inc32((address)BiasedLocking::anonymously_biased_lock_entry_count_addr(), 1, A0, tmp_reg);
aoqi@6880 648 pop(A0);
aoqi@6880 649 pop(tmp_reg);
aoqi@6880 650 bind(L);
aoqi@6880 651 }
aoqi@6880 652 if (slow_case != NULL) {
aoqi@6880 653 beq_far(AT, R0, *slow_case);
aoqi@6880 654 delayed()->nop();
aoqi@6880 655 }
aoqi@6880 656 b(done);
aoqi@6880 657 delayed()->nop();
aoqi@6880 658
aoqi@6880 659 bind(try_rebias);
aoqi@6880 660 // At this point we know the epoch has expired, meaning that the
aoqi@6880 661 // current "bias owner", if any, is actually invalid. Under these
aoqi@6880 662 // circumstances _only_, we are allowed to use the current header's
aoqi@6880 663 // value as the comparison value when doing the cas to acquire the
aoqi@6880 664 // bias in the current epoch. In other words, we allow transfer of
aoqi@6880 665 // the bias from one thread to another directly in this situation.
aoqi@6880 666 //
aoqi@6880 667 // FIXME: due to a lack of registers we currently blow away the age
aoqi@6880 668 // bits in this situation. Should attempt to preserve them.
aoqi@6880 669 if (need_tmp_reg) {
aoqi@6880 670 push(tmp_reg);
aoqi@6880 671 }
aoqi@6880 672 load_prototype_header(tmp_reg, obj_reg);
aoqi@6880 673 get_thread(swap_reg);
aoqi@6880 674 orr(tmp_reg, tmp_reg, swap_reg);
aoqi@6880 675 ld_ptr(swap_reg, saved_mark_addr);
aoqi@6880 676
aoqi@6880 677 //if (os::is_MP()) {
aoqi@6880 678 // sync();
aoqi@6880 679 //}
aoqi@6880 680 cmpxchg(tmp_reg, Address(obj_reg, 0), swap_reg);
aoqi@6880 681 if (need_tmp_reg) {
aoqi@6880 682 pop(tmp_reg);
aoqi@6880 683 }
aoqi@6880 684 // If the biasing toward our thread failed, then another thread
aoqi@6880 685 // succeeded in biasing it toward itself and we need to revoke that
aoqi@6880 686 // bias. The revocation will occur in the runtime in the slow case.
aoqi@6880 687 if (PrintBiasedLockingStatistics) {
aoqi@6880 688 Label L;
aoqi@6880 689 bne(AT, R0, L);
aoqi@6880 690 delayed()->nop();
aoqi@6880 691 push(AT);
aoqi@6880 692 push(tmp_reg);
aoqi@6880 693 atomic_inc32((address)BiasedLocking::rebiased_lock_entry_count_addr(), 1, AT, tmp_reg);
aoqi@6880 694 pop(tmp_reg);
aoqi@6880 695 pop(AT);
aoqi@6880 696 bind(L);
aoqi@6880 697 }
aoqi@6880 698 if (slow_case != NULL) {
aoqi@6880 699 beq_far(AT, R0, *slow_case);
aoqi@6880 700 delayed()->nop();
aoqi@6880 701 }
aoqi@6880 702
aoqi@6880 703 b(done);
aoqi@6880 704 delayed()->nop();
aoqi@6880 705 bind(try_revoke_bias);
aoqi@6880 706 // The prototype mark in the klass doesn't have the bias bit set any
aoqi@6880 707 // more, indicating that objects of this data type are not supposed
aoqi@6880 708 // to be biased any more. We are going to try to reset the mark of
aoqi@6880 709 // this object to the prototype value and fall through to the
aoqi@6880 710 // CAS-based locking scheme. Note that if our CAS fails, it means
aoqi@6880 711 // that another thread raced us for the privilege of revoking the
aoqi@6880 712 // bias of this particular object, so it's okay to continue in the
aoqi@6880 713 // normal locking code.
aoqi@6880 714 //
aoqi@6880 715 // FIXME: due to a lack of registers we currently blow away the age
aoqi@6880 716 // bits in this situation. Should attempt to preserve them.
aoqi@6880 717 ld_ptr(swap_reg, saved_mark_addr);
aoqi@6880 718
aoqi@6880 719 if (need_tmp_reg) {
aoqi@6880 720 push(tmp_reg);
aoqi@6880 721 }
aoqi@6880 722 load_prototype_header(tmp_reg, obj_reg);
aoqi@6880 723 //if (os::is_MP()) {
aoqi@6880 724 // lock();
aoqi@6880 725 //}
aoqi@6880 726 cmpxchg(tmp_reg, Address(obj_reg, 0), swap_reg);
aoqi@6880 727 if (need_tmp_reg) {
aoqi@6880 728 pop(tmp_reg);
aoqi@6880 729 }
aoqi@6880 730 // Fall through to the normal CAS-based lock, because no matter what
aoqi@6880 731 // the result of the above CAS, some thread must have succeeded in
aoqi@6880 732 // removing the bias bit from the object's header.
aoqi@6880 733 if (PrintBiasedLockingStatistics) {
aoqi@6880 734 Label L;
aoqi@6880 735 bne(AT, R0, L);
aoqi@6880 736 delayed()->nop();
aoqi@6880 737 push(AT);
aoqi@6880 738 push(tmp_reg);
aoqi@6880 739 atomic_inc32((address)BiasedLocking::revoked_lock_entry_count_addr(), 1, AT, tmp_reg);
aoqi@6880 740 pop(tmp_reg);
aoqi@6880 741 pop(AT);
aoqi@6880 742 bind(L);
aoqi@6880 743 }
aoqi@6880 744
aoqi@6880 745 bind(cas_label);
aoqi@6880 746 return null_check_offset;
aoqi@6880 747 }
aoqi@6880 748
aoqi@6880 749 void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) {
aoqi@6880 750 assert(UseBiasedLocking, "why call this otherwise?");
aoqi@6880 751
aoqi@6880 752 // Check for biased locking unlock case, which is a no-op
aoqi@6880 753 // Note: we do not have to check the thread ID for two reasons.
aoqi@6880 754 // First, the interpreter checks for IllegalMonitorStateException at
aoqi@6880 755 // a higher level. Second, if the bias was revoked while we held the
aoqi@6880 756 // lock, the object could not be rebiased toward another thread, so
aoqi@6880 757 // the bias bit would be clear.
aoqi@6880 758 #ifdef _LP64
aoqi@6880 759 ld(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
aoqi@6880 760 andi(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
aoqi@6880 761 daddi(AT, R0, markOopDesc::biased_lock_pattern);
aoqi@6880 762 #else
aoqi@6880 763 lw(temp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
aoqi@6880 764 andi(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
aoqi@6880 765 addi(AT, R0, markOopDesc::biased_lock_pattern);
aoqi@6880 766 #endif
aoqi@6880 767
aoqi@6880 768 beq(AT, temp_reg, done);
aoqi@6880 769 delayed()->nop();
aoqi@6880 770 }
aoqi@6880 771
aoqi@6880 772 // the stack pointer adjustment is needed. see InterpreterMacroAssembler::super_call_VM_leaf
aoqi@6880 773 // this method will handle the stack problem, you need not to preserve the stack space for the argument now
aoqi@8009 774 void MacroAssembler::call_VM_leaf_base(address entry_point, int number_of_arguments) {
aoqi@6880 775 Label L, E;
aoqi@6880 776
aoqi@6880 777 assert(number_of_arguments <= 4, "just check");
aoqi@6880 778
aoqi@6880 779 andi(AT, SP, 0xf);
aoqi@6880 780 beq(AT, R0, L);
aoqi@6880 781 delayed()->nop();
aoqi@6880 782 daddi(SP, SP, -8);
aoqi@6880 783 call(entry_point, relocInfo::runtime_call_type);
aoqi@6880 784 delayed()->nop();
aoqi@6880 785 daddi(SP, SP, 8);
aoqi@6880 786 b(E);
aoqi@6880 787 delayed()->nop();
aoqi@6880 788
aoqi@6880 789 bind(L);
aoqi@6880 790 call(entry_point, relocInfo::runtime_call_type);
aoqi@6880 791 delayed()->nop();
aoqi@6880 792 bind(E);
aoqi@6880 793 }
aoqi@6880 794
aoqi@6880 795
aoqi@6880 796 void MacroAssembler::jmp(address entry) {
aoqi@6880 797 patchable_set48(T9, (long)entry);
aoqi@6880 798 jr(T9);
aoqi@6880 799 }
aoqi@6880 800
aoqi@6880 801 void MacroAssembler::jmp(address entry, relocInfo::relocType rtype) {
aoqi@6880 802 switch (rtype) {
aoqi@6880 803 case relocInfo::runtime_call_type:
aoqi@6880 804 case relocInfo::none:
aoqi@6880 805 jmp(entry);
aoqi@6880 806 break;
aoqi@6880 807 default:
aoqi@6880 808 {
aoqi@6880 809 InstructionMark im(this);
aoqi@6880 810 relocate(rtype);
aoqi@6880 811 patchable_set48(T9, (long)entry);
aoqi@6880 812 jr(T9);
aoqi@6880 813 }
aoqi@6880 814 break;
aoqi@6880 815 }
aoqi@6880 816 }
aoqi@6880 817
aoqi@8862 818 void MacroAssembler::jmp_far(Label& L) {
aoqi@8862 819 if (L.is_bound()) {
aoqi@8862 820 address entry = target(L);
aoqi@8862 821 assert(entry != NULL, "jmp most probably wrong");
aoqi@8862 822 InstructionMark im(this);
aoqi@8862 823
aoqi@8862 824 relocate(relocInfo::internal_word_type);
aoqi@8862 825 patchable_set48(T9, (long)entry);
aoqi@8862 826 } else {
aoqi@8862 827 InstructionMark im(this);
aoqi@8862 828 L.add_patch_at(code(), locator());
aoqi@8862 829
aoqi@8862 830 relocate(relocInfo::internal_word_type);
aoqi@8862 831 patchable_set48(T9, (long)pc());
aoqi@8862 832 }
aoqi@8862 833
aoqi@8862 834 jr(T9);
zhaixiang@9144 835 delayed()->nop();
aoqi@8862 836 }
aoqi@8865 837 void MacroAssembler::mov_metadata(Address dst, Metadata* obj) {
aoqi@8865 838 int oop_index;
aoqi@8865 839 if (obj) {
aoqi@8865 840 oop_index = oop_recorder()->find_index(obj);
aoqi@8865 841 } else {
aoqi@8865 842 oop_index = oop_recorder()->allocate_metadata_index(obj);
aoqi@8865 843 }
aoqi@8865 844 relocate(metadata_Relocation::spec(oop_index));
aoqi@8865 845 patchable_set48(AT, (long)obj);
aoqi@8865 846 sd(AT, dst);
aoqi@8865 847 }
aoqi@8865 848
aoqi@8865 849 void MacroAssembler::mov_metadata(Register dst, Metadata* obj) {
aoqi@8865 850 int oop_index;
aoqi@8865 851 if (obj) {
aoqi@8865 852 oop_index = oop_recorder()->find_index(obj);
aoqi@8865 853 } else {
aoqi@8865 854 oop_index = oop_recorder()->allocate_metadata_index(obj);
aoqi@8865 855 }
aoqi@8865 856 relocate(metadata_Relocation::spec(oop_index));
aoqi@8865 857 patchable_set48(dst, (long)obj);
aoqi@8865 858 }
aoqi@8862 859
aoqi@6880 860 void MacroAssembler::call(address entry) {
aoqi@6880 861 // c/c++ code assume T9 is entry point, so we just always move entry to t9
aoqi@6880 862 // maybe there is some more graceful method to handle this. FIXME
aoqi@6880 863 // For more info, see class NativeCall.
aoqi@6880 864 #ifndef _LP64
aoqi@6880 865 move(T9, (int)entry);
aoqi@6880 866 #else
aoqi@6880 867 patchable_set48(T9, (long)entry);
aoqi@6880 868 #endif
aoqi@6880 869 jalr(T9);
aoqi@6880 870 }
aoqi@6880 871
aoqi@6880 872 void MacroAssembler::call(address entry, relocInfo::relocType rtype) {
aoqi@6880 873 switch (rtype) {
aoqi@6880 874 case relocInfo::runtime_call_type:
aoqi@6880 875 case relocInfo::none:
aoqi@6880 876 call(entry);
aoqi@6880 877 break;
aoqi@6880 878 default:
aoqi@6880 879 {
aoqi@6880 880 InstructionMark im(this);
aoqi@6880 881 relocate(rtype);
aoqi@6880 882 call(entry);
aoqi@6880 883 }
aoqi@6880 884 break;
aoqi@6880 885 }
aoqi@6880 886 }
aoqi@6880 887
aoqi@6880 888 void MacroAssembler::call(address entry, RelocationHolder& rh)
aoqi@6880 889 {
aoqi@6880 890 switch (rh.type()) {
aoqi@6880 891 case relocInfo::runtime_call_type:
aoqi@6880 892 case relocInfo::none:
aoqi@6880 893 call(entry);
aoqi@6880 894 break;
aoqi@6880 895 default:
aoqi@6880 896 {
aoqi@6880 897 InstructionMark im(this);
aoqi@6880 898 relocate(rh);
aoqi@6880 899 call(entry);
aoqi@6880 900 }
aoqi@6880 901 break;
aoqi@6880 902 }
aoqi@6880 903 }
aoqi@6880 904
aoqi@6880 905 void MacroAssembler::ic_call(address entry) {
aoqi@6880 906 RelocationHolder rh = virtual_call_Relocation::spec(pc());
aoqi@6880 907 patchable_set48(IC_Klass, (long)Universe::non_oop_word());
aoqi@6880 908 assert(entry != NULL, "call most probably wrong");
aoqi@6880 909 InstructionMark im(this);
aoqi@6880 910 relocate(rh);
aoqi@8865 911 patchable_call(entry);
aoqi@6880 912 }
aoqi@6880 913
aoqi@6880 914 void MacroAssembler::c2bool(Register r) {
aoqi@6880 915 Label L;
aoqi@6880 916 Assembler::beq(r, R0, L);
aoqi@6880 917 delayed()->nop();
aoqi@6880 918 move(r, 1);
aoqi@6880 919 bind(L);
aoqi@6880 920 }
aoqi@6880 921
aoqi@6880 922 #ifndef PRODUCT
aoqi@6880 923 extern "C" void findpc(intptr_t x);
aoqi@6880 924 #endif
aoqi@6880 925
aoqi@6880 926 void MacroAssembler::debug(char* msg/*, RegistersForDebugging* regs*/) {
aoqi@6880 927 if ( ShowMessageBoxOnError ) {
aoqi@6880 928 JavaThreadState saved_state = JavaThread::current()->thread_state();
aoqi@6880 929 JavaThread::current()->set_thread_state(_thread_in_vm);
aoqi@6880 930 {
aoqi@6880 931 // In order to get locks work, we need to fake a in_VM state
aoqi@6880 932 ttyLocker ttyl;
aoqi@6880 933 ::tty->print_cr("EXECUTION STOPPED: %s\n", msg);
aoqi@6880 934 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
aoqi@6880 935 BytecodeCounter::print();
aoqi@6880 936 }
aoqi@6880 937
aoqi@6880 938 }
aoqi@6880 939 ThreadStateTransition::transition(JavaThread::current(), _thread_in_vm, saved_state);
aoqi@6880 940 }
aoqi@6880 941 else
aoqi@6880 942 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg);
aoqi@6880 943 }
aoqi@6880 944
aoqi@6880 945
aoqi@6880 946 void MacroAssembler::stop(const char* msg) {
aoqi@6880 947 li(A0, (long)msg);
aoqi@6880 948 #ifndef _LP64
aoqi@9228 949 //reserver space for argument.
aoqi@6880 950 addiu(SP, SP, - 1 * wordSize);
aoqi@6880 951 #endif
aoqi@6880 952 call(CAST_FROM_FN_PTR(address, MacroAssembler::debug), relocInfo::runtime_call_type);
aoqi@6880 953 delayed()->nop();
aoqi@6880 954 #ifndef _LP64
aoqi@6880 955 //restore space for argument
aoqi@6880 956 addiu(SP, SP, 1 * wordSize);
aoqi@6880 957 #endif
aoqi@6880 958 brk(17);
aoqi@6880 959 }
aoqi@6880 960
aoqi@6880 961 void MacroAssembler::warn(const char* msg) {
aoqi@6880 962 #ifdef _LP64
aoqi@6880 963 pushad();
aoqi@6880 964 li(A0, (long)msg);
aoqi@6880 965 push(S2);
aoqi@6880 966 move(AT, -(StackAlignmentInBytes));
aoqi@6880 967 move(S2, SP); // use S2 as a sender SP holder
aoqi@6880 968 andr(SP, SP, AT); // align stack as required by ABI
aoqi@6880 969 call(CAST_FROM_FN_PTR(address, MacroAssembler::debug), relocInfo::runtime_call_type);
aoqi@6880 970 delayed()->nop();
aoqi@6880 971 move(SP, S2); // use S2 as a sender SP holder
aoqi@6880 972 pop(S2);
aoqi@6880 973 popad();
aoqi@6880 974 #else
aoqi@6880 975 pushad();
aoqi@6880 976 addi(SP, SP, -4);
aoqi@6880 977 sw(A0, SP, -1 * wordSize);
aoqi@6880 978 li(A0, (long)msg);
aoqi@6880 979 addi(SP, SP, -1 * wordSize);
aoqi@6880 980 call(CAST_FROM_FN_PTR(address, MacroAssembler::debug), relocInfo::runtime_call_type);
aoqi@6880 981 delayed()->nop();
aoqi@6880 982 addi(SP, SP, 1 * wordSize);
aoqi@6880 983 lw(A0, SP, -1 * wordSize);
aoqi@6880 984 addi(SP, SP, 4);
aoqi@6880 985 popad();
aoqi@6880 986 #endif
aoqi@6880 987 }
aoqi@6880 988
aoqi@6880 989 void MacroAssembler::print_reg(Register reg) {
aoqi@6880 990 void * cur_pc = pc();
aoqi@6880 991 pushad();
aoqi@6880 992 NOT_LP64(push(FP);)
aoqi@6880 993
aoqi@6880 994 li(A0, (long)reg->name());
aoqi@6880 995 if (reg == SP)
aoqi@6880 996 addiu(A1, SP, wordSize * 23); //23 registers saved in pushad()
aoqi@6880 997 else if (reg == A0)
aoqi@6880 998 ld(A1, SP, wordSize * 19); //A0 has been modified by li(A0, (long)reg->name()). Ugly Code!
aoqi@6880 999 else
aoqi@6880 1000 move(A1, reg);
aoqi@6880 1001 li(A2, (long)cur_pc);
aoqi@6880 1002 push(S2);
aoqi@6880 1003 move(AT, -(StackAlignmentInBytes));
aoqi@6880 1004 move(S2, SP); // use S2 as a sender SP holder
aoqi@6880 1005 andr(SP, SP, AT); // align stack as required by ABI
aoqi@6880 1006 call(CAST_FROM_FN_PTR(address, SharedRuntime::print_reg_with_pc),relocInfo::runtime_call_type);
aoqi@6880 1007 delayed()->nop();
aoqi@6880 1008 move(SP, S2); // use S2 as a sender SP holder
aoqi@6880 1009 pop(S2);
aoqi@6880 1010 NOT_LP64(pop(FP);)
aoqi@6880 1011 popad();
aoqi@6880 1012
aoqi@6880 1013 }
aoqi@6880 1014
aoqi@6880 1015 void MacroAssembler::print_reg(FloatRegister reg) {
aoqi@6880 1016 void * cur_pc = pc();
aoqi@6880 1017 pushad();
aoqi@6880 1018 NOT_LP64(push(FP);)
aoqi@6880 1019 li(A0, (long)reg->name());
aoqi@6880 1020 push(S2);
aoqi@6880 1021 move(AT, -(StackAlignmentInBytes));
aoqi@6880 1022 move(S2, SP); // use S2 as a sender SP holder
aoqi@6880 1023 andr(SP, SP, AT); // align stack as required by ABI
aoqi@6880 1024 call(CAST_FROM_FN_PTR(address, SharedRuntime::print_str),relocInfo::runtime_call_type);
aoqi@6880 1025 delayed()->nop();
aoqi@6880 1026 move(SP, S2); // use S2 as a sender SP holder
aoqi@6880 1027 pop(S2);
aoqi@6880 1028 NOT_LP64(pop(FP);)
aoqi@6880 1029 popad();
aoqi@6880 1030
aoqi@6880 1031 pushad();
aoqi@6880 1032 NOT_LP64(push(FP);)
aoqi@6880 1033 move(FP, SP);
aoqi@6880 1034 move(AT, -(StackAlignmentInBytes));
aoqi@6880 1035 andr(SP , SP , AT);
aoqi@6880 1036 mov_d(F12, reg);
aoqi@6880 1037 call(CAST_FROM_FN_PTR(address, SharedRuntime::print_double),relocInfo::runtime_call_type);
aoqi@6880 1038 delayed()->nop();
aoqi@6880 1039 move(SP, FP);
aoqi@6880 1040 NOT_LP64(pop(FP);)
aoqi@6880 1041 popad();
aoqi@6880 1042
aoqi@6880 1043 }
aoqi@6880 1044
aoqi@6880 1045 void MacroAssembler::increment(Register reg, int imm) {
aoqi@6880 1046 if (!imm) return;
aoqi@6880 1047 if (is_simm16(imm)) {
aoqi@6880 1048 #ifdef _LP64
aoqi@6880 1049 daddiu(reg, reg, imm);
aoqi@6880 1050 #else
aoqi@6880 1051 addiu(reg, reg, imm);
aoqi@6880 1052 #endif
aoqi@6880 1053 } else {
aoqi@6880 1054 move(AT, imm);
aoqi@6880 1055 #ifdef _LP64
aoqi@6880 1056 daddu(reg, reg, AT);
aoqi@6880 1057 #else
aoqi@6880 1058 addu(reg, reg, AT);
aoqi@6880 1059 #endif
aoqi@6880 1060 }
aoqi@6880 1061 }
aoqi@6880 1062
aoqi@6880 1063 void MacroAssembler::decrement(Register reg, int imm) {
aoqi@6880 1064 increment(reg, -imm);
aoqi@6880 1065 }
aoqi@6880 1066
aoqi@6880 1067
aoqi@6880 1068 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1069 address entry_point,
aoqi@6880 1070 bool check_exceptions) {
aoqi@6880 1071 call_VM_helper(oop_result, entry_point, 0, check_exceptions);
aoqi@6880 1072 }
aoqi@6880 1073
aoqi@6880 1074 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1075 address entry_point,
aoqi@6880 1076 Register arg_1,
aoqi@6880 1077 bool check_exceptions) {
aoqi@6880 1078 if (arg_1!=A1) move(A1, arg_1);
aoqi@6880 1079 call_VM_helper(oop_result, entry_point, 1, check_exceptions);
aoqi@6880 1080 }
aoqi@6880 1081
aoqi@6880 1082 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1083 address entry_point,
aoqi@6880 1084 Register arg_1,
aoqi@6880 1085 Register arg_2,
aoqi@6880 1086 bool check_exceptions) {
aoqi@6880 1087 if (arg_1!=A1) move(A1, arg_1);
aoqi@6880 1088 if (arg_2!=A2) move(A2, arg_2);
aoqi@6880 1089 assert(arg_2 != A1, "smashed argument");
aoqi@6880 1090 call_VM_helper(oop_result, entry_point, 2, check_exceptions);
aoqi@6880 1091 }
aoqi@6880 1092
aoqi@6880 1093 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1094 address entry_point,
aoqi@6880 1095 Register arg_1,
aoqi@6880 1096 Register arg_2,
aoqi@6880 1097 Register arg_3,
aoqi@6880 1098 bool check_exceptions) {
aoqi@6880 1099 if (arg_1!=A1) move(A1, arg_1);
aoqi@6880 1100 if (arg_2!=A2) move(A2, arg_2); assert(arg_2 != A1, "smashed argument");
aoqi@6880 1101 if (arg_3!=A3) move(A3, arg_3); assert(arg_3 != A1 && arg_3 != A2, "smashed argument");
aoqi@6880 1102 call_VM_helper(oop_result, entry_point, 3, check_exceptions);
aoqi@6880 1103 }
aoqi@6880 1104
aoqi@6880 1105 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1106 Register last_java_sp,
aoqi@6880 1107 address entry_point,
aoqi@6880 1108 int number_of_arguments,
aoqi@6880 1109 bool check_exceptions) {
aoqi@6880 1110 call_VM_base(oop_result, NOREG, last_java_sp, entry_point, number_of_arguments, check_exceptions);
aoqi@6880 1111 }
aoqi@6880 1112
aoqi@6880 1113 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1114 Register last_java_sp,
aoqi@6880 1115 address entry_point,
aoqi@6880 1116 Register arg_1,
aoqi@6880 1117 bool check_exceptions) {
aoqi@6880 1118 if (arg_1 != A1) move(A1, arg_1);
aoqi@6880 1119 call_VM(oop_result, last_java_sp, entry_point, 1, check_exceptions);
aoqi@6880 1120 }
aoqi@6880 1121
aoqi@6880 1122 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1123 Register last_java_sp,
aoqi@6880 1124 address entry_point,
aoqi@6880 1125 Register arg_1,
aoqi@6880 1126 Register arg_2,
aoqi@6880 1127 bool check_exceptions) {
aoqi@6880 1128 if (arg_1 != A1) move(A1, arg_1);
aoqi@6880 1129 if (arg_2 != A2) move(A2, arg_2); assert(arg_2 != A1, "smashed argument");
aoqi@6880 1130 call_VM(oop_result, last_java_sp, entry_point, 2, check_exceptions);
aoqi@6880 1131 }
aoqi@6880 1132
aoqi@6880 1133 void MacroAssembler::call_VM(Register oop_result,
aoqi@6880 1134 Register last_java_sp,
aoqi@6880 1135 address entry_point,
aoqi@6880 1136 Register arg_1,
aoqi@6880 1137 Register arg_2,
aoqi@6880 1138 Register arg_3,
aoqi@6880 1139 bool check_exceptions) {
aoqi@6880 1140 if (arg_1 != A1) move(A1, arg_1);
aoqi@6880 1141 if (arg_2 != A2) move(A2, arg_2); assert(arg_2 != A1, "smashed argument");
aoqi@6880 1142 if (arg_3 != A3) move(A3, arg_3); assert(arg_3 != A1 && arg_3 != A2, "smashed argument");
aoqi@6880 1143 call_VM(oop_result, last_java_sp, entry_point, 3, check_exceptions);
aoqi@6880 1144 }
aoqi@6880 1145
aoqi@6880 1146 void MacroAssembler::call_VM_base(Register oop_result,
aoqi@6880 1147 Register java_thread,
aoqi@6880 1148 Register last_java_sp,
aoqi@6880 1149 address entry_point,
aoqi@6880 1150 int number_of_arguments,
aoqi@8009 1151 bool check_exceptions) {
aoqi@6880 1152
aoqi@6880 1153 address before_call_pc;
aoqi@6880 1154 // determine java_thread register
aoqi@6880 1155 if (!java_thread->is_valid()) {
aoqi@6880 1156 #ifndef OPT_THREAD
aoqi@6880 1157 java_thread = T2;
aoqi@6880 1158 get_thread(java_thread);
aoqi@6880 1159 #else
aoqi@6880 1160 java_thread = TREG;
aoqi@6880 1161 #endif
aoqi@6880 1162 }
aoqi@6880 1163 // determine last_java_sp register
aoqi@6880 1164 if (!last_java_sp->is_valid()) {
aoqi@6880 1165 last_java_sp = SP;
aoqi@6880 1166 }
aoqi@6880 1167 // debugging support
aoqi@6880 1168 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
aoqi@6880 1169 assert(number_of_arguments <= 4 , "cannot have negative number of arguments");
aoqi@6880 1170 assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result");
aoqi@6880 1171 assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp");
aoqi@6880 1172
aoqi@9459 1173 assert(last_java_sp != FP, "this code doesn't work for last_java_sp == fp, which currently can't portably work anyway since C2 doesn't save fp");
aoqi@6880 1174
aoqi@6880 1175 // set last Java frame before call
aoqi@6880 1176 before_call_pc = (address)pc();
aoqi@6880 1177 set_last_Java_frame(java_thread, last_java_sp, FP, before_call_pc);
aoqi@6880 1178
aoqi@6880 1179 // do the call
aoqi@6880 1180 move(A0, java_thread);
aoqi@6880 1181 call(entry_point, relocInfo::runtime_call_type);
aoqi@6880 1182 delayed()->nop();
aoqi@6880 1183
aoqi@6880 1184 // restore the thread (cannot use the pushed argument since arguments
aoqi@6880 1185 // may be overwritten by C code generated by an optimizing compiler);
aoqi@6880 1186 // however can use the register value directly if it is callee saved.
aoqi@6880 1187 #ifndef OPT_THREAD
wangxue@7995 1188 get_thread(java_thread);
wangxue@7995 1189 #else
aoqi@6880 1190 #ifdef ASSERT
aoqi@7997 1191 {
wangxue@7995 1192 Label L;
wangxue@7995 1193 get_thread(AT);
wangxue@7995 1194 beq(java_thread, AT, L);
wangxue@7995 1195 delayed()->nop();
aoqi@8009 1196 stop("MacroAssembler::call_VM_base: TREG not callee saved?");
wangxue@7995 1197 bind(L);
wangxue@7995 1198 }
aoqi@6880 1199 #endif
aoqi@6880 1200 #endif
aoqi@6880 1201
aoqi@6880 1202 // discard thread and arguments
aoqi@6880 1203 ld_ptr(SP, java_thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@6880 1204 // reset last Java frame
fujie@9171 1205 reset_last_Java_frame(java_thread, false);
aoqi@6880 1206
aoqi@6880 1207 check_and_handle_popframe(java_thread);
aoqi@6880 1208 check_and_handle_earlyret(java_thread);
aoqi@6880 1209 if (check_exceptions) {
aoqi@6880 1210 // check for pending exceptions (java_thread is set upon return)
aoqi@6880 1211 Label L;
aoqi@6880 1212 #ifdef _LP64
aoqi@6880 1213 ld(AT, java_thread, in_bytes(Thread::pending_exception_offset()));
aoqi@6880 1214 #else
aoqi@6880 1215 lw(AT, java_thread, in_bytes(Thread::pending_exception_offset()));
aoqi@6880 1216 #endif
aoqi@6880 1217 beq(AT, R0, L);
aoqi@6880 1218 delayed()->nop();
aoqi@6880 1219 li(AT, before_call_pc);
aoqi@6880 1220 push(AT);
aoqi@6880 1221 jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type);
aoqi@6880 1222 delayed()->nop();
aoqi@6880 1223 bind(L);
aoqi@6880 1224 }
aoqi@6880 1225
aoqi@6880 1226 // get oop result if there is one and reset the value in the thread
aoqi@6880 1227 if (oop_result->is_valid()) {
aoqi@6880 1228 #ifdef _LP64
aoqi@6880 1229 ld(oop_result, java_thread, in_bytes(JavaThread::vm_result_offset()));
aoqi@6880 1230 sd(R0, java_thread, in_bytes(JavaThread::vm_result_offset()));
aoqi@6880 1231 #else
aoqi@6880 1232 lw(oop_result, java_thread, in_bytes(JavaThread::vm_result_offset()));
aoqi@6880 1233 sw(R0, java_thread, in_bytes(JavaThread::vm_result_offset()));
aoqi@6880 1234 #endif
aoqi@6880 1235 verify_oop(oop_result);
aoqi@6880 1236 }
aoqi@6880 1237 }
aoqi@6880 1238
aoqi@6880 1239 void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) {
aoqi@6880 1240
aoqi@6880 1241 move(V0, SP);
aoqi@6880 1242 //we also reserve space for java_thread here
aoqi@6880 1243 #ifndef _LP64
aoqi@6880 1244 daddi(SP, SP, (1 + number_of_arguments) * (- wordSize));
aoqi@6880 1245 #endif
aoqi@6880 1246 move(AT, -(StackAlignmentInBytes));
aoqi@6880 1247 andr(SP, SP, AT);
aoqi@6880 1248 call_VM_base(oop_result, NOREG, V0, entry_point, number_of_arguments, check_exceptions);
aoqi@6880 1249
aoqi@6880 1250 }
aoqi@6880 1251
aoqi@6880 1252 void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) {
aoqi@6880 1253 call_VM_leaf_base(entry_point, number_of_arguments);
aoqi@6880 1254 }
aoqi@6880 1255
aoqi@6880 1256 void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0) {
aoqi@6880 1257 if (arg_0 != A0) move(A0, arg_0);
aoqi@6880 1258 call_VM_leaf(entry_point, 1);
aoqi@6880 1259 }
aoqi@6880 1260
aoqi@6880 1261 void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1) {
aoqi@6880 1262 if (arg_0 != A0) move(A0, arg_0);
aoqi@6880 1263 if (arg_1 != A1) move(A1, arg_1); assert(arg_1 != A0, "smashed argument");
aoqi@6880 1264 call_VM_leaf(entry_point, 2);
aoqi@6880 1265 }
aoqi@6880 1266
aoqi@6880 1267 void MacroAssembler::call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2) {
aoqi@6880 1268 if (arg_0 != A0) move(A0, arg_0);
aoqi@6880 1269 if (arg_1 != A1) move(A1, arg_1); assert(arg_1 != A0, "smashed argument");
aoqi@6880 1270 if (arg_2 != A2) move(A2, arg_2); assert(arg_2 != A0 && arg_2 != A1, "smashed argument");
aoqi@6880 1271 call_VM_leaf(entry_point, 3);
aoqi@6880 1272 }
aoqi@6880 1273 void MacroAssembler::super_call_VM_leaf(address entry_point) {
aoqi@6880 1274 MacroAssembler::call_VM_leaf_base(entry_point, 0);
aoqi@6880 1275 }
aoqi@6880 1276
aoqi@6880 1277
aoqi@6880 1278 void MacroAssembler::super_call_VM_leaf(address entry_point,
aoqi@6880 1279 Register arg_1) {
aoqi@6880 1280 if (arg_1 != A0) move(A0, arg_1);
aoqi@6880 1281 MacroAssembler::call_VM_leaf_base(entry_point, 1);
aoqi@6880 1282 }
aoqi@6880 1283
aoqi@6880 1284
aoqi@6880 1285 void MacroAssembler::super_call_VM_leaf(address entry_point,
aoqi@6880 1286 Register arg_1,
aoqi@6880 1287 Register arg_2) {
aoqi@6880 1288 if (arg_1 != A0) move(A0, arg_1);
aoqi@6880 1289 if (arg_2 != A1) move(A1, arg_2); assert(arg_2 != A0, "smashed argument");
aoqi@6880 1290 MacroAssembler::call_VM_leaf_base(entry_point, 2);
aoqi@6880 1291 }
aoqi@6880 1292 void MacroAssembler::super_call_VM_leaf(address entry_point,
aoqi@6880 1293 Register arg_1,
aoqi@6880 1294 Register arg_2,
aoqi@6880 1295 Register arg_3) {
aoqi@6880 1296 if (arg_1 != A0) move(A0, arg_1);
aoqi@6880 1297 if (arg_2 != A1) move(A1, arg_2); assert(arg_2 != A0, "smashed argument");
aoqi@6880 1298 if (arg_3 != A2) move(A2, arg_3); assert(arg_3 != A0 && arg_3 != A1, "smashed argument");
aoqi@6880 1299 MacroAssembler::call_VM_leaf_base(entry_point, 3);
aoqi@6880 1300 }
aoqi@6880 1301
aoqi@6880 1302 void MacroAssembler::check_and_handle_earlyret(Register java_thread) {
aoqi@6880 1303 }
aoqi@6880 1304
aoqi@6880 1305 void MacroAssembler::check_and_handle_popframe(Register java_thread) {
aoqi@6880 1306 }
aoqi@6880 1307
aoqi@6880 1308 void MacroAssembler::null_check(Register reg, int offset) {
aoqi@6880 1309 if (needs_explicit_null_check(offset)) {
aoqi@6880 1310 // provoke OS NULL exception if reg = NULL by
aoqi@6880 1311 // accessing M[reg] w/o changing any (non-CC) registers
aoqi@6880 1312 // NOTE: cmpl is plenty here to provoke a segv
aoqi@6880 1313 lw(AT, reg, 0);
aoqi@6880 1314 } else {
aoqi@6880 1315 // nothing to do, (later) access of M[reg + offset]
aoqi@6880 1316 // will provoke OS NULL exception if reg = NULL
aoqi@6880 1317 }
aoqi@6880 1318 }
aoqi@6880 1319
aoqi@6880 1320 void MacroAssembler::enter() {
aoqi@6880 1321 push2(RA, FP);
aoqi@6880 1322 move(FP, SP);
aoqi@6880 1323 }
aoqi@6880 1324
aoqi@6880 1325 void MacroAssembler::leave() {
aoqi@6880 1326 #ifndef _LP64
aoqi@6880 1327 addi(SP, FP, 2 * wordSize);
aoqi@6880 1328 lw(RA, SP, - 1 * wordSize);
aoqi@6880 1329 lw(FP, SP, - 2 * wordSize);
aoqi@6880 1330 #else
aoqi@6880 1331 daddi(SP, FP, 2 * wordSize);
aoqi@6880 1332 ld(RA, SP, - 1 * wordSize);
aoqi@6880 1333 ld(FP, SP, - 2 * wordSize);
aoqi@6880 1334 #endif
aoqi@6880 1335 }
aoqi@9459 1336
fujie@9171 1337 void MacroAssembler::reset_last_Java_frame(Register java_thread, bool clear_fp) {
aoqi@6880 1338 // determine java_thread register
aoqi@6880 1339 if (!java_thread->is_valid()) {
aoqi@6880 1340 #ifndef OPT_THREAD
aoqi@6880 1341 java_thread = T1;
aoqi@6880 1342 get_thread(java_thread);
aoqi@6880 1343 #else
aoqi@6880 1344 java_thread = TREG;
aoqi@6880 1345 #endif
aoqi@6880 1346 }
aoqi@6880 1347 // we must set sp to zero to clear frame
aoqi@6880 1348 st_ptr(R0, java_thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@6880 1349 // must clear fp, so that compiled frames are not confused; it is possible
aoqi@6880 1350 // that we need it only for debugging
fujie@9171 1351 if(clear_fp) {
aoqi@6880 1352 st_ptr(R0, java_thread, in_bytes(JavaThread::last_Java_fp_offset()));
fujie@9171 1353 }
fujie@9171 1354
fujie@9171 1355 // Always clear the pc because it could have been set by make_walkable()
fujie@9171 1356 st_ptr(R0, java_thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@6880 1357 }
aoqi@6880 1358
fujie@9171 1359 void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
aoqi@6880 1360 Register thread = TREG;
aoqi@6880 1361 #ifndef OPT_THREAD
aoqi@6880 1362 get_thread(thread);
aoqi@6880 1363 #endif
aoqi@6880 1364 // we must set sp to zero to clear frame
aoqi@6880 1365 sd(R0, Address(thread, JavaThread::last_Java_sp_offset()));
aoqi@6880 1366 // must clear fp, so that compiled frames are not confused; it is
aoqi@6880 1367 // possible that we need it only for debugging
aoqi@6880 1368 if (clear_fp) {
aoqi@6880 1369 sd(R0, Address(thread, JavaThread::last_Java_fp_offset()));
aoqi@6880 1370 }
aoqi@6880 1371
fujie@9171 1372 // Always clear the pc because it could have been set by make_walkable()
fujie@9171 1373 sd(R0, Address(thread, JavaThread::last_Java_pc_offset()));
aoqi@6880 1374 }
aoqi@6880 1375
aoqi@6880 1376 // Write serialization page so VM thread can do a pseudo remote membar.
aoqi@6880 1377 // We use the current thread pointer to calculate a thread specific
aoqi@6880 1378 // offset to write to within the page. This minimizes bus traffic
aoqi@6880 1379 // due to cache line collision.
aoqi@6880 1380 void MacroAssembler::serialize_memory(Register thread, Register tmp) {
aoqi@6880 1381 move(tmp, thread);
aoqi@6880 1382 srl(tmp, tmp,os::get_serialize_page_shift_count());
aoqi@6880 1383 move(AT, (os::vm_page_size() - sizeof(int)));
aoqi@6880 1384 andr(tmp, tmp,AT);
aoqi@6880 1385 sw(tmp,Address(tmp, (intptr_t)os::get_memory_serialize_page()));
aoqi@6880 1386 }
aoqi@6880 1387
aoqi@6880 1388 // Calls to C land
aoqi@6880 1389 //
aoqi@9459 1390 // When entering C land, the fp, & sp of the last Java frame have to be recorded
aoqi@6880 1391 // in the (thread-local) JavaThread object. When leaving C land, the last Java fp
aoqi@6880 1392 // has to be reset to 0. This is required to allow proper stack traversal.
aoqi@6880 1393 void MacroAssembler::set_last_Java_frame(Register java_thread,
aoqi@6880 1394 Register last_java_sp,
aoqi@6880 1395 Register last_java_fp,
aoqi@6880 1396 address last_java_pc) {
aoqi@6880 1397 // determine java_thread register
aoqi@6880 1398 if (!java_thread->is_valid()) {
aoqi@6880 1399 #ifndef OPT_THREAD
aoqi@6880 1400 java_thread = T2;
aoqi@6880 1401 get_thread(java_thread);
aoqi@6880 1402 #else
aoqi@6880 1403 java_thread = TREG;
aoqi@6880 1404 #endif
aoqi@6880 1405 }
aoqi@6880 1406 // determine last_java_sp register
aoqi@6880 1407 if (!last_java_sp->is_valid()) {
aoqi@6880 1408 last_java_sp = SP;
aoqi@6880 1409 }
aoqi@6880 1410
aoqi@6880 1411 // last_java_fp is optional
aoqi@6880 1412 if (last_java_fp->is_valid()) {
aoqi@6880 1413 st_ptr(last_java_fp, java_thread, in_bytes(JavaThread::last_Java_fp_offset()));
aoqi@6880 1414 }
aoqi@6880 1415
aoqi@6880 1416 // last_java_pc is optional
aoqi@6880 1417 if (last_java_pc != NULL) {
fujie@9171 1418 relocate(relocInfo::internal_word_type);
aoqi@6880 1419 patchable_set48(AT, (long)last_java_pc);
fujie@9171 1420 st_ptr(AT, java_thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@6880 1421 }
aoqi@6880 1422 st_ptr(last_java_sp, java_thread, in_bytes(JavaThread::last_Java_sp_offset()));
aoqi@6880 1423 }
aoqi@6880 1424
aoqi@6880 1425 void MacroAssembler::set_last_Java_frame(Register last_java_sp,
aoqi@6880 1426 Register last_java_fp,
aoqi@6880 1427 address last_java_pc) {
aoqi@6880 1428 // determine last_java_sp register
aoqi@6880 1429 if (!last_java_sp->is_valid()) {
aoqi@6880 1430 last_java_sp = SP;
aoqi@6880 1431 }
aoqi@6880 1432
aoqi@6880 1433 Register thread = TREG;
aoqi@6880 1434 #ifndef OPT_THREAD
aoqi@6880 1435 get_thread(thread);
aoqi@6880 1436 #endif
aoqi@6880 1437 // last_java_fp is optional
aoqi@6880 1438 if (last_java_fp->is_valid()) {
aoqi@6880 1439 sd(last_java_fp, Address(thread, JavaThread::last_Java_fp_offset()));
aoqi@6880 1440 }
aoqi@6880 1441
aoqi@6880 1442 // last_java_pc is optional
aoqi@6880 1443 if (last_java_pc != NULL) {
fujie@9171 1444 relocate(relocInfo::internal_word_type);
fujie@9171 1445 patchable_set48(AT, (long)last_java_pc);
fujie@9171 1446 st_ptr(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset()));
aoqi@6880 1447 }
aoqi@6880 1448
aoqi@6880 1449 sd(last_java_sp, Address(thread, JavaThread::last_Java_sp_offset()));
aoqi@6880 1450 }
aoqi@6880 1451
aoqi@6880 1452 //////////////////////////////////////////////////////////////////////////////////
aoqi@6880 1453 #if INCLUDE_ALL_GCS
aoqi@6880 1454
aoqi@6880 1455 void MacroAssembler::g1_write_barrier_pre(Register obj,
fujie@8000 1456 Register pre_val,
aoqi@6880 1457 Register thread,
aoqi@6880 1458 Register tmp,
fujie@8000 1459 bool tosca_live,
fujie@8000 1460 bool expand_call) {
fujie@8000 1461
fujie@8000 1462 // If expand_call is true then we expand the call_VM_leaf macro
fujie@8000 1463 // directly to skip generating the check by
fujie@8000 1464 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
fujie@8000 1465
fujie@8000 1466 #ifdef _LP64
fujie@8000 1467 assert(thread == TREG, "must be");
fujie@8000 1468 #endif // _LP64
fujie@8000 1469
fujie@8000 1470 Label done;
fujie@8000 1471 Label runtime;
fujie@8000 1472
fujie@8000 1473 assert(pre_val != noreg, "check this code");
fujie@8000 1474
fujie@8000 1475 if (obj != noreg) {
fujie@8000 1476 assert_different_registers(obj, pre_val, tmp);
fujie@8000 1477 assert(pre_val != V0, "check this code");
fujie@8000 1478 }
fujie@8000 1479
fujie@8000 1480 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
fujie@8000 1481 PtrQueue::byte_offset_of_active()));
fujie@8000 1482 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
fujie@8000 1483 PtrQueue::byte_offset_of_index()));
fujie@8000 1484 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
fujie@8000 1485 PtrQueue::byte_offset_of_buf()));
fujie@8000 1486
fujie@8000 1487
fujie@8000 1488 // Is marking active?
fujie@8000 1489 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
fujie@8000 1490 lw(AT, in_progress);
fujie@8000 1491 } else {
fujie@8000 1492 assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
fujie@8000 1493 lb(AT, in_progress);
fujie@8000 1494 }
fujie@8000 1495 beq(AT, R0, done);
zhaixiang@9144 1496 delayed()->nop();
fujie@8000 1497
fujie@8000 1498 // Do we need to load the previous value?
fujie@8000 1499 if (obj != noreg) {
fujie@8000 1500 load_heap_oop(pre_val, Address(obj, 0));
fujie@8000 1501 }
fujie@8000 1502
fujie@8000 1503 // Is the previous value null?
fujie@8000 1504 beq(pre_val, R0, done);
zhaixiang@9144 1505 delayed()->nop();
fujie@8000 1506
fujie@8000 1507 // Can we store original value in the thread's buffer?
fujie@8000 1508 // Is index == 0?
fujie@8000 1509 // (The index field is typed as size_t.)
fujie@8000 1510
fujie@8000 1511 ld(tmp, index);
fujie@8000 1512 beq(tmp, R0, runtime);
zhaixiang@9144 1513 delayed()->nop();
fujie@8000 1514
fujie@8000 1515 daddiu(tmp, tmp, -1 * wordSize);
fujie@8000 1516 sd(tmp, index);
fujie@8000 1517 ld(AT, buffer);
fujie@8000 1518 daddu(tmp, tmp, AT);
fujie@8000 1519
fujie@8000 1520 // Record the previous value
fujie@8000 1521 sd(pre_val, tmp, 0);
fujie@8000 1522 beq(R0, R0, done);
zhaixiang@9144 1523 delayed()->nop();
fujie@8000 1524
fujie@8000 1525 bind(runtime);
fujie@8000 1526 // save the live input values
fujie@8006 1527 if (tosca_live) push(V0);
fujie@8006 1528
fujie@8006 1529 if (obj != noreg && obj != V0) push(obj);
fujie@8006 1530
fujie@8006 1531 if (pre_val != V0) push(pre_val);
fujie@8000 1532
fujie@8000 1533 // Calling the runtime using the regular call_VM_leaf mechanism generates
fujie@8000 1534 // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
aoqi@9459 1535 // that checks that the *(fp+frame::interpreter_frame_last_sp) == NULL.
fujie@8000 1536 //
fujie@8000 1537 // If we care generating the pre-barrier without a frame (e.g. in the
aoqi@9459 1538 // intrinsified Reference.get() routine) then fp might be pointing to
fujie@8000 1539 // the caller frame and so this check will most likely fail at runtime.
fujie@8000 1540 //
fujie@8000 1541 // Expanding the call directly bypasses the generation of the check.
fujie@8000 1542 // So when we do not have have a full interpreter frame on the stack
fujie@8000 1543 // expand_call should be passed true.
fujie@8000 1544
fujie@8000 1545 NOT_LP64( push(thread); )
fujie@8000 1546
fujie@8000 1547 if (expand_call) {
fujie@8000 1548 LP64_ONLY( assert(pre_val != A1, "smashed arg"); )
fujie@8000 1549 if (thread != A1) move(A1, thread);
fujie@8000 1550 if (pre_val != A0) move(A0, pre_val);
fujie@8000 1551 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
fujie@8000 1552 } else {
fujie@8000 1553 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
fujie@8000 1554 }
fujie@8000 1555
fujie@8000 1556 NOT_LP64( pop(thread); )
fujie@8000 1557
fujie@8000 1558 // save the live input values
fujie@8000 1559 if (pre_val != V0)
fujie@8000 1560 pop(pre_val);
fujie@8000 1561
fujie@8000 1562 if (obj != noreg && obj != V0)
fujie@8000 1563 pop(obj);
fujie@8000 1564
fujie@8000 1565 if(tosca_live) pop(V0);
fujie@8000 1566
fujie@8000 1567 bind(done);
aoqi@6880 1568 }
aoqi@6880 1569
aoqi@6880 1570 void MacroAssembler::g1_write_barrier_post(Register store_addr,
aoqi@6880 1571 Register new_val,
aoqi@6880 1572 Register thread,
aoqi@6880 1573 Register tmp,
aoqi@6880 1574 Register tmp2) {
fujie@8004 1575 assert(tmp != AT, "must be");
fujie@8004 1576 assert(tmp2 != AT, "must be");
fujie@8000 1577 #ifdef _LP64
fujie@8000 1578 assert(thread == TREG, "must be");
fujie@8000 1579 #endif // _LP64
fujie@8000 1580
fujie@8000 1581 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
fujie@8000 1582 PtrQueue::byte_offset_of_index()));
fujie@8000 1583 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
fujie@8000 1584 PtrQueue::byte_offset_of_buf()));
fujie@8000 1585
fujie@8000 1586 BarrierSet* bs = Universe::heap()->barrier_set();
fujie@8000 1587 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
fujie@8000 1588 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
fujie@8000 1589
fujie@8000 1590 Label done;
fujie@8000 1591 Label runtime;
fujie@8000 1592
fujie@8000 1593 // Does store cross heap regions?
fujie@8000 1594 xorr(AT, store_addr, new_val);
fujie@8000 1595 dsrl(AT, AT, HeapRegion::LogOfHRGrainBytes);
fujie@8000 1596 beq(AT, R0, done);
zhaixiang@9144 1597 delayed()->nop();
aoqi@8009 1598
fujie@8000 1599
fujie@8000 1600 // crosses regions, storing NULL?
fujie@8000 1601 beq(new_val, R0, done);
zhaixiang@9144 1602 delayed()->nop();
fujie@8000 1603
fujie@8000 1604 // storing region crossing non-NULL, is card already dirty?
fujie@8000 1605 const Register card_addr = tmp;
fujie@8000 1606 const Register cardtable = tmp2;
fujie@8000 1607
fujie@8000 1608 move(card_addr, store_addr);
fujie@8000 1609 dsrl(card_addr, card_addr, CardTableModRefBS::card_shift);
fujie@8000 1610 // Do not use ExternalAddress to load 'byte_map_base', since 'byte_map_base' is NOT
fujie@8000 1611 // a valid address and therefore is not properly handled by the relocation code.
fujie@8000 1612 set64(cardtable, (intptr_t)ct->byte_map_base);
fujie@8000 1613 daddu(card_addr, card_addr, cardtable);
fujie@8000 1614
fujie@8000 1615 lb(AT, card_addr, 0);
fujie@8000 1616 daddiu(AT, AT, -1 * (int)G1SATBCardTableModRefBS::g1_young_card_val());
fujie@8000 1617 beq(AT, R0, done);
zhaixiang@9144 1618 delayed()->nop();
fujie@8000 1619
fujie@8000 1620 sync();
fujie@8000 1621 lb(AT, card_addr, 0);
fujie@8000 1622 daddiu(AT, AT, -1 * (int)(int)CardTableModRefBS::dirty_card_val());
fujie@8000 1623 beq(AT, R0, done);
zhaixiang@9144 1624 delayed()->nop();
fujie@8000 1625
fujie@8000 1626
fujie@8000 1627 // storing a region crossing, non-NULL oop, card is clean.
fujie@8000 1628 // dirty card and log.
aoqi@8009 1629 move(AT, (int)CardTableModRefBS::dirty_card_val());
fujie@8000 1630 sb(AT, card_addr, 0);
fujie@8000 1631
fujie@8000 1632 lw(AT, queue_index);
fujie@8000 1633 beq(AT, R0, runtime);
zhaixiang@9144 1634 delayed()->nop();
fujie@8000 1635 daddiu(AT, AT, -1 * wordSize);
fujie@8000 1636 sw(AT, queue_index);
fujie@8000 1637 ld(tmp2, buffer);
fujie@8000 1638 #ifdef _LP64
fujie@8000 1639 ld(AT, queue_index);
fujie@8000 1640 daddu(tmp2, tmp2, AT);
fujie@8000 1641 sd(card_addr, tmp2, 0);
fujie@8000 1642 #else
fujie@8000 1643 lw(AT, queue_index);
fujie@8000 1644 addu32(tmp2, tmp2, AT);
fujie@8000 1645 sw(card_addr, tmp2, 0);
fujie@8000 1646 #endif
fujie@8000 1647 beq(R0, R0, done);
zhaixiang@9144 1648 delayed()->nop();
fujie@8000 1649
fujie@8000 1650 bind(runtime);
fujie@8000 1651 // save the live input values
fujie@8000 1652 push(store_addr);
fujie@8000 1653 push(new_val);
fujie@8000 1654 #ifdef _LP64
fujie@8000 1655 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, TREG);
fujie@8000 1656 #else
fujie@8000 1657 push(thread);
fujie@8000 1658 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
fujie@8000 1659 pop(thread);
fujie@8000 1660 #endif
fujie@8000 1661 pop(new_val);
fujie@8000 1662 pop(store_addr);
fujie@8000 1663
fujie@8000 1664 bind(done);
aoqi@6880 1665 }
aoqi@6880 1666
aoqi@6880 1667 #endif // INCLUDE_ALL_GCS
aoqi@6880 1668 //////////////////////////////////////////////////////////////////////////////////
aoqi@6880 1669
aoqi@6880 1670
aoqi@6880 1671 void MacroAssembler::store_check(Register obj) {
aoqi@6880 1672 // Does a store check for the oop in register obj. The content of
aoqi@6880 1673 // register obj is destroyed afterwards.
aoqi@6880 1674 store_check_part_1(obj);
aoqi@6880 1675 store_check_part_2(obj);
aoqi@6880 1676 }
aoqi@6880 1677
aoqi@6880 1678 void MacroAssembler::store_check(Register obj, Address dst) {
aoqi@6880 1679 store_check(obj);
aoqi@6880 1680 }
aoqi@6880 1681
aoqi@6880 1682
aoqi@6880 1683 // split the store check operation so that other instructions can be scheduled inbetween
aoqi@6880 1684 void MacroAssembler::store_check_part_1(Register obj) {
aoqi@6880 1685 BarrierSet* bs = Universe::heap()->barrier_set();
aoqi@6880 1686 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
aoqi@6880 1687 #ifdef _LP64
aoqi@6880 1688 dsrl(obj, obj, CardTableModRefBS::card_shift);
aoqi@6880 1689 #else
aoqi@6880 1690 shr(obj, CardTableModRefBS::card_shift);
aoqi@6880 1691 #endif
aoqi@6880 1692 }
aoqi@6880 1693
aoqi@6880 1694 void MacroAssembler::store_check_part_2(Register obj) {
aoqi@6880 1695 BarrierSet* bs = Universe::heap()->barrier_set();
aoqi@6880 1696 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
aoqi@6880 1697 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
aoqi@6880 1698 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
aoqi@6880 1699
fujie@8002 1700 set64(AT, (long)ct->byte_map_base);
aoqi@6880 1701 #ifdef _LP64
aoqi@6880 1702 dadd(AT, AT, obj);
aoqi@6880 1703 #else
aoqi@6880 1704 add(AT, AT, obj);
aoqi@6880 1705 #endif
fujie@8002 1706 if (UseConcMarkSweepGC) sync();
aoqi@6880 1707 sb(R0, AT, 0);
aoqi@6880 1708 }
aoqi@6880 1709
aoqi@6880 1710 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
aoqi@6880 1711 void MacroAssembler::tlab_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes,
aoqi@6880 1712 Register t1, Register t2, Label& slow_case) {
aoqi@6880 1713 assert_different_registers(obj, var_size_in_bytes, t1, t2, AT);
aoqi@6880 1714
aoqi@6880 1715 Register end = t2;
aoqi@6880 1716 #ifndef OPT_THREAD
aoqi@6880 1717 Register thread = t1;
aoqi@6880 1718 get_thread(thread);
aoqi@6880 1719 #else
aoqi@6880 1720 Register thread = TREG;
aoqi@6880 1721 #endif
aoqi@6880 1722 verify_tlab(t1, t2);//blows t1&t2
aoqi@6880 1723
aoqi@6880 1724 ld_ptr(obj, thread, in_bytes(JavaThread::tlab_top_offset()));
aoqi@6880 1725
aoqi@6880 1726 if (var_size_in_bytes == NOREG) {
wangxue@9245 1727 set64(AT, con_size_in_bytes);
wangxue@9245 1728 add(end, obj, AT);
aoqi@6880 1729 } else {
aoqi@6880 1730 add(end, obj, var_size_in_bytes);
aoqi@6880 1731 }
aoqi@6880 1732
aoqi@6880 1733 ld_ptr(AT, thread, in_bytes(JavaThread::tlab_end_offset()));
aoqi@6880 1734 sltu(AT, AT, end);
aoqi@6880 1735 bne_far(AT, R0, slow_case);
aoqi@6880 1736 delayed()->nop();
aoqi@6880 1737
aoqi@6880 1738
aoqi@6880 1739 // update the tlab top pointer
aoqi@6880 1740 st_ptr(end, thread, in_bytes(JavaThread::tlab_top_offset()));
aoqi@6880 1741
aoqi@6880 1742 verify_tlab(t1, t2);
aoqi@6880 1743 }
aoqi@6880 1744
aoqi@6880 1745 // Defines obj, preserves var_size_in_bytes
aoqi@6880 1746 void MacroAssembler::eden_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes,
aoqi@6880 1747 Register t1, Register t2, Label& slow_case) {
aoqi@6880 1748 assert_different_registers(obj, var_size_in_bytes, t1, AT);
aoqi@9228 1749 if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
aoqi@6880 1750 // No allocation in the shared eden.
aoqi@6880 1751 b_far(slow_case);
aoqi@6880 1752 delayed()->nop();
aoqi@6880 1753 } else {
aoqi@6880 1754
aoqi@6880 1755 #ifndef _LP64
aoqi@6880 1756 Address heap_top(t1, Assembler::split_low((intptr_t)Universe::heap()->top_addr()));
aoqi@6880 1757 lui(t1, split_high((intptr_t)Universe::heap()->top_addr()));
aoqi@6880 1758 #else
aoqi@6880 1759 Address heap_top(t1);
aoqi@6880 1760 li(t1, (long)Universe::heap()->top_addr());
aoqi@6880 1761 #endif
aoqi@6880 1762 ld_ptr(obj, heap_top);
aoqi@6880 1763
aoqi@6880 1764 Register end = t2;
aoqi@6880 1765 Label retry;
aoqi@6880 1766
aoqi@6880 1767 bind(retry);
aoqi@6880 1768 if (var_size_in_bytes == NOREG) {
wangxue@9245 1769 set64(AT, con_size_in_bytes);
wangxue@9245 1770 add(end, obj, AT);
aoqi@6880 1771 } else {
aoqi@6880 1772 add(end, obj, var_size_in_bytes);
aoqi@6880 1773 }
aoqi@6880 1774 // if end < obj then we wrapped around => object too long => slow case
aoqi@6880 1775 sltu(AT, end, obj);
aoqi@6880 1776 bne_far(AT, R0, slow_case);
aoqi@6880 1777 delayed()->nop();
aoqi@6880 1778
aoqi@6880 1779 li(AT, (long)Universe::heap()->end_addr());
fujie@9152 1780 ld_ptr(AT, AT, 0);
aoqi@6880 1781 sltu(AT, AT, end);
aoqi@6880 1782 bne_far(AT, R0, slow_case);
aoqi@6880 1783 delayed()->nop();
aoqi@6880 1784 // Compare obj with the top addr, and if still equal, store the new top addr in
aoqi@6880 1785 // end at the address of the top addr pointer. Sets ZF if was equal, and clears
aoqi@6880 1786 // it otherwise. Use lock prefix for atomicity on MPs.
aoqi@6880 1787 //if (os::is_MP()) {
aoqi@6880 1788 // sync();
aoqi@6880 1789 //}
aoqi@6880 1790
aoqi@6880 1791 // if someone beat us on the allocation, try again, otherwise continue
aoqi@6880 1792 cmpxchg(end, heap_top, obj);
aoqi@9228 1793 beq_far(AT, R0, retry);
aoqi@6880 1794 delayed()->nop();
aoqi@6880 1795 }
aoqi@6880 1796 }
aoqi@6880 1797
aoqi@6880 1798 // C2 doesn't invoke this one.
aoqi@6880 1799 void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case) {
aoqi@6880 1800 Register top = T0;
aoqi@6880 1801 Register t1 = T1;
aoqi@6880 1802 Register t2 = T9;
aoqi@6880 1803 Register t3 = T3;
aoqi@6880 1804 Register thread_reg = T8;
fujie@9152 1805 assert_different_registers(top, thread_reg, t1, t2, /* preserve: */ T2, A4);
aoqi@6880 1806 Label do_refill, discard_tlab;
fujie@9152 1807
aoqi@9228 1808 if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
aoqi@6880 1809 // No allocation in the shared eden.
aoqi@6880 1810 b(slow_case);
aoqi@6880 1811 delayed()->nop();
aoqi@6880 1812 }
aoqi@6880 1813
aoqi@6880 1814 get_thread(thread_reg);
aoqi@6880 1815
aoqi@6880 1816 ld_ptr(top, thread_reg, in_bytes(JavaThread::tlab_top_offset()));
fujie@9152 1817 ld_ptr(t1, thread_reg, in_bytes(JavaThread::tlab_end_offset()));
aoqi@6880 1818
aoqi@6880 1819 // calculate amount of free space
aoqi@6880 1820 sub(t1, t1, top);
aoqi@6880 1821 shr(t1, LogHeapWordSize);
aoqi@6880 1822
aoqi@6880 1823 // Retain tlab and allocate object in shared space if
aoqi@6880 1824 // the amount free in the tlab is too large to discard.
aoqi@6880 1825 ld_ptr(t2, thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
aoqi@6880 1826 slt(AT, t2, t1);
aoqi@6880 1827 beq(AT, R0, discard_tlab);
aoqi@6880 1828 delayed()->nop();
aoqi@6880 1829
aoqi@6880 1830 // Retain
aoqi@6880 1831 #ifndef _LP64
aoqi@6880 1832 move(AT, ThreadLocalAllocBuffer::refill_waste_limit_increment());
aoqi@6880 1833 #else
aoqi@6880 1834 li(AT, ThreadLocalAllocBuffer::refill_waste_limit_increment());
aoqi@6880 1835 #endif
aoqi@6880 1836 add(t2, t2, AT);
aoqi@6880 1837 st_ptr(t2, thread_reg, in_bytes(JavaThread::tlab_refill_waste_limit_offset()));
aoqi@6880 1838
aoqi@6880 1839 if (TLABStats) {
aoqi@6880 1840 // increment number of slow_allocations
aoqi@6880 1841 lw(AT, thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset()));
aoqi@6880 1842 addiu(AT, AT, 1);
aoqi@6880 1843 sw(AT, thread_reg, in_bytes(JavaThread::tlab_slow_allocations_offset()));
aoqi@6880 1844 }
aoqi@6880 1845 b(try_eden);
aoqi@6880 1846 delayed()->nop();
aoqi@6880 1847
aoqi@6880 1848 bind(discard_tlab);
aoqi@6880 1849 if (TLABStats) {
aoqi@6880 1850 // increment number of refills
aoqi@6880 1851 lw(AT, thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset()));
aoqi@6880 1852 addi(AT, AT, 1);
aoqi@6880 1853 sw(AT, thread_reg, in_bytes(JavaThread::tlab_number_of_refills_offset()));
aoqi@6880 1854 // accumulate wastage -- t1 is amount free in tlab
aoqi@6880 1855 lw(AT, thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
aoqi@6880 1856 add(AT, AT, t1);
aoqi@6880 1857 sw(AT, thread_reg, in_bytes(JavaThread::tlab_fast_refill_waste_offset()));
aoqi@6880 1858 }
aoqi@6880 1859
aoqi@6880 1860 // if tlab is currently allocated (top or end != null) then
aoqi@6880 1861 // fill [top, end + alignment_reserve) with array object
aoqi@6880 1862 beq(top, R0, do_refill);
aoqi@6880 1863 delayed()->nop();
aoqi@6880 1864
aoqi@6880 1865 // set up the mark word
aoqi@6880 1866 li(AT, (long)markOopDesc::prototype()->copy_set_hash(0x2));
aoqi@6880 1867 st_ptr(AT, top, oopDesc::mark_offset_in_bytes());
aoqi@6880 1868
aoqi@6880 1869 // set the length to the remaining space
aoqi@6880 1870 addi(t1, t1, - typeArrayOopDesc::header_size(T_INT));
aoqi@6880 1871 addi(t1, t1, ThreadLocalAllocBuffer::alignment_reserve());
aoqi@6880 1872 shl(t1, log2_intptr(HeapWordSize/sizeof(jint)));
aoqi@6880 1873 sw(t1, top, arrayOopDesc::length_offset_in_bytes());
aoqi@6880 1874
aoqi@6880 1875 // set klass to intArrayKlass
aoqi@6880 1876 #ifndef _LP64
aoqi@6880 1877 lui(AT, split_high((intptr_t)Universe::intArrayKlassObj_addr()));
aoqi@6880 1878 lw(t1, AT, split_low((intptr_t)Universe::intArrayKlassObj_addr()));
aoqi@6880 1879 #else
aoqi@6880 1880 li(AT, (intptr_t)Universe::intArrayKlassObj_addr());
aoqi@6880 1881 ld_ptr(t1, AT, 0);
aoqi@6880 1882 #endif
aoqi@6880 1883 //st_ptr(t1, top, oopDesc::klass_offset_in_bytes());
aoqi@6880 1884 store_klass(top, t1);
aoqi@6880 1885
wangxue@9205 1886 ld_ptr(t1, thread_reg, in_bytes(JavaThread::tlab_start_offset()));
wangxue@9205 1887 subu(t1, top, t1);
wangxue@9205 1888 incr_allocated_bytes(thread_reg, t1, 0);
wangxue@9205 1889
aoqi@6880 1890 // refill the tlab with an eden allocation
aoqi@6880 1891 bind(do_refill);
aoqi@6880 1892 ld_ptr(t1, thread_reg, in_bytes(JavaThread::tlab_size_offset()));
aoqi@6880 1893 shl(t1, LogHeapWordSize);
aoqi@6880 1894 // add object_size ??
aoqi@6880 1895 eden_allocate(top, t1, 0, t2, t3, slow_case);
aoqi@6880 1896
aoqi@6880 1897 // Check that t1 was preserved in eden_allocate.
aoqi@6880 1898 #ifdef ASSERT
aoqi@6880 1899 if (UseTLAB) {
aoqi@6880 1900 Label ok;
aoqi@6880 1901 assert_different_registers(thread_reg, t1);
aoqi@6880 1902 ld_ptr(AT, thread_reg, in_bytes(JavaThread::tlab_size_offset()));
aoqi@6880 1903 shl(AT, LogHeapWordSize);
aoqi@6880 1904 beq(AT, t1, ok);
aoqi@6880 1905 delayed()->nop();
aoqi@6880 1906 stop("assert(t1 != tlab size)");
aoqi@6880 1907 should_not_reach_here();
aoqi@6880 1908
aoqi@6880 1909 bind(ok);
aoqi@6880 1910 }
aoqi@6880 1911 #endif
aoqi@6880 1912 st_ptr(top, thread_reg, in_bytes(JavaThread::tlab_start_offset()));
aoqi@6880 1913 st_ptr(top, thread_reg, in_bytes(JavaThread::tlab_top_offset()));
aoqi@6880 1914 add(top, top, t1);
aoqi@6880 1915 addi(top, top, - ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
aoqi@6880 1916 st_ptr(top, thread_reg, in_bytes(JavaThread::tlab_end_offset()));
aoqi@6880 1917 verify_tlab(t1, t2);
aoqi@6880 1918 b(retry);
aoqi@6880 1919 delayed()->nop();
aoqi@6880 1920 }
aoqi@6880 1921
wangxue@9205 1922 void MacroAssembler::incr_allocated_bytes(Register thread,
wangxue@9205 1923 Register var_size_in_bytes,
wangxue@9205 1924 int con_size_in_bytes,
wangxue@9205 1925 Register t1) {
wangxue@9205 1926 if (!thread->is_valid()) {
wangxue@9205 1927 #ifndef OPT_THREAD
wangxue@9205 1928 assert(t1->is_valid(), "need temp reg");
wangxue@9205 1929 thread = t1;
wangxue@9205 1930 get_thread(thread);
wangxue@9205 1931 #else
wangxue@9205 1932 thread = TREG;
wangxue@9205 1933 #endif
wangxue@9205 1934 }
wangxue@9205 1935
wangxue@9205 1936 ld_ptr(AT, thread, in_bytes(JavaThread::allocated_bytes_offset()));
wangxue@9205 1937 if (var_size_in_bytes->is_valid()) {
wangxue@9205 1938 addu(AT, AT, var_size_in_bytes);
wangxue@9205 1939 } else {
wangxue@9205 1940 addiu(AT, AT, con_size_in_bytes);
wangxue@9205 1941 }
wangxue@9205 1942 st_ptr(AT, thread, in_bytes(JavaThread::allocated_bytes_offset()));
wangxue@9205 1943 }
wangxue@9205 1944
aoqi@6880 1945 static const double pi_4 = 0.7853981633974483;
aoqi@6880 1946
aoqi@6880 1947 // must get argument(a double) in F12/F13
aoqi@6880 1948 //void MacroAssembler::trigfunc(char trig, bool preserve_cpu_regs, int num_fpu_regs_in_use) {
aoqi@9228 1949 //We need to preseve the register which maybe modified during the Call
aoqi@6880 1950 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) {
aoqi@9459 1951 // save all modified register here
aoqi@9459 1952 // FIXME, in the disassembly of tirgfunc, only used V0, V1, T9, SP, RA, so we ony save V0, V1, T9
aoqi@6880 1953 pushad();
aoqi@9459 1954 // we should preserve the stack space before we call
aoqi@6880 1955 addi(SP, SP, -wordSize * 2);
aoqi@9459 1956 switch (trig){
aoqi@6880 1957 case 's' :
aoqi@9459 1958 call( CAST_FROM_FN_PTR(address, SharedRuntime::dsin), relocInfo::runtime_call_type );
aoqi@6880 1959 delayed()->nop();
aoqi@6880 1960 break;
aoqi@6880 1961 case 'c':
aoqi@6880 1962 call( CAST_FROM_FN_PTR(address, SharedRuntime::dcos), relocInfo::runtime_call_type );
aoqi@6880 1963 delayed()->nop();
aoqi@6880 1964 break;
aoqi@6880 1965 case 't':
aoqi@6880 1966 call( CAST_FROM_FN_PTR(address, SharedRuntime::dtan), relocInfo::runtime_call_type );
aoqi@6880 1967 delayed()->nop();
aoqi@6880 1968 break;
aoqi@6880 1969 default:assert (false, "bad intrinsic");
aoqi@6880 1970 break;
aoqi@6880 1971
aoqi@6880 1972 }
aoqi@6880 1973
aoqi@6880 1974 addi(SP, SP, wordSize * 2);
aoqi@6880 1975 popad();
aoqi@6880 1976 }
aoqi@6880 1977
aoqi@6880 1978 #ifdef _LP64
aoqi@6880 1979 void MacroAssembler::li(Register rd, long imm) {
aoqi@6880 1980 if (imm <= max_jint && imm >= min_jint) {
aoqi@6880 1981 li32(rd, (int)imm);
aoqi@6880 1982 } else if (julong(imm) <= 0xFFFFFFFF) {
aoqi@6880 1983 assert_not_delayed();
aoqi@6880 1984 // lui sign-extends, so we can't use that.
aoqi@6880 1985 ori(rd, R0, julong(imm) >> 16);
aoqi@6880 1986 dsll(rd, rd, 16);
aoqi@6880 1987 ori(rd, rd, split_low(imm));
aoqi@6880 1988 } else if ((imm > 0) && is_simm16(imm >> 32)) {
aoqi@9459 1989 // A 48-bit address
aoqi@6880 1990 li48(rd, imm);
aoqi@6880 1991 } else {
aoqi@6880 1992 li64(rd, imm);
aoqi@6880 1993 }
aoqi@6880 1994 }
aoqi@6880 1995 #else
aoqi@6880 1996 void MacroAssembler::li(Register rd, long imm) {
aoqi@6880 1997 li32(rd, (int)imm);
aoqi@6880 1998 }
aoqi@6880 1999 #endif
aoqi@6880 2000
aoqi@6880 2001 void MacroAssembler::li32(Register reg, int imm) {
aoqi@6880 2002 if (is_simm16(imm)) {
aoqi@9459 2003 // for imm < 0, we should use addi instead of addiu.
aoqi@9459 2004 //
aoqi@9459 2005 // java.lang.StringCoding$StringDecoder.decode(jobject, jint, jint)
aoqi@9459 2006 //
aoqi@9459 2007 // 78 move [int:-1|I] [a0|I]
aoqi@9459 2008 // : daddi a0, zero, 0xffffffff (correct)
aoqi@9459 2009 // : daddiu a0, zero, 0xffffffff (incorrect)
aoqi@9459 2010 //
aoqi@6880 2011 if (imm >= 0)
aoqi@6880 2012 addiu(reg, R0, imm);
aoqi@6880 2013 else
aoqi@6880 2014 addi(reg, R0, imm);
aoqi@6880 2015 } else {
aoqi@6880 2016 lui(reg, split_low(imm >> 16));
aoqi@6880 2017 if (split_low(imm))
aoqi@6880 2018 ori(reg, reg, split_low(imm));
aoqi@6880 2019 }
aoqi@6880 2020 }
aoqi@6880 2021
aoqi@6880 2022 #ifdef _LP64
aoqi@6880 2023 void MacroAssembler::set64(Register d, jlong value) {
aoqi@6880 2024 assert_not_delayed();
aoqi@6880 2025
aoqi@6880 2026 int hi = (int)(value >> 32);
aoqi@6880 2027 int lo = (int)(value & ~0);
aoqi@6880 2028
aoqi@6880 2029 if (value == lo) { // 32-bit integer
aoqi@6880 2030 if (is_simm16(value)) {
aoqi@6880 2031 daddiu(d, R0, value);
aoqi@6880 2032 } else {
aoqi@6880 2033 lui(d, split_low(value >> 16));
aoqi@6880 2034 if (split_low(value)) {
aoqi@6880 2035 ori(d, d, split_low(value));
aoqi@6880 2036 }
aoqi@6880 2037 }
aoqi@6880 2038 } else if (hi == 0) { // hardware zero-extends to upper 32
aoqi@6880 2039 ori(d, R0, julong(value) >> 16);
aoqi@6880 2040 dsll(d, d, 16);
aoqi@6880 2041 if (split_low(value)) {
aoqi@6880 2042 ori(d, d, split_low(value));
aoqi@6880 2043 }
aoqi@6880 2044 } else if ((value> 0) && is_simm16(value >> 32)) { // li48
aoqi@6880 2045 // 4 insts
aoqi@6880 2046 li48(d, value);
aoqi@6880 2047 } else { // li64
aoqi@6880 2048 // 6 insts
aoqi@6880 2049 li64(d, value);
aoqi@6880 2050 }
aoqi@6880 2051 }
aoqi@6880 2052
aoqi@6880 2053
aoqi@6880 2054 int MacroAssembler::insts_for_set64(jlong value) {
aoqi@6880 2055 int hi = (int)(value >> 32);
aoqi@6880 2056 int lo = (int)(value & ~0);
aoqi@6880 2057
aoqi@6880 2058 int count = 0;
aoqi@6880 2059
aoqi@6880 2060 if (value == lo) { // 32-bit integer
aoqi@6880 2061 if (is_simm16(value)) {
aoqi@6880 2062 //daddiu(d, R0, value);
aoqi@6880 2063 count++;
aoqi@6880 2064 } else {
aoqi@6880 2065 //lui(d, split_low(value >> 16));
aoqi@6880 2066 count++;
aoqi@6880 2067 if (split_low(value)) {
aoqi@6880 2068 //ori(d, d, split_low(value));
aoqi@6880 2069 count++;
aoqi@6880 2070 }
aoqi@6880 2071 }
aoqi@6880 2072 } else if (hi == 0) { // hardware zero-extends to upper 32
aoqi@6880 2073 //ori(d, R0, julong(value) >> 16);
aoqi@6880 2074 //dsll(d, d, 16);
aoqi@6880 2075 count += 2;
aoqi@6880 2076 if (split_low(value)) {
aoqi@6880 2077 //ori(d, d, split_low(value));
aoqi@6880 2078 count++;
aoqi@6880 2079 }
aoqi@6880 2080 } else if ((value> 0) && is_simm16(value >> 32)) { // li48
aoqi@6880 2081 // 4 insts
aoqi@6880 2082 //li48(d, value);
aoqi@6880 2083 count += 4;
aoqi@6880 2084 } else { // li64
aoqi@6880 2085 // 6 insts
aoqi@6880 2086 //li64(d, value);
aoqi@6880 2087 count += 6;
aoqi@6880 2088 }
aoqi@6880 2089
aoqi@6880 2090 return count;
aoqi@6880 2091 }
aoqi@6880 2092
aoqi@6880 2093 void MacroAssembler::patchable_set48(Register d, jlong value) {
aoqi@6880 2094 assert_not_delayed();
aoqi@6880 2095
aoqi@6880 2096 int hi = (int)(value >> 32);
aoqi@6880 2097 int lo = (int)(value & ~0);
aoqi@6880 2098
aoqi@6880 2099 int count = 0;
aoqi@6880 2100
aoqi@6880 2101 if (value == lo) { // 32-bit integer
aoqi@6880 2102 if (is_simm16(value)) {
aoqi@6880 2103 daddiu(d, R0, value);
aoqi@6880 2104 count += 1;
aoqi@6880 2105 } else {
aoqi@6880 2106 lui(d, split_low(value >> 16));
aoqi@6880 2107 count += 1;
aoqi@6880 2108 if (split_low(value)) {
aoqi@6880 2109 ori(d, d, split_low(value));
aoqi@6880 2110 count += 1;
aoqi@6880 2111 }
aoqi@6880 2112 }
aoqi@6880 2113 } else if (hi == 0) { // hardware zero-extends to upper 32
aoqi@6880 2114 ori(d, R0, julong(value) >> 16);
aoqi@6880 2115 dsll(d, d, 16);
aoqi@6880 2116 count += 2;
aoqi@6880 2117 if (split_low(value)) {
aoqi@6880 2118 ori(d, d, split_low(value));
aoqi@6880 2119 count += 1;
aoqi@6880 2120 }
aoqi@6880 2121 } else if ((value> 0) && is_simm16(value >> 32)) { // li48
aoqi@6880 2122 // 4 insts
aoqi@6880 2123 li48(d, value);
aoqi@6880 2124 count += 4;
aoqi@6880 2125 } else { // li64
aoqi@6880 2126 tty->print_cr("value = 0x%x", value);
aoqi@6880 2127 guarantee(false, "Not supported yet !");
aoqi@6880 2128 }
aoqi@6880 2129
fujie@9242 2130 while (count < 4) {
aoqi@6880 2131 nop();
fujie@9242 2132 count++;
aoqi@6880 2133 }
aoqi@6880 2134 }
aoqi@6880 2135
aoqi@6880 2136 void MacroAssembler::patchable_set32(Register d, jlong value) {
aoqi@6880 2137 assert_not_delayed();
aoqi@6880 2138
aoqi@6880 2139 int hi = (int)(value >> 32);
aoqi@6880 2140 int lo = (int)(value & ~0);
aoqi@6880 2141
aoqi@6880 2142 int count = 0;
aoqi@6880 2143
aoqi@6880 2144 if (value == lo) { // 32-bit integer
aoqi@6880 2145 if (is_simm16(value)) {
aoqi@6880 2146 daddiu(d, R0, value);
aoqi@6880 2147 count += 1;
aoqi@6880 2148 } else {
aoqi@6880 2149 lui(d, split_low(value >> 16));
aoqi@6880 2150 count += 1;
aoqi@6880 2151 if (split_low(value)) {
aoqi@6880 2152 ori(d, d, split_low(value));
aoqi@6880 2153 count += 1;
aoqi@6880 2154 }
aoqi@6880 2155 }
aoqi@6880 2156 } else if (hi == 0) { // hardware zero-extends to upper 32
aoqi@6880 2157 ori(d, R0, julong(value) >> 16);
aoqi@6880 2158 dsll(d, d, 16);
aoqi@6880 2159 count += 2;
aoqi@6880 2160 if (split_low(value)) {
aoqi@6880 2161 ori(d, d, split_low(value));
aoqi@6880 2162 count += 1;
aoqi@6880 2163 }
aoqi@6880 2164 } else {
aoqi@6880 2165 tty->print_cr("value = 0x%x", value);
aoqi@6880 2166 guarantee(false, "Not supported yet !");
aoqi@6880 2167 }
aoqi@6880 2168
fujie@9242 2169 while (count < 3) {
aoqi@6880 2170 nop();
fujie@9242 2171 count++;
aoqi@6880 2172 }
aoqi@6880 2173 }
aoqi@6880 2174
aoqi@6880 2175 void MacroAssembler::patchable_call32(Register d, jlong value) {
aoqi@6880 2176 assert_not_delayed();
aoqi@6880 2177
aoqi@6880 2178 int hi = (int)(value >> 32);
aoqi@6880 2179 int lo = (int)(value & ~0);
aoqi@6880 2180
aoqi@6880 2181 int count = 0;
aoqi@6880 2182
aoqi@6880 2183 if (value == lo) { // 32-bit integer
aoqi@6880 2184 if (is_simm16(value)) {
aoqi@6880 2185 daddiu(d, R0, value);
aoqi@6880 2186 count += 1;
aoqi@6880 2187 } else {
aoqi@6880 2188 lui(d, split_low(value >> 16));
aoqi@6880 2189 count += 1;
aoqi@6880 2190 if (split_low(value)) {
aoqi@6880 2191 ori(d, d, split_low(value));
aoqi@6880 2192 count += 1;
aoqi@6880 2193 }
aoqi@6880 2194 }
aoqi@6880 2195 } else {
aoqi@6880 2196 tty->print_cr("value = 0x%x", value);
aoqi@6880 2197 guarantee(false, "Not supported yet !");
aoqi@6880 2198 }
aoqi@6880 2199
fujie@9242 2200 while (count < 2) {
aoqi@6880 2201 nop();
fujie@9242 2202 count++;
aoqi@6880 2203 }
aoqi@6880 2204 }
aoqi@6880 2205
aoqi@6880 2206 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
aoqi@6880 2207 assert(UseCompressedClassPointers, "should only be used for compressed header");
aoqi@6880 2208 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
aoqi@6880 2209
aoqi@6880 2210 int klass_index = oop_recorder()->find_index(k);
aoqi@6880 2211 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
aoqi@6880 2212 long narrowKlass = (long)Klass::encode_klass(k);
aoqi@6880 2213
aoqi@6880 2214 relocate(rspec, Assembler::narrow_oop_operand);
aoqi@6880 2215 patchable_set48(dst, narrowKlass);
aoqi@6880 2216 }
aoqi@6880 2217
aoqi@6880 2218
aoqi@6880 2219 void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
aoqi@6880 2220 assert(UseCompressedOops, "should only be used for compressed header");
aoqi@6880 2221 assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
aoqi@6880 2222
aoqi@6880 2223 int oop_index = oop_recorder()->find_index(obj);
aoqi@6880 2224 RelocationHolder rspec = oop_Relocation::spec(oop_index);
aoqi@6880 2225
aoqi@6880 2226 relocate(rspec, Assembler::narrow_oop_operand);
aoqi@6880 2227 patchable_set48(dst, oop_index);
aoqi@6880 2228 }
aoqi@6880 2229
aoqi@6880 2230 void MacroAssembler::li64(Register rd, long imm) {
aoqi@6880 2231 assert_not_delayed();
fujie@9263 2232 lui(rd, split_low(imm >> 48));
aoqi@6880 2233 ori(rd, rd, split_low(imm >> 32));
aoqi@6880 2234 dsll(rd, rd, 16);
aoqi@6880 2235 ori(rd, rd, split_low(imm >> 16));
aoqi@6880 2236 dsll(rd, rd, 16);
aoqi@6880 2237 ori(rd, rd, split_low(imm));
aoqi@6880 2238 }
aoqi@6880 2239
aoqi@6880 2240 void MacroAssembler::li48(Register rd, long imm) {
aoqi@6880 2241 assert_not_delayed();
aoqi@6880 2242 assert(is_simm16(imm >> 32), "Not a 48-bit address");
aoqi@6880 2243 lui(rd, imm >> 32);
aoqi@6880 2244 ori(rd, rd, split_low(imm >> 16));
aoqi@6880 2245 dsll(rd, rd, 16);
aoqi@6880 2246 ori(rd, rd, split_low(imm));
aoqi@6880 2247 }
aoqi@6880 2248 #endif
aoqi@9459 2249
aoqi@6880 2250 void MacroAssembler::verify_oop(Register reg, const char* s) {
aoqi@6880 2251 if (!VerifyOops) return;
aoqi@6880 2252 const char * b = NULL;
aoqi@6880 2253 stringStream ss;
aoqi@6880 2254 ss.print("verify_oop: %s: %s", reg->name(), s);
aoqi@6880 2255 b = code_string(ss.as_string());
aoqi@6880 2256 #ifdef _LP64
aoqi@6880 2257 pushad();
aoqi@6880 2258 move(A1, reg);
aoqi@6880 2259 li(A0, (long)b);
aoqi@6880 2260 li(AT, (long)StubRoutines::verify_oop_subroutine_entry_address());
aoqi@6880 2261 ld(T9, AT, 0);
aoqi@6880 2262 jalr(T9);
aoqi@6880 2263 delayed()->nop();
aoqi@6880 2264 popad();
aoqi@6880 2265 #else
aoqi@6880 2266 // Pass register number to verify_oop_subroutine
aoqi@6880 2267 sw(T0, SP, - wordSize);
aoqi@6880 2268 sw(T1, SP, - 2*wordSize);
aoqi@6880 2269 sw(RA, SP, - 3*wordSize);
aoqi@6880 2270 sw(A0, SP ,- 4*wordSize);
aoqi@6880 2271 sw(A1, SP ,- 5*wordSize);
aoqi@6880 2272 sw(AT, SP ,- 6*wordSize);
aoqi@6880 2273 sw(T9, SP ,- 7*wordSize);
aoqi@6880 2274 addiu(SP, SP, - 7 * wordSize);
aoqi@6880 2275 move(A1, reg);
aoqi@6880 2276 li(A0, (long)b);
aoqi@6880 2277 // call indirectly to solve generation ordering problem
aoqi@6880 2278 li(AT, (long)StubRoutines::verify_oop_subroutine_entry_address());
aoqi@6880 2279 lw(T9, AT, 0);
aoqi@6880 2280 jalr(T9);
aoqi@6880 2281 delayed()->nop();
aoqi@6880 2282 lw(T0, SP, 6* wordSize);
aoqi@6880 2283 lw(T1, SP, 5* wordSize);
aoqi@6880 2284 lw(RA, SP, 4* wordSize);
aoqi@6880 2285 lw(A0, SP, 3* wordSize);
aoqi@6880 2286 lw(A1, SP, 2* wordSize);
aoqi@6880 2287 lw(AT, SP, 1* wordSize);
aoqi@6880 2288 lw(T9, SP, 0* wordSize);
aoqi@6880 2289 addiu(SP, SP, 7 * wordSize);
aoqi@6880 2290 #endif
aoqi@6880 2291 }
aoqi@6880 2292
aoqi@6880 2293
aoqi@6880 2294 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
aoqi@6880 2295 if (!VerifyOops) {
aoqi@6880 2296 nop();
aoqi@6880 2297 return;
aoqi@6880 2298 }
aoqi@6880 2299 // Pass register number to verify_oop_subroutine
aoqi@6880 2300 const char * b = NULL;
aoqi@6880 2301 stringStream ss;
aoqi@6880 2302 ss.print("verify_oop_addr: %s", s);
aoqi@6880 2303 b = code_string(ss.as_string());
aoqi@6880 2304
aoqi@6880 2305 st_ptr(T0, SP, - wordSize);
aoqi@6880 2306 st_ptr(T1, SP, - 2*wordSize);
aoqi@6880 2307 st_ptr(RA, SP, - 3*wordSize);
aoqi@6880 2308 st_ptr(A0, SP, - 4*wordSize);
aoqi@6880 2309 st_ptr(A1, SP, - 5*wordSize);
aoqi@6880 2310 st_ptr(AT, SP, - 6*wordSize);
aoqi@6880 2311 st_ptr(T9, SP, - 7*wordSize);
aoqi@6880 2312 ld_ptr(A1, addr); // addr may use SP, so load from it before change SP
aoqi@6880 2313 addiu(SP, SP, - 7 * wordSize);
aoqi@6880 2314
aoqi@6880 2315 li(A0, (long)b);
aoqi@6880 2316 // call indirectly to solve generation ordering problem
aoqi@6880 2317 li(AT, (long)StubRoutines::verify_oop_subroutine_entry_address());
aoqi@6880 2318 ld_ptr(T9, AT, 0);
aoqi@6880 2319 jalr(T9);
aoqi@6880 2320 delayed()->nop();
aoqi@6880 2321 ld_ptr(T0, SP, 6* wordSize);
aoqi@6880 2322 ld_ptr(T1, SP, 5* wordSize);
aoqi@6880 2323 ld_ptr(RA, SP, 4* wordSize);
aoqi@6880 2324 ld_ptr(A0, SP, 3* wordSize);
aoqi@6880 2325 ld_ptr(A1, SP, 2* wordSize);
aoqi@6880 2326 ld_ptr(AT, SP, 1* wordSize);
aoqi@6880 2327 ld_ptr(T9, SP, 0* wordSize);
aoqi@6880 2328 addiu(SP, SP, 7 * wordSize);
aoqi@6880 2329 }
aoqi@6880 2330
aoqi@6880 2331 // used registers : T0, T1
aoqi@6880 2332 void MacroAssembler::verify_oop_subroutine() {
aoqi@6880 2333 // RA: ra
aoqi@6880 2334 // A0: char* error message
aoqi@6880 2335 // A1: oop object to verify
aoqi@6880 2336
aoqi@6880 2337 Label exit, error;
aoqi@6880 2338 // increment counter
aoqi@6880 2339 li(T0, (long)StubRoutines::verify_oop_count_addr());
aoqi@6880 2340 lw(AT, T0, 0);
aoqi@6880 2341 #ifdef _LP64
aoqi@6880 2342 daddi(AT, AT, 1);
aoqi@6880 2343 #else
aoqi@6880 2344 addi(AT, AT, 1);
aoqi@6880 2345 #endif
aoqi@6880 2346 sw(AT, T0, 0);
aoqi@6880 2347
aoqi@6880 2348 // make sure object is 'reasonable'
aoqi@6880 2349 beq(A1, R0, exit); // if obj is NULL it is ok
aoqi@6880 2350 delayed()->nop();
aoqi@6880 2351
aoqi@6880 2352 // Check if the oop is in the right area of memory
aoqi@9459 2353 // const int oop_mask = Universe::verify_oop_mask();
aoqi@9459 2354 // const int oop_bits = Universe::verify_oop_bits();
aoqi@6880 2355 const uintptr_t oop_mask = Universe::verify_oop_mask();
aoqi@6880 2356 const uintptr_t oop_bits = Universe::verify_oop_bits();
aoqi@6880 2357 li(AT, oop_mask);
aoqi@6880 2358 andr(T0, A1, AT);
aoqi@6880 2359 li(AT, oop_bits);
aoqi@6880 2360 bne(T0, AT, error);
aoqi@6880 2361 delayed()->nop();
aoqi@6880 2362
aoqi@6880 2363 // make sure klass is 'reasonable'
aoqi@9459 2364 // add for compressedoops
aoqi@6880 2365 reinit_heapbase();
aoqi@9459 2366 // add for compressedoops
aoqi@6880 2367 load_klass(T0, A1);
aoqi@6880 2368 beq(T0, R0, error); // if klass is NULL it is broken
aoqi@6880 2369 delayed()->nop();
aoqi@6880 2370 // return if everything seems ok
aoqi@6880 2371 bind(exit);
aoqi@6880 2372
aoqi@6880 2373 jr(RA);
aoqi@6880 2374 delayed()->nop();
aoqi@6880 2375
aoqi@6880 2376 // handle errors
aoqi@6880 2377 bind(error);
aoqi@6880 2378 pushad();
aoqi@6880 2379 #ifndef _LP64
aoqi@6880 2380 addi(SP, SP, (-1) * wordSize);
aoqi@6880 2381 #endif
aoqi@6880 2382 call(CAST_FROM_FN_PTR(address, MacroAssembler::debug), relocInfo::runtime_call_type);
aoqi@6880 2383 delayed()->nop();
aoqi@6880 2384 #ifndef _LP64
aoqi@6880 2385 addiu(SP, SP, 1 * wordSize);
aoqi@6880 2386 #endif
aoqi@6880 2387 popad();
aoqi@6880 2388 jr(RA);
aoqi@6880 2389 delayed()->nop();
aoqi@6880 2390 }
aoqi@6880 2391
aoqi@6880 2392 void MacroAssembler::verify_tlab(Register t1, Register t2) {
aoqi@6880 2393 #ifdef ASSERT
aoqi@6880 2394 assert_different_registers(t1, t2, AT);
aoqi@6880 2395 if (UseTLAB && VerifyOops) {
aoqi@6880 2396 Label next, ok;
aoqi@6880 2397
aoqi@6880 2398 get_thread(t1);
aoqi@6880 2399
aoqi@6880 2400 ld_ptr(t2, t1, in_bytes(JavaThread::tlab_top_offset()));
aoqi@6880 2401 ld_ptr(AT, t1, in_bytes(JavaThread::tlab_start_offset()));
aoqi@6880 2402 sltu(AT, t2, AT);
aoqi@6880 2403 beq(AT, R0, next);
aoqi@6880 2404 delayed()->nop();
aoqi@6880 2405
aoqi@6880 2406 stop("assert(top >= start)");
aoqi@6880 2407
aoqi@6880 2408 bind(next);
aoqi@6880 2409 ld_ptr(AT, t1, in_bytes(JavaThread::tlab_end_offset()));
aoqi@6880 2410 sltu(AT, AT, t2);
aoqi@6880 2411 beq(AT, R0, ok);
aoqi@6880 2412 delayed()->nop();
aoqi@6880 2413
aoqi@6880 2414 stop("assert(top <= end)");
aoqi@6880 2415
aoqi@6880 2416 bind(ok);
aoqi@6880 2417
aoqi@6880 2418 }
aoqi@6880 2419 #endif
aoqi@6880 2420 }
aoqi@9459 2421
aoqi@9459 2422 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
aoqi@6880 2423 Register tmp,
aoqi@6880 2424 int offset) {
aoqi@9459 2425 intptr_t value = *delayed_value_addr;
aoqi@9459 2426 if (value != 0)
aoqi@9459 2427 return RegisterOrConstant(value + offset);
aoqi@9459 2428 AddressLiteral a(delayed_value_addr);
aoqi@9459 2429 // load indirectly to solve generation ordering problem
aoqi@9459 2430 //movptr(tmp, ExternalAddress((address) delayed_value_addr));
aoqi@9459 2431 //ld(tmp, a);
aoqi@9459 2432 if (offset != 0)
aoqi@9459 2433 daddi(tmp,tmp, offset);
aoqi@9459 2434
aoqi@9459 2435 return RegisterOrConstant(tmp);
aoqi@9459 2436 }
aoqi@6880 2437
aoqi@6880 2438 void MacroAssembler::hswap(Register reg) {
aoqi@6880 2439 //short
aoqi@6880 2440 //andi(reg, reg, 0xffff);
aoqi@6880 2441 srl(AT, reg, 8);
aoqi@6880 2442 sll(reg, reg, 24);
aoqi@6880 2443 sra(reg, reg, 16);
aoqi@6880 2444 orr(reg, reg, AT);
aoqi@6880 2445 }
aoqi@6880 2446
aoqi@6880 2447 void MacroAssembler::huswap(Register reg) {
aoqi@6880 2448 #ifdef _LP64
aoqi@6880 2449 dsrl(AT, reg, 8);
aoqi@6880 2450 dsll(reg, reg, 24);
aoqi@6880 2451 dsrl(reg, reg, 16);
aoqi@6880 2452 orr(reg, reg, AT);
aoqi@6880 2453 andi(reg, reg, 0xffff);
aoqi@6880 2454 #else
aoqi@6880 2455 //andi(reg, reg, 0xffff);
aoqi@6880 2456 srl(AT, reg, 8);
aoqi@6880 2457 sll(reg, reg, 24);
aoqi@6880 2458 srl(reg, reg, 16);
aoqi@6880 2459 orr(reg, reg, AT);
aoqi@6880 2460 #endif
aoqi@6880 2461 }
aoqi@6880 2462
aoqi@6880 2463 // something funny to do this will only one more register AT
aoqi@6880 2464 // 32 bits
aoqi@6880 2465 void MacroAssembler::swap(Register reg) {
aoqi@6880 2466 srl(AT, reg, 8);
aoqi@6880 2467 sll(reg, reg, 24);
aoqi@6880 2468 orr(reg, reg, AT);
aoqi@6880 2469 //reg : 4 1 2 3
aoqi@6880 2470 srl(AT, AT, 16);
aoqi@6880 2471 xorr(AT, AT, reg);
aoqi@6880 2472 andi(AT, AT, 0xff);
aoqi@6880 2473 //AT : 0 0 0 1^3);
aoqi@6880 2474 xorr(reg, reg, AT);
aoqi@6880 2475 //reg : 4 1 2 1
aoqi@6880 2476 sll(AT, AT, 16);
aoqi@6880 2477 xorr(reg, reg, AT);
aoqi@6880 2478 //reg : 4 3 2 1
aoqi@6880 2479 }
aoqi@6880 2480
aoqi@6880 2481 #ifdef _LP64
aoqi@6880 2482
aoqi@9459 2483 // do 32-bit CAS using MIPS64 lld/scd
aoqi@9459 2484 //
aoqi@9459 2485 // cas_int should only compare 32-bits of the memory value.
aoqi@9459 2486 // However, lld/scd will do 64-bit operation, which violates the intention of cas_int.
aoqi@9459 2487 // To simulate a 32-bit atomic operation, the value loaded with LLD should be split into
aoqi@9459 2488 // tow halves, and only the low-32 bits is compared. If equals, the low-32 bits of newval,
aoqi@9459 2489 // plus the high-32 bits or memory value, are stored togethor with SCD.
aoqi@9459 2490 //
aoqi@9459 2491 //Example:
aoqi@9459 2492 //
aoqi@9459 2493 // double d = 3.1415926;
aoqi@9459 2494 // System.err.println("hello" + d);
aoqi@9459 2495 //
aoqi@9459 2496 // sun.misc.FloatingDecimal$1.<init>()
aoqi@9459 2497 // |
aoqi@9459 2498 // `- java.util.concurrent.atomic.AtomicInteger::compareAndSet()
aoqi@9459 2499 //
aoqi@9459 2500 // 38 cas_int [a7a7|J] [a0|I] [a6|I]
aoqi@9459 2501 // a0: 0xffffffffe8ea9f63 pc: 0x55647f3354
aoqi@9459 2502 // a6: 0x4ab325aa
aoqi@9459 2503 //
aoqi@9459 2504 //again:
aoqi@9459 2505 // 0x00000055647f3c5c: lld at, 0x0(a7) ; 64-bit load, "0xe8ea9f63"
aoqi@9459 2506 //
aoqi@9459 2507 // 0x00000055647f3c60: sll t9, at, 0 ; t9: low-32 bits (sign extended)
aoqi@9459 2508 // 0x00000055647f3c64: dsrl32 t8, at, 0 ; t8: high-32 bits
aoqi@9459 2509 // 0x00000055647f3c68: dsll32 t8, t8, 0
aoqi@9459 2510 // 0x00000055647f3c6c: bne t9, a0, 0x00000055647f3c9c ; goto nequal
aoqi@9459 2511 // 0x00000055647f3c70: sll zero, zero, 0
aoqi@9459 2512 //
aoqi@9459 2513 // 0x00000055647f3c74: ori v1, zero, 0xffffffff ; v1: low-32 bits of newval (sign unextended)
aoqi@9459 2514 // 0x00000055647f3c78: dsll v1, v1, 16 ; v1 = a6 & 0xFFFFFFFF;
aoqi@9459 2515 // 0x00000055647f3c7c: ori v1, v1, 0xffffffff
aoqi@9459 2516 // 0x00000055647f3c80: and v1, a6, v1
aoqi@9459 2517 // 0x00000055647f3c84: or at, t8, v1
aoqi@9459 2518 // 0x00000055647f3c88: scd at, 0x0(a7)
aoqi@9459 2519 // 0x00000055647f3c8c: beq at, zero, 0x00000055647f3c5c ; goto again
aoqi@9459 2520 // 0x00000055647f3c90: sll zero, zero, 0
aoqi@9459 2521 // 0x00000055647f3c94: beq zero, zero, 0x00000055647f45ac ; goto done
aoqi@9459 2522 // 0x00000055647f3c98: sll zero, zero, 0
aoqi@9459 2523 //nequal:
aoqi@9459 2524 // 0x00000055647f45a4: dadd a0, t9, zero
aoqi@9459 2525 // 0x00000055647f45a8: dadd at, zero, zero
aoqi@9459 2526 //done:
aoqi@9459 2527 //
aoqi@6880 2528
aoqi@6880 2529 void MacroAssembler::cmpxchg32(Register x_reg, Address dest, Register c_reg) {
aoqi@9459 2530 // MIPS64 can use ll/sc for 32-bit atomic memory access
aoqi@6880 2531 Label done, again, nequal;
aoqi@6880 2532
aoqi@6880 2533 bind(again);
aoqi@6880 2534
aoqi@9808 2535 if (UseSyncLevel >= 10000 || UseSyncLevel == 1000 || UseSyncLevel == 4000) sync();
aoqi@6880 2536 ll(AT, dest);
aoqi@6880 2537 bne(AT, c_reg, nequal);
aoqi@6880 2538 delayed()->nop();
aoqi@6880 2539
aoqi@6880 2540 move(AT, x_reg);
aoqi@6880 2541 sc(AT, dest);
aoqi@6880 2542 beq(AT, R0, again);
aoqi@6880 2543 delayed()->nop();
aoqi@6880 2544 b(done);
aoqi@6880 2545 delayed()->nop();
aoqi@6880 2546
aoqi@6880 2547 // not xchged
aoqi@6880 2548 bind(nequal);
aoqi@6880 2549 sync();
aoqi@6880 2550 move(c_reg, AT);
aoqi@6880 2551 move(AT, R0);
aoqi@6880 2552
aoqi@6880 2553 bind(done);
aoqi@6880 2554 }
aoqi@6880 2555 #endif // cmpxchg32
aoqi@6880 2556
aoqi@6880 2557 void MacroAssembler::cmpxchg(Register x_reg, Address dest, Register c_reg) {
aoqi@6880 2558 Label done, again, nequal;
aoqi@6880 2559
aoqi@6880 2560 bind(again);
aoqi@9808 2561 if (UseSyncLevel >= 10000 || UseSyncLevel == 1000 || UseSyncLevel == 4000) sync();
aoqi@6880 2562 #ifdef _LP64
aoqi@6880 2563 lld(AT, dest);
aoqi@6880 2564 #else
aoqi@6880 2565 ll(AT, dest);
aoqi@6880 2566 #endif
aoqi@6880 2567 bne(AT, c_reg, nequal);
aoqi@6880 2568 delayed()->nop();
aoqi@6880 2569
aoqi@6880 2570 move(AT, x_reg);
aoqi@6880 2571 #ifdef _LP64
aoqi@6880 2572 scd(AT, dest);
aoqi@6880 2573 #else
aoqi@6880 2574 sc(AT, dest);
aoqi@6880 2575 #endif
aoqi@6880 2576 beq(AT, R0, again);
aoqi@6880 2577 delayed()->nop();
aoqi@6880 2578 b(done);
aoqi@6880 2579 delayed()->nop();
aoqi@6880 2580
aoqi@6880 2581 // not xchged
aoqi@6880 2582 bind(nequal);
aoqi@6880 2583 sync();
aoqi@6880 2584 move(c_reg, AT);
aoqi@6880 2585 move(AT, R0);
aoqi@6880 2586
aoqi@6880 2587 bind(done);
aoqi@6880 2588 }
aoqi@6880 2589
aoqi@6880 2590 void MacroAssembler::cmpxchg8(Register x_regLo, Register x_regHi, Address dest, Register c_regLo, Register c_regHi) {
aoqi@6880 2591 Label done, again, nequal;
aoqi@6880 2592
aoqi@6880 2593 Register x_reg = x_regLo;
aoqi@6880 2594 dsll32(x_regHi, x_regHi, 0);
aoqi@6880 2595 dsll32(x_regLo, x_regLo, 0);
aoqi@6880 2596 dsrl32(x_regLo, x_regLo, 0);
aoqi@6880 2597 orr(x_reg, x_regLo, x_regHi);
aoqi@6880 2598
aoqi@6880 2599 Register c_reg = c_regLo;
aoqi@6880 2600 dsll32(c_regHi, c_regHi, 0);
aoqi@6880 2601 dsll32(c_regLo, c_regLo, 0);
aoqi@6880 2602 dsrl32(c_regLo, c_regLo, 0);
aoqi@6880 2603 orr(c_reg, c_regLo, c_regHi);
aoqi@6880 2604
aoqi@6880 2605 bind(again);
aoqi@6880 2606
aoqi@9808 2607 if (UseSyncLevel >= 10000 || UseSyncLevel == 1000 || UseSyncLevel == 4000) sync();
aoqi@6880 2608 lld(AT, dest);
aoqi@6880 2609 bne(AT, c_reg, nequal);
aoqi@6880 2610 delayed()->nop();
aoqi@6880 2611
aoqi@6880 2612 //move(AT, x_reg);
aoqi@6880 2613 dadd(AT, x_reg, R0);
aoqi@6880 2614 scd(AT, dest);
aoqi@6880 2615 beq(AT, R0, again);
aoqi@6880 2616 delayed()->nop();
aoqi@6880 2617 b(done);
aoqi@6880 2618 delayed()->nop();
aoqi@6880 2619
aoqi@6880 2620 // not xchged
aoqi@6880 2621 bind(nequal);
aoqi@6880 2622 sync();
aoqi@6880 2623 //move(c_reg, AT);
aoqi@6880 2624 //move(AT, R0);
aoqi@6880 2625 dadd(c_reg, AT, R0);
aoqi@6880 2626 dadd(AT, R0, R0);
aoqi@6880 2627 bind(done);
aoqi@6880 2628 }
aoqi@6880 2629
aoqi@6880 2630 // be sure the three register is different
aoqi@6880 2631 void MacroAssembler::rem_s(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp) {
aoqi@6880 2632 assert_different_registers(tmp, fs, ft);
aoqi@6880 2633 div_s(tmp, fs, ft);
aoqi@6880 2634 trunc_l_s(tmp, tmp);
aoqi@6880 2635 cvt_s_l(tmp, tmp);
aoqi@6880 2636 mul_s(tmp, tmp, ft);
aoqi@6880 2637 sub_s(fd, fs, tmp);
aoqi@6880 2638 }
aoqi@6880 2639
aoqi@6880 2640 // be sure the three register is different
aoqi@6880 2641 void MacroAssembler::rem_d(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp) {
aoqi@6880 2642 assert_different_registers(tmp, fs, ft);
aoqi@6880 2643 div_d(tmp, fs, ft);
aoqi@6880 2644 trunc_l_d(tmp, tmp);
aoqi@6880 2645 cvt_d_l(tmp, tmp);
aoqi@6880 2646 mul_d(tmp, tmp, ft);
aoqi@6880 2647 sub_d(fd, fs, tmp);
aoqi@6880 2648 }
aoqi@6880 2649
aoqi@6880 2650 // Fast_Lock and Fast_Unlock used by C2
aoqi@6880 2651
aoqi@6880 2652 // Because the transitions from emitted code to the runtime
aoqi@6880 2653 // monitorenter/exit helper stubs are so slow it's critical that
aoqi@6880 2654 // we inline both the stack-locking fast-path and the inflated fast path.
aoqi@6880 2655 //
aoqi@6880 2656 // See also: cmpFastLock and cmpFastUnlock.
aoqi@6880 2657 //
aoqi@6880 2658 // What follows is a specialized inline transliteration of the code
aoqi@6880 2659 // in slow_enter() and slow_exit(). If we're concerned about I$ bloat
aoqi@6880 2660 // another option would be to emit TrySlowEnter and TrySlowExit methods
aoqi@6880 2661 // at startup-time. These methods would accept arguments as
aoqi@9459 2662 // (Obj, Self, box, Scratch) and return success-failure
aoqi@6880 2663 // indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply
aoqi@6880 2664 // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit.
aoqi@6880 2665 // In practice, however, the # of lock sites is bounded and is usually small.
aoqi@6880 2666 // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer
aoqi@6880 2667 // if the processor uses simple bimodal branch predictors keyed by EIP
aoqi@6880 2668 // Since the helper routines would be called from multiple synchronization
aoqi@6880 2669 // sites.
aoqi@6880 2670 //
aoqi@6880 2671 // An even better approach would be write "MonitorEnter()" and "MonitorExit()"
aoqi@6880 2672 // in java - using j.u.c and unsafe - and just bind the lock and unlock sites
aoqi@6880 2673 // to those specialized methods. That'd give us a mostly platform-independent
aoqi@6880 2674 // implementation that the JITs could optimize and inline at their pleasure.
aoqi@6880 2675 // Done correctly, the only time we'd need to cross to native could would be
aoqi@6880 2676 // to park() or unpark() threads. We'd also need a few more unsafe operators
aoqi@6880 2677 // to (a) prevent compiler-JIT reordering of non-volatile accesses, and
aoqi@6880 2678 // (b) explicit barriers or fence operations.
aoqi@6880 2679 //
aoqi@6880 2680 // TODO:
aoqi@6880 2681 //
aoqi@6880 2682 // * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr).
aoqi@6880 2683 // This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals.
aoqi@6880 2684 // Given TLAB allocation, Self is usually manifested in a register, so passing it into
aoqi@6880 2685 // the lock operators would typically be faster than reifying Self.
aoqi@6880 2686 //
aoqi@6880 2687 // * Ideally I'd define the primitives as:
aoqi@9459 2688 // fast_lock (nax Obj, nax box, tmp, nax scr) where box, tmp and scr are KILLED.
aoqi@9459 2689 // fast_unlock (nax Obj, box, nax tmp) where box and tmp are KILLED
aoqi@6880 2690 // Unfortunately ADLC bugs prevent us from expressing the ideal form.
aoqi@6880 2691 // Instead, we're stuck with a rather awkward and brittle register assignments below.
aoqi@6880 2692 // Furthermore the register assignments are overconstrained, possibly resulting in
aoqi@6880 2693 // sub-optimal code near the synchronization site.
aoqi@6880 2694 //
aoqi@6880 2695 // * Eliminate the sp-proximity tests and just use "== Self" tests instead.
aoqi@6880 2696 // Alternately, use a better sp-proximity test.
aoqi@6880 2697 //
aoqi@6880 2698 // * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value.
aoqi@6880 2699 // Either one is sufficient to uniquely identify a thread.
aoqi@6880 2700 // TODO: eliminate use of sp in _owner and use get_thread(tr) instead.
aoqi@6880 2701 //
aoqi@6880 2702 // * Intrinsify notify() and notifyAll() for the common cases where the
aoqi@6880 2703 // object is locked by the calling thread but the waitlist is empty.
aoqi@6880 2704 // avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll().
aoqi@6880 2705 //
aoqi@6880 2706 // * use jccb and jmpb instead of jcc and jmp to improve code density.
aoqi@6880 2707 // But beware of excessive branch density on AMD Opterons.
aoqi@6880 2708 //
aoqi@6880 2709 // * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success
aoqi@6880 2710 // or failure of the fast-path. If the fast-path fails then we pass
aoqi@6880 2711 // control to the slow-path, typically in C. In Fast_Lock and
aoqi@6880 2712 // Fast_Unlock we often branch to DONE_LABEL, just to find that C2
aoqi@6880 2713 // will emit a conditional branch immediately after the node.
aoqi@6880 2714 // So we have branches to branches and lots of ICC.ZF games.
aoqi@6880 2715 // Instead, it might be better to have C2 pass a "FailureLabel"
aoqi@6880 2716 // into Fast_Lock and Fast_Unlock. In the case of success, control
aoqi@6880 2717 // will drop through the node. ICC.ZF is undefined at exit.
aoqi@6880 2718 // In the case of failure, the node will branch directly to the
aoqi@6880 2719 // FailureLabel
aoqi@6880 2720
aoqi@6880 2721
aoqi@6880 2722 // obj: object to lock
aoqi@6880 2723 // box: on-stack box address (displaced header location) - KILLED
aoqi@9459 2724 // tmp: tmp -- KILLED
aoqi@6880 2725 // scr: tmp -- KILLED
aoqi@6880 2726 void MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmpReg, Register scrReg) {
aoqi@6880 2727
aoqi@6880 2728 // Ensure the register assignents are disjoint
aoqi@6880 2729 guarantee (objReg != boxReg, "") ;
aoqi@6880 2730 guarantee (objReg != tmpReg, "") ;
aoqi@6880 2731 guarantee (objReg != scrReg, "") ;
aoqi@6880 2732 guarantee (boxReg != tmpReg, "") ;
aoqi@6880 2733 guarantee (boxReg != scrReg, "") ;
aoqi@6880 2734
aoqi@6880 2735
aoqi@6880 2736 block_comment("FastLock");
aoqi@6880 2737 if (PrintBiasedLockingStatistics) {
aoqi@6880 2738 push(tmpReg);
aoqi@6880 2739 atomic_inc32((address)BiasedLocking::total_entry_count_addr(), 1, AT, tmpReg);
aoqi@6880 2740 pop(tmpReg);
aoqi@6880 2741 }
aoqi@6880 2742
aoqi@6880 2743 if (EmitSync & 1) {
aoqi@6880 2744 move(AT, 0x0);
aoqi@6880 2745 return;
aoqi@6880 2746 } else
aoqi@6880 2747 if (EmitSync & 2) {
aoqi@6880 2748 Label DONE_LABEL ;
aoqi@6880 2749 if (UseBiasedLocking) {
aoqi@6880 2750 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
aoqi@6880 2751 biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL);
aoqi@6880 2752 }
aoqi@6880 2753
aoqi@6880 2754 ld(tmpReg, Address(objReg, 0)) ; // fetch markword
aoqi@6880 2755 ori(tmpReg, tmpReg, 0x1);
aoqi@6880 2756 sd(tmpReg, Address(boxReg, 0)); // Anticipate successful CAS
aoqi@6880 2757
aoqi@6880 2758 cmpxchg(boxReg, Address(objReg, 0), tmpReg); // Updates tmpReg
aoqi@6880 2759 bne(AT, R0, DONE_LABEL);
aoqi@6880 2760 delayed()->nop();
aoqi@6880 2761
aoqi@6880 2762 // Recursive locking
aoqi@6880 2763 dsubu(tmpReg, tmpReg, SP);
aoqi@6880 2764 li(AT, (7 - os::vm_page_size() ));
aoqi@6880 2765 andr(tmpReg, tmpReg, AT);
aoqi@6880 2766 sd(tmpReg, Address(boxReg, 0));
aoqi@6880 2767 bind(DONE_LABEL) ;
aoqi@6880 2768 } else {
aoqi@6880 2769 // Possible cases that we'll encounter in fast_lock
aoqi@6880 2770 // ------------------------------------------------
aoqi@6880 2771 // * Inflated
aoqi@6880 2772 // -- unlocked
aoqi@6880 2773 // -- Locked
aoqi@6880 2774 // = by self
aoqi@6880 2775 // = by other
aoqi@6880 2776 // * biased
aoqi@6880 2777 // -- by Self
aoqi@6880 2778 // -- by other
aoqi@6880 2779 // * neutral
aoqi@6880 2780 // * stack-locked
aoqi@6880 2781 // -- by self
aoqi@6880 2782 // = sp-proximity test hits
aoqi@6880 2783 // = sp-proximity test generates false-negative
aoqi@6880 2784 // -- by other
aoqi@6880 2785 //
aoqi@6880 2786
aoqi@6880 2787 Label IsInflated, DONE_LABEL, PopDone ;
aoqi@6880 2788
aoqi@6880 2789 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage
aoqi@6880 2790 // order to reduce the number of conditional branches in the most common cases.
aoqi@6880 2791 // Beware -- there's a subtle invariant that fetch of the markword
aoqi@6880 2792 // at [FETCH], below, will never observe a biased encoding (*101b).
aoqi@6880 2793 // If this invariant is not held we risk exclusion (safety) failure.
aoqi@6880 2794 if (UseBiasedLocking && !UseOptoBiasInlining) {
aoqi@6880 2795 biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL);
aoqi@6880 2796 }
aoqi@6880 2797
aoqi@6880 2798 ld(tmpReg, Address(objReg, 0)) ; //Fetch the markword of the object.
aoqi@6880 2799 andi(AT, tmpReg, markOopDesc::monitor_value);
aoqi@6880 2800 bne(AT, R0, IsInflated); // inflated vs stack-locked|neutral|bias
aoqi@6880 2801 delayed()->nop();
aoqi@6880 2802
aoqi@6880 2803 // Attempt stack-locking ...
aoqi@6880 2804 ori (tmpReg, tmpReg, markOopDesc::unlocked_value);
aoqi@6880 2805 sd(tmpReg, Address(boxReg, 0)); // Anticipate successful CAS
aoqi@6880 2806 //if (os::is_MP()) {
aoqi@6880 2807 // sync();
aoqi@6880 2808 //}
aoqi@6880 2809
aoqi@6880 2810 cmpxchg(boxReg, Address(objReg, 0), tmpReg); // Updates tmpReg
aoqi@6880 2811 //AT == 1: unlocked
aoqi@6880 2812
aoqi@6880 2813 if (PrintBiasedLockingStatistics) {
aoqi@6880 2814 Label L;
aoqi@6880 2815 beq(AT, R0, L);
aoqi@6880 2816 delayed()->nop();
aoqi@6880 2817 push(T0);
aoqi@6880 2818 push(T1);
aoqi@6880 2819 atomic_inc32((address)BiasedLocking::fast_path_entry_count_addr(), 1, T0, T1);
aoqi@6880 2820 pop(T1);
aoqi@6880 2821 pop(T0);
aoqi@6880 2822 bind(L);
aoqi@6880 2823 }
aoqi@6880 2824 bne(AT, R0, DONE_LABEL);
aoqi@6880 2825 delayed()->nop();
aoqi@6880 2826
aoqi@6880 2827 // Recursive locking
aoqi@6880 2828 // The object is stack-locked: markword contains stack pointer to BasicLock.
aoqi@6880 2829 // Locked by current thread if difference with current SP is less than one page.
aoqi@6880 2830 dsubu(tmpReg, tmpReg, SP);
aoqi@6880 2831 li(AT, 7 - os::vm_page_size() );
aoqi@6880 2832 andr(tmpReg, tmpReg, AT);
aoqi@6880 2833 sd(tmpReg, Address(boxReg, 0));
aoqi@6880 2834 if (PrintBiasedLockingStatistics) {
aoqi@6880 2835 Label L;
aoqi@6880 2836 // tmpReg == 0 => BiasedLocking::_fast_path_entry_count++
aoqi@6880 2837 bne(tmpReg, R0, L);
aoqi@6880 2838 delayed()->nop();
aoqi@6880 2839 push(T0);
aoqi@6880 2840 push(T1);
aoqi@6880 2841 atomic_inc32((address)BiasedLocking::fast_path_entry_count_addr(), 1, T0, T1);
aoqi@6880 2842 pop(T1);
aoqi@6880 2843 pop(T0);
aoqi@6880 2844 bind(L);
aoqi@6880 2845 }
aoqi@9459 2846 sltiu(AT, tmpReg, 1); // AT = (tmpReg == 0) ? 1 : 0
aoqi@6880 2847
aoqi@6880 2848 b(DONE_LABEL) ;
aoqi@6880 2849 delayed()->nop();
aoqi@6880 2850
aoqi@6880 2851 bind(IsInflated) ;
aoqi@6880 2852 // The object's monitor m is unlocked iff m->owner == NULL,
aoqi@6880 2853 // otherwise m->owner may contain a thread or a stack address.
aoqi@6880 2854
aoqi@6880 2855 // TODO: someday avoid the ST-before-CAS penalty by
aoqi@6880 2856 // relocating (deferring) the following ST.
aoqi@6880 2857 // We should also think about trying a CAS without having
aoqi@6880 2858 // fetched _owner. If the CAS is successful we may
aoqi@6880 2859 // avoid an RTO->RTS upgrade on the $line.
aoqi@6880 2860 // Without cast to int32_t a movptr will destroy r10 which is typically obj
aoqi@6880 2861 li(AT, (int32_t)intptr_t(markOopDesc::unused_mark()));
aoqi@6880 2862 sd(AT, Address(boxReg, 0));
aoqi@6880 2863
aoqi@6880 2864 move(boxReg, tmpReg) ;
aoqi@6880 2865 ld(tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
aoqi@6880 2866 // if (m->owner != 0) => AT = 0, goto slow path.
aoqi@6880 2867 move(AT, R0);
aoqi@6880 2868 bne(tmpReg, R0, DONE_LABEL);
aoqi@6880 2869 delayed()->nop();
aoqi@6880 2870
aoqi@6880 2871 #ifndef OPT_THREAD
aoqi@6880 2872 get_thread (TREG) ;
aoqi@6880 2873 #endif
aoqi@6880 2874 // It's inflated and appears unlocked
aoqi@6880 2875 //if (os::is_MP()) {
aoqi@6880 2876 // sync();
aoqi@6880 2877 //}
aoqi@6880 2878 cmpxchg(TREG, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), tmpReg) ;
aoqi@6880 2879 // Intentional fall-through into DONE_LABEL ...
aoqi@6880 2880
aoqi@6880 2881
aoqi@6880 2882 // DONE_LABEL is a hot target - we'd really like to place it at the
aoqi@6880 2883 // start of cache line by padding with NOPs.
aoqi@6880 2884 // See the AMD and Intel software optimization manuals for the
aoqi@6880 2885 // most efficient "long" NOP encodings.
aoqi@6880 2886 // Unfortunately none of our alignment mechanisms suffice.
aoqi@6880 2887 bind(DONE_LABEL);
aoqi@6880 2888
aoqi@6880 2889 // At DONE_LABEL the AT is set as follows ...
aoqi@6880 2890 // Fast_Unlock uses the same protocol.
aoqi@6880 2891 // AT == 1 -> Success
aoqi@6880 2892 // AT == 0 -> Failure - force control through the slow-path
aoqi@6880 2893
aoqi@6880 2894 // Avoid branch-to-branch on AMD processors
aoqi@6880 2895 // This appears to be superstition.
aoqi@6880 2896 if (EmitSync & 32) nop() ;
aoqi@6880 2897
aoqi@6880 2898 }
aoqi@6880 2899 }
aoqi@6880 2900
aoqi@6880 2901 // obj: object to unlock
aoqi@9459 2902 // box: box address (displaced header location), killed.
aoqi@9459 2903 // tmp: killed tmp; cannot be obj nor box.
aoqi@6880 2904 //
aoqi@6880 2905 // Some commentary on balanced locking:
aoqi@6880 2906 //
aoqi@6880 2907 // Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites.
aoqi@6880 2908 // Methods that don't have provably balanced locking are forced to run in the
aoqi@6880 2909 // interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
aoqi@6880 2910 // The interpreter provides two properties:
aoqi@6880 2911 // I1: At return-time the interpreter automatically and quietly unlocks any
aoqi@6880 2912 // objects acquired the current activation (frame). Recall that the
aoqi@6880 2913 // interpreter maintains an on-stack list of locks currently held by
aoqi@6880 2914 // a frame.
aoqi@6880 2915 // I2: If a method attempts to unlock an object that is not held by the
aoqi@6880 2916 // the frame the interpreter throws IMSX.
aoqi@6880 2917 //
aoqi@6880 2918 // Lets say A(), which has provably balanced locking, acquires O and then calls B().
aoqi@6880 2919 // B() doesn't have provably balanced locking so it runs in the interpreter.
aoqi@6880 2920 // Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O
aoqi@6880 2921 // is still locked by A().
aoqi@6880 2922 //
aoqi@6880 2923 // The only other source of unbalanced locking would be JNI. The "Java Native Interface:
aoqi@6880 2924 // Programmer's Guide and Specification" claims that an object locked by jni_monitorenter
aoqi@6880 2925 // should not be unlocked by "normal" java-level locking and vice-versa. The specification
aoqi@6880 2926 // doesn't specify what will occur if a program engages in such mixed-mode locking, however.
aoqi@6880 2927
aoqi@6880 2928 void MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register tmpReg) {
aoqi@6880 2929
aoqi@6880 2930 guarantee (objReg != boxReg, "") ;
aoqi@6880 2931 guarantee (objReg != tmpReg, "") ;
aoqi@6880 2932 guarantee (boxReg != tmpReg, "") ;
aoqi@6880 2933
aoqi@6880 2934 block_comment("FastUnlock");
aoqi@6880 2935
aoqi@6880 2936
aoqi@6880 2937 if (EmitSync & 4) {
aoqi@6880 2938 // Disable - inhibit all inlining. Force control through the slow-path
aoqi@6880 2939 move(AT, 0x0);
aoqi@6880 2940 return;
aoqi@6880 2941 } else
aoqi@6880 2942 if (EmitSync & 8) {
aoqi@6880 2943 Label DONE_LABEL ;
aoqi@6880 2944 if (UseBiasedLocking) {
aoqi@6880 2945 biased_locking_exit(objReg, tmpReg, DONE_LABEL);
aoqi@6880 2946 }
aoqi@6880 2947 // classic stack-locking code ...
aoqi@6880 2948 ld(tmpReg, Address(boxReg, 0)) ;
aoqi@6880 2949 beq(tmpReg, R0, DONE_LABEL) ;
aoqi@6880 2950 move(AT, 0x1); // delay slot
aoqi@6880 2951
aoqi@9459 2952 cmpxchg(tmpReg, Address(objReg, 0), boxReg);
aoqi@6880 2953 bind(DONE_LABEL);
aoqi@6880 2954 } else {
aoqi@6880 2955 Label DONE_LABEL, Stacked, CheckSucc, Inflated ;
aoqi@6880 2956
aoqi@6880 2957 // Critically, the biased locking test must have precedence over
aoqi@6880 2958 // and appear before the (box->dhw == 0) recursive stack-lock test.
aoqi@6880 2959 if (UseBiasedLocking && !UseOptoBiasInlining) {
aoqi@6880 2960 biased_locking_exit(objReg, tmpReg, DONE_LABEL);
aoqi@6880 2961 }
aoqi@6880 2962
aoqi@6880 2963 ld(AT, Address(boxReg, 0)) ; // Examine the displaced header
aoqi@6880 2964 beq(AT, R0, DONE_LABEL) ; // 0 indicates recursive stack-lock
aoqi@6880 2965 delayed()->daddiu(AT, R0, 0x1);
aoqi@6880 2966
aoqi@6880 2967 ld(tmpReg, Address(objReg, 0)) ; // Examine the object's markword
aoqi@6880 2968 andi(AT, tmpReg, markOopDesc::monitor_value) ; // Inflated?
aoqi@6880 2969 beq(AT, R0, Stacked) ; // Inflated?
aoqi@6880 2970 delayed()->nop();
aoqi@6880 2971
aoqi@6880 2972 bind(Inflated) ;
aoqi@6880 2973 // It's inflated.
aoqi@6880 2974 // Despite our balanced locking property we still check that m->_owner == Self
aoqi@6880 2975 // as java routines or native JNI code called by this thread might
aoqi@6880 2976 // have released the lock.
aoqi@6880 2977 // Refer to the comments in synchronizer.cpp for how we might encode extra
aoqi@6880 2978 // state in _succ so we can avoid fetching EntryList|cxq.
aoqi@6880 2979 //
aoqi@6880 2980 // I'd like to add more cases in fast_lock() and fast_unlock() --
aoqi@6880 2981 // such as recursive enter and exit -- but we have to be wary of
aoqi@6880 2982 // I$ bloat, T$ effects and BP$ effects.
aoqi@6880 2983 //
aoqi@6880 2984 // If there's no contention try a 1-0 exit. That is, exit without
aoqi@6880 2985 // a costly MEMBAR or CAS. See synchronizer.cpp for details on how
aoqi@6880 2986 // we detect and recover from the race that the 1-0 exit admits.
aoqi@6880 2987 //
aoqi@6880 2988 // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier
aoqi@6880 2989 // before it STs null into _owner, releasing the lock. Updates
aoqi@6880 2990 // to data protected by the critical section must be visible before
aoqi@6880 2991 // we drop the lock (and thus before any other thread could acquire
aoqi@6880 2992 // the lock and observe the fields protected by the lock).
aoqi@6880 2993 #ifndef OPT_THREAD
aoqi@6880 2994 get_thread (TREG) ;
aoqi@6880 2995 #endif
aoqi@6880 2996
aoqi@6880 2997 // It's inflated
aoqi@6880 2998 ld(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
aoqi@6880 2999 xorr(boxReg, boxReg, TREG);
aoqi@6880 3000
aoqi@6880 3001 ld(AT, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
aoqi@6880 3002 orr(boxReg, boxReg, AT);
aoqi@6880 3003
aoqi@6880 3004 move(AT, R0);
aoqi@6880 3005 bne(boxReg, R0, DONE_LABEL);
aoqi@6880 3006 delayed()->nop();
aoqi@6880 3007
aoqi@6880 3008 ld(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
aoqi@6880 3009 ld(AT, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
aoqi@6880 3010 orr(boxReg, boxReg, AT);
aoqi@6880 3011
aoqi@6880 3012 move(AT, R0);
aoqi@6880 3013 bne(boxReg, R0, DONE_LABEL);
aoqi@6880 3014 delayed()->nop();
aoqi@6880 3015
aoqi@6880 3016 sync();
aoqi@6880 3017 sd(R0, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
aoqi@6880 3018 move(AT, 0x1);
aoqi@6880 3019 b(DONE_LABEL);
aoqi@6880 3020 delayed()->nop();
aoqi@6880 3021
aoqi@6880 3022 bind (Stacked);
aoqi@6880 3023 ld(tmpReg, Address(boxReg, 0)) ;
aoqi@6880 3024 //if (os::is_MP()) { sync(); }
aoqi@6880 3025 cmpxchg(tmpReg, Address(objReg, 0), boxReg);
aoqi@6880 3026
aoqi@6880 3027 if (EmitSync & 65536) {
aoqi@6880 3028 bind (CheckSucc);
aoqi@6880 3029 }
aoqi@6880 3030
aoqi@6880 3031 bind(DONE_LABEL);
aoqi@6880 3032
aoqi@6880 3033 // Avoid branch to branch on AMD processors
aoqi@6880 3034 if (EmitSync & 32768) { nop() ; }
aoqi@6880 3035 }
aoqi@6880 3036 }
aoqi@6880 3037
aoqi@6880 3038 void MacroAssembler::align(int modulus) {
aoqi@6880 3039 while (offset() % modulus != 0) nop();
aoqi@6880 3040 }
aoqi@6880 3041
aoqi@6880 3042
aoqi@6880 3043 void MacroAssembler::verify_FPU(int stack_depth, const char* s) {
aoqi@6880 3044 //Unimplemented();
aoqi@6880 3045 }
aoqi@6880 3046
aoqi@6880 3047 #ifdef _LP64
aoqi@6880 3048 Register caller_saved_registers[] = {AT, V0, V1, A0, A1, A2, A3, A4, A5, A6, A7, T0, T1, T2, T3, T8, T9, GP, RA, FP};
zhaixiang@9170 3049 Register caller_saved_registers_except_v0[] = {AT, V1, A0, A1, A2, A3, A4, A5, A6, A7, T0, T1, T2, T3, T8, T9, GP, RA, FP};
aoqi@6880 3050
aoqi@9228 3051 //In MIPS64, F0~23 are all caller-saved registers
aoqi@6880 3052 FloatRegister caller_saved_fpu_registers[] = {F0, F12, F13};
aoqi@6880 3053 #else
aoqi@6880 3054 Register caller_saved_registers[] = {AT, V0, V1, A0, A1, A2, A3, T4, T5, T6, T7, T0, T1, T2, T3, T8, T9, GP, RA, FP};
zhaixiang@9170 3055 Register caller_saved_registers_except_v0[] = {AT, V1, A0, A1, A2, A3, T4, T5, T6, T7, T0, T1, T2, T3, T8, T9, GP, RA, FP};
aoqi@6880 3056
aoqi@6880 3057 Register caller_saved_fpu_registers[] = {};
aoqi@6880 3058 #endif
aoqi@6880 3059
aoqi@9459 3060 // We preserve all caller-saved register
aoqi@6880 3061 void MacroAssembler::pushad(){
aoqi@6880 3062 int i;
aoqi@6880 3063
aoqi@9459 3064 // Fixed-point registers
aoqi@6880 3065 int len = sizeof(caller_saved_registers) / sizeof(caller_saved_registers[0]);
aoqi@6880 3066 daddi(SP, SP, -1 * len * wordSize);
aoqi@6880 3067 for (i = 0; i < len; i++)
aoqi@6880 3068 {
aoqi@6880 3069 #ifdef _LP64
aoqi@6880 3070 sd(caller_saved_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3071 #else
aoqi@6880 3072 sw(caller_saved_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3073 #endif
aoqi@6880 3074 }
aoqi@6880 3075
aoqi@9459 3076 // Floating-point registers
aoqi@6880 3077 len = sizeof(caller_saved_fpu_registers) / sizeof(caller_saved_fpu_registers[0]);
aoqi@6880 3078 daddi(SP, SP, -1 * len * wordSize);
aoqi@6880 3079 for (i = 0; i < len; i++)
aoqi@6880 3080 {
aoqi@6880 3081 #ifdef _LP64
aoqi@6880 3082 sdc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3083 #else
aoqi@6880 3084 swc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3085 #endif
aoqi@6880 3086 }
aoqi@6880 3087 };
aoqi@6880 3088
aoqi@6880 3089 void MacroAssembler::popad(){
aoqi@6880 3090 int i;
aoqi@6880 3091
aoqi@9459 3092 // Floating-point registers
aoqi@6880 3093 int len = sizeof(caller_saved_fpu_registers) / sizeof(caller_saved_fpu_registers[0]);
aoqi@6880 3094 for (i = 0; i < len; i++)
aoqi@6880 3095 {
aoqi@6880 3096 #ifdef _LP64
aoqi@6880 3097 ldc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3098 #else
aoqi@6880 3099 lwc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3100 #endif
aoqi@6880 3101 }
aoqi@6880 3102 daddi(SP, SP, len * wordSize);
aoqi@6880 3103
aoqi@9459 3104 // Fixed-point registers
aoqi@6880 3105 len = sizeof(caller_saved_registers) / sizeof(caller_saved_registers[0]);
aoqi@6880 3106 for (i = 0; i < len; i++)
aoqi@6880 3107 {
aoqi@6880 3108 #ifdef _LP64
aoqi@6880 3109 ld(caller_saved_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3110 #else
aoqi@6880 3111 lw(caller_saved_registers[i], SP, (len - i - 1) * wordSize);
aoqi@6880 3112 #endif
aoqi@6880 3113 }
aoqi@6880 3114 daddi(SP, SP, len * wordSize);
aoqi@6880 3115 };
aoqi@6880 3116
zhaixiang@9170 3117 // We preserve all caller-saved register except V0
zhaixiang@9170 3118 void MacroAssembler::pushad_except_v0() {
zhaixiang@9170 3119 int i;
zhaixiang@9170 3120
aoqi@9459 3121 // Fixed-point registers
zhaixiang@9170 3122 int len = sizeof(caller_saved_registers_except_v0) / sizeof(caller_saved_registers_except_v0[0]);
zhaixiang@9170 3123 daddi(SP, SP, -1 * len * wordSize);
zhaixiang@9170 3124 for (i = 0; i < len; i++) {
zhaixiang@9170 3125 #ifdef _LP64
zhaixiang@9170 3126 sd(caller_saved_registers_except_v0[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3127 #else
zhaixiang@9170 3128 sw(caller_saved_registers_except_v0[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3129 #endif
zhaixiang@9170 3130 }
zhaixiang@9170 3131
aoqi@9459 3132 // Floating-point registers
zhaixiang@9170 3133 len = sizeof(caller_saved_fpu_registers) / sizeof(caller_saved_fpu_registers[0]);
zhaixiang@9170 3134 daddi(SP, SP, -1 * len * wordSize);
zhaixiang@9170 3135 for (i = 0; i < len; i++) {
zhaixiang@9170 3136 #ifdef _LP64
zhaixiang@9170 3137 sdc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3138 #else
zhaixiang@9170 3139 swc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3140 #endif
zhaixiang@9170 3141 }
zhaixiang@9170 3142 }
zhaixiang@9170 3143
zhaixiang@9170 3144 void MacroAssembler::popad_except_v0() {
zhaixiang@9170 3145 int i;
zhaixiang@9170 3146
aoqi@9459 3147 // Floating-point registers
zhaixiang@9170 3148 int len = sizeof(caller_saved_fpu_registers) / sizeof(caller_saved_fpu_registers[0]);
zhaixiang@9170 3149 for (i = 0; i < len; i++) {
zhaixiang@9170 3150 #ifdef _LP64
zhaixiang@9170 3151 ldc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3152 #else
zhaixiang@9170 3153 lwc1(caller_saved_fpu_registers[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3154 #endif
zhaixiang@9170 3155 }
zhaixiang@9170 3156 daddi(SP, SP, len * wordSize);
zhaixiang@9170 3157
aoqi@9459 3158 // Fixed-point registers
zhaixiang@9170 3159 len = sizeof(caller_saved_registers_except_v0) / sizeof(caller_saved_registers_except_v0[0]);
zhaixiang@9170 3160 for (i = 0; i < len; i++) {
zhaixiang@9170 3161 #ifdef _LP64
zhaixiang@9170 3162 ld(caller_saved_registers_except_v0[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3163 #else
zhaixiang@9170 3164 lw(caller_saved_registers_except_v0[i], SP, (len - i - 1) * wordSize);
zhaixiang@9170 3165 #endif
zhaixiang@9170 3166 }
zhaixiang@9170 3167 daddi(SP, SP, len * wordSize);
zhaixiang@9170 3168 }
zhaixiang@9170 3169
aoqi@6880 3170 void MacroAssembler::push2(Register reg1, Register reg2) {
aoqi@6880 3171 #ifdef _LP64
aoqi@6880 3172 daddi(SP, SP, -16);
aoqi@6880 3173 sd(reg2, SP, 0);
aoqi@6880 3174 sd(reg1, SP, 8);
aoqi@6880 3175 #else
aoqi@6880 3176 addi(SP, SP, -8);
aoqi@6880 3177 sw(reg2, SP, 0);
aoqi@6880 3178 sw(reg1, SP, 4);
aoqi@6880 3179 #endif
aoqi@6880 3180 }
aoqi@6880 3181
aoqi@6880 3182 void MacroAssembler::pop2(Register reg1, Register reg2) {
aoqi@6880 3183 #ifdef _LP64
aoqi@6880 3184 ld(reg1, SP, 0);
aoqi@6880 3185 ld(reg2, SP, 8);
aoqi@6880 3186 daddi(SP, SP, 16);
aoqi@6880 3187 #else
aoqi@6880 3188 lw(reg1, SP, 0);
aoqi@6880 3189 lw(reg2, SP, 4);
aoqi@6880 3190 addi(SP, SP, 8);
aoqi@6880 3191 #endif
aoqi@6880 3192 }
aoqi@6880 3193
aoqi@9459 3194 // for UseCompressedOops Option
aoqi@6880 3195 void MacroAssembler::load_klass(Register dst, Register src) {
aoqi@6880 3196 #ifdef _LP64
aoqi@8009 3197 if(UseCompressedClassPointers){
aoqi@8009 3198 lwu(dst, Address(src, oopDesc::klass_offset_in_bytes()));
aoqi@8009 3199 decode_klass_not_null(dst);
aoqi@8009 3200 } else
aoqi@6880 3201 #endif
aoqi@8009 3202 ld(dst, src, oopDesc::klass_offset_in_bytes());
aoqi@6880 3203 }
aoqi@6880 3204
aoqi@6880 3205 void MacroAssembler::store_klass(Register dst, Register src) {
aoqi@6880 3206 #ifdef _LP64
aoqi@8009 3207 if(UseCompressedClassPointers){
aoqi@6880 3208 encode_klass_not_null(src);
aoqi@6880 3209 sw(src, dst, oopDesc::klass_offset_in_bytes());
aoqi@8009 3210 } else {
aoqi@6880 3211 #endif
aoqi@6880 3212 sd(src, dst, oopDesc::klass_offset_in_bytes());
aoqi@8009 3213 }
aoqi@6880 3214 }
aoqi@6880 3215
aoqi@6880 3216 void MacroAssembler::load_prototype_header(Register dst, Register src) {
aoqi@6880 3217 load_klass(dst, src);
aoqi@6880 3218 ld(dst, Address(dst, Klass::prototype_header_offset()));
aoqi@6880 3219 }
aoqi@6880 3220
aoqi@6880 3221 #ifdef _LP64
aoqi@6880 3222 void MacroAssembler::store_klass_gap(Register dst, Register src) {
aoqi@6880 3223 if (UseCompressedClassPointers) {
aoqi@6880 3224 sw(src, dst, oopDesc::klass_gap_offset_in_bytes());
aoqi@6880 3225 }
aoqi@6880 3226 }
aoqi@6880 3227
aoqi@6880 3228 void MacroAssembler::load_heap_oop(Register dst, Address src) {
aoqi@8009 3229 if(UseCompressedOops){
aoqi@8009 3230 lwu(dst, src);
aoqi@8009 3231 decode_heap_oop(dst);
aoqi@8009 3232 } else {
aoqi@8009 3233 ld(dst, src);
aoqi@8009 3234 }
aoqi@6880 3235 }
aoqi@6880 3236
aoqi@6880 3237 void MacroAssembler::store_heap_oop(Address dst, Register src){
aoqi@8009 3238 if(UseCompressedOops){
aoqi@8009 3239 assert(!dst.uses(src), "not enough registers");
aoqi@8009 3240 encode_heap_oop(src);
aoqi@8009 3241 sw(src, dst);
aoqi@8009 3242 } else {
aoqi@8009 3243 sd(src, dst);
aoqi@8009 3244 }
aoqi@6880 3245 }
aoqi@6880 3246
fujie@8001 3247 void MacroAssembler::store_heap_oop_null(Address dst){
aoqi@8009 3248 if(UseCompressedOops){
aoqi@8009 3249 sw(R0, dst);
aoqi@8009 3250 } else {
aoqi@8009 3251 sd(R0, dst);
aoqi@8009 3252 }
fujie@8001 3253 }
fujie@8001 3254
aoqi@6880 3255 #ifdef ASSERT
aoqi@6880 3256 void MacroAssembler::verify_heapbase(const char* msg) {
aoqi@6880 3257 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
aoqi@6880 3258 assert (Universe::heap() != NULL, "java heap should be initialized");
aoqi@6880 3259 }
aoqi@6880 3260 #endif
aoqi@6880 3261
aoqi@6880 3262
aoqi@6880 3263 // Algorithm must match oop.inline.hpp encode_heap_oop.
aoqi@6880 3264 void MacroAssembler::encode_heap_oop(Register r) {
aoqi@6880 3265 #ifdef ASSERT
aoqi@6880 3266 verify_heapbase("MacroAssembler::encode_heap_oop:heap base corrupted?");
aoqi@6880 3267 #endif
aoqi@6880 3268 verify_oop(r, "broken oop in encode_heap_oop");
aoqi@6880 3269 if (Universe::narrow_oop_base() == NULL) {
aoqi@6880 3270 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3271 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3272 shr(r, LogMinObjAlignmentInBytes);
aoqi@6880 3273 }
aoqi@6880 3274 return;
aoqi@6880 3275 }
aoqi@6880 3276
aoqi@8009 3277 movz(r, S5_heapbase, r);
aoqi@8009 3278 dsub(r, r, S5_heapbase);
aoqi@8009 3279 if (Universe::narrow_oop_shift() != 0) {
aoqi@8009 3280 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@8009 3281 shr(r, LogMinObjAlignmentInBytes);
aoqi@8009 3282 }
aoqi@6880 3283 }
aoqi@6880 3284
aoqi@6880 3285 void MacroAssembler::encode_heap_oop(Register dst, Register src) {
aoqi@6880 3286 #ifdef ASSERT
aoqi@6880 3287 verify_heapbase("MacroAssembler::encode_heap_oop:heap base corrupted?");
aoqi@6880 3288 #endif
aoqi@6880 3289 verify_oop(src, "broken oop in encode_heap_oop");
aoqi@6880 3290 if (Universe::narrow_oop_base() == NULL) {
aoqi@6880 3291 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3292 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3293 dsrl(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3294 } else {
aoqi@6880 3295 if (dst != src) move(dst, src);
aoqi@6880 3296 }
aoqi@6880 3297 } else {
aoqi@6880 3298 if (dst == src) {
aoqi@6880 3299 movz(dst, S5_heapbase, dst);
aoqi@6880 3300 dsub(dst, dst, S5_heapbase);
aoqi@6880 3301 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3302 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3303 shr(dst, LogMinObjAlignmentInBytes);
aoqi@6880 3304 }
aoqi@6880 3305 } else {
aoqi@6880 3306 dsub(dst, src, S5_heapbase);
aoqi@6880 3307 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3308 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3309 shr(dst, LogMinObjAlignmentInBytes);
aoqi@6880 3310 }
aoqi@6880 3311 movz(dst, R0, src);
aoqi@6880 3312 }
aoqi@6880 3313 }
aoqi@6880 3314 }
aoqi@6880 3315
aoqi@6880 3316 void MacroAssembler::encode_heap_oop_not_null(Register r) {
aoqi@8009 3317 assert (UseCompressedOops, "should be compressed");
aoqi@6880 3318 #ifdef ASSERT
aoqi@8009 3319 if (CheckCompressedOops) {
aoqi@8009 3320 Label ok;
aoqi@8009 3321 bne(r, R0, ok);
aoqi@8009 3322 delayed()->nop();
aoqi@8009 3323 stop("null oop passed to encode_heap_oop_not_null");
aoqi@8009 3324 bind(ok);
aoqi@8009 3325 }
aoqi@6880 3326 #endif
aoqi@6880 3327 verify_oop(r, "broken oop in encode_heap_oop_not_null");
aoqi@6880 3328 if (Universe::narrow_oop_base() != NULL) {
aoqi@6880 3329 dsub(r, r, S5_heapbase);
aoqi@6880 3330 }
aoqi@6880 3331 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3332 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3333 shr(r, LogMinObjAlignmentInBytes);
aoqi@6880 3334 }
aoqi@6880 3335
aoqi@6880 3336 }
aoqi@6880 3337
aoqi@6880 3338 void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
aoqi@8009 3339 assert (UseCompressedOops, "should be compressed");
aoqi@6880 3340 #ifdef ASSERT
aoqi@8009 3341 if (CheckCompressedOops) {
aoqi@8009 3342 Label ok;
aoqi@8009 3343 bne(src, R0, ok);
aoqi@8009 3344 delayed()->nop();
aoqi@8009 3345 stop("null oop passed to encode_heap_oop_not_null2");
aoqi@8009 3346 bind(ok);
aoqi@8009 3347 }
aoqi@8009 3348 #endif
aoqi@8009 3349 verify_oop(src, "broken oop in encode_heap_oop_not_null2");
aoqi@8009 3350
aoqi@8009 3351 if (Universe::narrow_oop_base() != NULL) {
aoqi@8009 3352 dsub(dst, src, S5_heapbase);
aoqi@8009 3353 if (Universe::narrow_oop_shift() != 0) {
aoqi@8009 3354 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@8009 3355 shr(dst, LogMinObjAlignmentInBytes);
aoqi@6880 3356 }
aoqi@8009 3357 } else {
aoqi@8009 3358 if (Universe::narrow_oop_shift() != 0) {
aoqi@8009 3359 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@8009 3360 dsrl(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3361 } else {
aoqi@8009 3362 if (dst != src) move(dst, src);
aoqi@6880 3363 }
aoqi@8009 3364 }
aoqi@6880 3365 }
aoqi@6880 3366
aoqi@6880 3367 void MacroAssembler::decode_heap_oop(Register r) {
aoqi@6880 3368 #ifdef ASSERT
aoqi@6880 3369 verify_heapbase("MacroAssembler::decode_heap_oop corrupted?");
aoqi@6880 3370 #endif
aoqi@6880 3371 if (Universe::narrow_oop_base() == NULL) {
aoqi@6880 3372 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3373 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3374 shl(r, LogMinObjAlignmentInBytes);
aoqi@6880 3375 }
aoqi@6880 3376 } else {
aoqi@6880 3377 move(AT, r);
aoqi@6880 3378 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3379 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3380 shl(r, LogMinObjAlignmentInBytes);
aoqi@6880 3381 }
aoqi@6880 3382 dadd(r, r, S5_heapbase);
aoqi@6880 3383 movz(r, R0, AT);
aoqi@6880 3384 }
aoqi@6880 3385 verify_oop(r, "broken oop in decode_heap_oop");
aoqi@6880 3386 }
aoqi@6880 3387
aoqi@6880 3388 void MacroAssembler::decode_heap_oop(Register dst, Register src) {
aoqi@6880 3389 #ifdef ASSERT
aoqi@6880 3390 verify_heapbase("MacroAssembler::decode_heap_oop corrupted?");
aoqi@6880 3391 #endif
aoqi@6880 3392 if (Universe::narrow_oop_base() == NULL) {
aoqi@6880 3393 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3394 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3395 if (dst != src) nop(); // DON'T DELETE THIS GUY.
aoqi@6880 3396 dsll(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3397 } else {
aoqi@6880 3398 if (dst != src) move(dst, src);
aoqi@6880 3399 }
aoqi@6880 3400 } else {
aoqi@6880 3401 if (dst == src) {
aoqi@6880 3402 move(AT, dst);
aoqi@6880 3403 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3404 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3405 shl(dst, LogMinObjAlignmentInBytes);
aoqi@6880 3406 }
aoqi@6880 3407 dadd(dst, dst, S5_heapbase);
aoqi@6880 3408 movz(dst, R0, AT);
aoqi@6880 3409 } else {
aoqi@6880 3410 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3411 assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3412 dsll(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3413 daddu(dst, dst, S5_heapbase);
aoqi@6880 3414 } else {
aoqi@6880 3415 daddu(dst, src, S5_heapbase);
aoqi@6880 3416 }
aoqi@6880 3417 movz(dst, R0, src);
aoqi@6880 3418 }
aoqi@6880 3419 }
aoqi@6880 3420 verify_oop(dst, "broken oop in decode_heap_oop");
aoqi@6880 3421 }
aoqi@6880 3422
aoqi@6880 3423 void MacroAssembler::decode_heap_oop_not_null(Register r) {
aoqi@6880 3424 // Note: it will change flags
aoqi@6880 3425 assert (UseCompressedOops, "should only be used for compressed headers");
aoqi@6880 3426 assert (Universe::heap() != NULL, "java heap should be initialized");
aoqi@6880 3427 // Cannot assert, unverified entry point counts instructions (see .ad file)
aoqi@6880 3428 // vtableStubs also counts instructions in pd_code_size_limit.
aoqi@6880 3429 // Also do not verify_oop as this is called by verify_oop.
aoqi@6880 3430 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3431 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3432 shl(r, LogMinObjAlignmentInBytes);
aoqi@6880 3433 if (Universe::narrow_oop_base() != NULL) {
aoqi@6880 3434 daddu(r, r, S5_heapbase);
aoqi@6880 3435 }
aoqi@6880 3436 } else {
aoqi@6880 3437 assert (Universe::narrow_oop_base() == NULL, "sanity");
aoqi@6880 3438 }
aoqi@6880 3439 }
aoqi@6880 3440
aoqi@6880 3441 void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
aoqi@6880 3442 assert (UseCompressedOops, "should only be used for compressed headers");
aoqi@6880 3443 assert (Universe::heap() != NULL, "java heap should be initialized");
aoqi@6880 3444
aoqi@6880 3445 // Cannot assert, unverified entry point counts instructions (see .ad file)
aoqi@6880 3446 // vtableStubs also counts instructions in pd_code_size_limit.
aoqi@6880 3447 // Also do not verify_oop as this is called by verify_oop.
aoqi@6880 3448 //lea(dst, Address(S5_heapbase, src, Address::times_8, 0));
aoqi@6880 3449 if (Universe::narrow_oop_shift() != 0) {
aoqi@6880 3450 assert(LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
aoqi@6880 3451 if (LogMinObjAlignmentInBytes == Address::times_8) {
aoqi@6880 3452 dsll(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3453 daddu(dst, dst, S5_heapbase);
aoqi@6880 3454 } else {
aoqi@6880 3455 dsll(dst, src, LogMinObjAlignmentInBytes);
aoqi@6880 3456 if (Universe::narrow_oop_base() != NULL) {
aoqi@6880 3457 daddu(dst, dst, S5_heapbase);
aoqi@6880 3458 }
aoqi@6880 3459 }
aoqi@6880 3460 } else {
aoqi@6880 3461 assert (Universe::narrow_oop_base() == NULL, "sanity");
aoqi@6880 3462 if (dst != src) {
aoqi@6880 3463 move(dst, src);
aoqi@6880 3464 }
aoqi@6880 3465 }
aoqi@6880 3466 }
aoqi@6880 3467
aoqi@6880 3468 void MacroAssembler::encode_klass_not_null(Register r) {
aoqi@6880 3469 if (Universe::narrow_klass_base() != NULL) {
aoqi@6880 3470 assert(r != AT, "Encoding a klass in AT");
aoqi@6880 3471 set64(AT, (int64_t)Universe::narrow_klass_base());
aoqi@6880 3472 dsub(r, r, AT);
aoqi@6880 3473 }
aoqi@6880 3474 if (Universe::narrow_klass_shift() != 0) {
aoqi@6880 3475 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
aoqi@6880 3476 shr(r, LogKlassAlignmentInBytes);
aoqi@6880 3477 }
aoqi@6880 3478 }
aoqi@6880 3479
aoqi@6880 3480 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
aoqi@6880 3481 if (dst == src) {
aoqi@6880 3482 encode_klass_not_null(src);
aoqi@6880 3483 } else {
aoqi@6880 3484 if (Universe::narrow_klass_base() != NULL) {
aoqi@6880 3485 set64(dst, (int64_t)Universe::narrow_klass_base());
aoqi@6880 3486 dsub(dst, src, dst);
aoqi@6880 3487 if (Universe::narrow_klass_shift() != 0) {
aoqi@6880 3488 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
aoqi@6880 3489 shr(dst, LogKlassAlignmentInBytes);
aoqi@6880 3490 }
aoqi@6880 3491 } else {
aoqi@6880 3492 if (Universe::narrow_klass_shift() != 0) {
aoqi@6880 3493 assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
aoqi@6880 3494 dsrl(dst, src, LogKlassAlignmentInBytes);
aoqi@6880 3495 } else {
aoqi@6880 3496 move(dst, src);
aoqi@6880 3497 }
aoqi@6880 3498 }
aoqi@6880 3499 }
aoqi@6880 3500 }
aoqi@6880 3501
aoqi@6880 3502 // Function instr_size_for_decode_klass_not_null() counts the instructions
aoqi@6880 3503 // generated by decode_klass_not_null(register r) and reinit_heapbase(),
aoqi@6880 3504 // when (Universe::heap() != NULL). Hence, if the instructions they
aoqi@6880 3505 // generate change, then this method needs to be updated.
aoqi@6880 3506 int MacroAssembler::instr_size_for_decode_klass_not_null() {
aoqi@6880 3507 assert (UseCompressedClassPointers, "only for compressed klass ptrs");
aoqi@6880 3508 if (Universe::narrow_klass_base() != NULL) {
aoqi@6880 3509 // mov64 + addq + shlq? + mov64 (for reinit_heapbase()).
aoqi@6880 3510 return (Universe::narrow_klass_shift() == 0 ? 4 * 9 : 4 * 10);
aoqi@6880 3511 } else {
aoqi@6880 3512 // longest load decode klass function, mov64, leaq
aoqi@6880 3513 return (Universe::narrow_klass_shift() == 0 ? 4 * 0 : 4 * 1);
aoqi@6880 3514 }
aoqi@6880 3515 }
aoqi@6880 3516
aoqi@6880 3517 void MacroAssembler::decode_klass_not_null(Register r) {
aoqi@6880 3518 assert (UseCompressedClassPointers, "should only be used for compressed headers");
aoqi@6880 3519 assert(r != AT, "Decoding a klass in AT");
aoqi@6880 3520 // Cannot assert, unverified entry point counts instructions (see .ad file)
aoqi@6880 3521 // vtableStubs also counts instructions in pd_code_size_limit.
aoqi@6880 3522 // Also do not verify_oop as this is called by verify_oop.
aoqi@6880 3523 if (Universe::narrow_klass_shift() != 0) {
aoqi@6880 3524 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
aoqi@6880 3525 shl(r, LogKlassAlignmentInBytes);
aoqi@6880 3526 }
aoqi@6880 3527 if (Universe::narrow_klass_base() != NULL) {
aoqi@6880 3528 set64(AT, (int64_t)Universe::narrow_klass_base());
aoqi@6880 3529 daddu(r, r, AT);
aoqi@6880 3530 //Not neccessary for MIPS at all.
aoqi@6880 3531 //reinit_heapbase();
aoqi@6880 3532 }
aoqi@6880 3533 }
aoqi@6880 3534
aoqi@6880 3535 void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
aoqi@6880 3536 assert (UseCompressedClassPointers, "should only be used for compressed headers");
aoqi@6880 3537
aoqi@6880 3538 if (dst == src) {
aoqi@6880 3539 decode_klass_not_null(dst);
aoqi@6880 3540 } else {
aoqi@6880 3541 // Cannot assert, unverified entry point counts instructions (see .ad file)
aoqi@6880 3542 // vtableStubs also counts instructions in pd_code_size_limit.
aoqi@6880 3543 // Also do not verify_oop as this is called by verify_oop.
aoqi@6880 3544 set64(dst, (int64_t)Universe::narrow_klass_base());
aoqi@6880 3545 if (Universe::narrow_klass_shift() != 0) {
aoqi@6880 3546 assert(LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
aoqi@6880 3547 assert(LogKlassAlignmentInBytes == Address::times_8, "klass not aligned on 64bits?");
aoqi@6880 3548 dsll(AT, src, Address::times_8);
aoqi@6880 3549 daddu(dst, dst, AT);
aoqi@6880 3550 } else {
aoqi@6880 3551 daddu(dst, src, dst);
aoqi@6880 3552 }
aoqi@6880 3553 }
aoqi@6880 3554 }
aoqi@6880 3555
aoqi@6880 3556 void MacroAssembler::incrementl(Register reg, int value) {
aoqi@6880 3557 if (value == min_jint) {
aoqi@6880 3558 move(AT, value);
aoqi@6880 3559 LP64_ONLY(addu32(reg, reg, AT)) NOT_LP64(addu(reg, reg, AT));
aoqi@6880 3560 return;
aoqi@6880 3561 }
aoqi@6880 3562 if (value < 0) { decrementl(reg, -value); return; }
aoqi@6880 3563 if (value == 0) { ; return; }
aoqi@6880 3564
aoqi@6880 3565 if(Assembler::is_simm16(value)) {
aoqi@6880 3566 NOT_LP64(addiu(reg, reg, value));
aoqi@6880 3567 LP64_ONLY(move(AT, value); addu32(reg, reg, AT));
aoqi@6880 3568 } else {
aoqi@6880 3569 move(AT, value);
aoqi@6880 3570 LP64_ONLY(addu32(reg, reg, AT)) NOT_LP64(addu(reg, reg, AT));
aoqi@6880 3571 }
aoqi@6880 3572 }
aoqi@6880 3573
aoqi@6880 3574 void MacroAssembler::decrementl(Register reg, int value) {
aoqi@6880 3575 if (value == min_jint) {
aoqi@6880 3576 move(AT, value);
aoqi@6880 3577 LP64_ONLY(subu32(reg, reg, AT)) NOT_LP64(subu(reg, reg, AT));
aoqi@6880 3578 return;
aoqi@6880 3579 }
aoqi@6880 3580 if (value < 0) { incrementl(reg, -value); return; }
aoqi@6880 3581 if (value == 0) { ; return; }
aoqi@6880 3582
aoqi@8009 3583 if (Assembler::is_simm16(value)) {
aoqi@6880 3584 NOT_LP64(addiu(reg, reg, -value));
aoqi@6880 3585 LP64_ONLY(move(AT, value); subu32(reg, reg, AT));
aoqi@6880 3586 } else {
aoqi@6880 3587 move(AT, value);
aoqi@6880 3588 LP64_ONLY(subu32(reg, reg, AT)) NOT_LP64(subu(reg, reg, AT));
aoqi@6880 3589 }
aoqi@6880 3590 }
aoqi@6880 3591
aoqi@6880 3592 void MacroAssembler::reinit_heapbase() {
aoqi@6880 3593 if (UseCompressedOops || UseCompressedClassPointers) {
aoqi@6880 3594 if (Universe::heap() != NULL) {
aoqi@6880 3595 if (Universe::narrow_oop_base() == NULL) {
aoqi@6880 3596 move(S5_heapbase, R0);
aoqi@6880 3597 } else {
aoqi@6880 3598 set64(S5_heapbase, (int64_t)Universe::narrow_ptrs_base());
aoqi@6880 3599 }
aoqi@6880 3600 } else {
aoqi@6880 3601 set64(S5_heapbase, (intptr_t)Universe::narrow_ptrs_base_addr());
aoqi@6880 3602 ld(S5_heapbase, S5_heapbase, 0);
aoqi@6880 3603 }
aoqi@6880 3604 }
aoqi@6880 3605 }
aoqi@6880 3606 #endif // _LP64
aoqi@6880 3607
aoqi@6880 3608 void MacroAssembler::check_klass_subtype(Register sub_klass,
aoqi@6880 3609 Register super_klass,
aoqi@6880 3610 Register temp_reg,
aoqi@6880 3611 Label& L_success) {
aoqi@6880 3612 //implement ind gen_subtype_check
aoqi@6880 3613 Label L_failure;
aoqi@6880 3614 check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, &L_success, &L_failure, NULL);
aoqi@6880 3615 check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, noreg, &L_success, NULL);
aoqi@6880 3616 bind(L_failure);
aoqi@6880 3617 }
aoqi@6880 3618
aoqi@6880 3619 SkipIfEqual::SkipIfEqual(
aoqi@6880 3620 MacroAssembler* masm, const bool* flag_addr, bool value) {
aoqi@6880 3621 _masm = masm;
aoqi@6880 3622 _masm->li(AT, (address)flag_addr);
wanghaomin@9577 3623 _masm->lb(AT, AT, 0);
wanghaomin@9577 3624 _masm->addi(AT, AT, -value);
wanghaomin@9577 3625 _masm->beq(AT, R0, _label);
aoqi@6880 3626 _masm->delayed()->nop();
aoqi@6880 3627 }
aoqi@6880 3628 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
aoqi@6880 3629 Register super_klass,
aoqi@6880 3630 Register temp_reg,
aoqi@6880 3631 Label* L_success,
aoqi@6880 3632 Label* L_failure,
aoqi@6880 3633 Label* L_slow_path,
aoqi@6880 3634 RegisterOrConstant super_check_offset) {
aoqi@6880 3635 assert_different_registers(sub_klass, super_klass, temp_reg);
aoqi@6880 3636 bool must_load_sco = (super_check_offset.constant_or_zero() == -1);
aoqi@6880 3637 if (super_check_offset.is_register()) {
aoqi@6880 3638 assert_different_registers(sub_klass, super_klass,
aoqi@6880 3639 super_check_offset.as_register());
aoqi@6880 3640 } else if (must_load_sco) {
aoqi@6880 3641 assert(temp_reg != noreg, "supply either a temp or a register offset");
aoqi@6880 3642 }
aoqi@6880 3643
aoqi@6880 3644 Label L_fallthrough;
aoqi@6880 3645 int label_nulls = 0;
aoqi@6880 3646 if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
aoqi@6880 3647 if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
aoqi@6880 3648 if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; }
aoqi@6880 3649 assert(label_nulls <= 1, "at most one NULL in the batch");
aoqi@6880 3650
aoqi@6880 3651 int sc_offset = in_bytes(Klass::secondary_super_cache_offset());
aoqi@6880 3652 int sco_offset = in_bytes(Klass::super_check_offset_offset());
aoqi@6880 3653 // If the pointers are equal, we are done (e.g., String[] elements).
aoqi@6880 3654 // This self-check enables sharing of secondary supertype arrays among
aoqi@6880 3655 // non-primary types such as array-of-interface. Otherwise, each such
aoqi@6880 3656 // type would need its own customized SSA.
aoqi@6880 3657 // We move this check to the front of the fast path because many
aoqi@6880 3658 // type checks are in fact trivially successful in this manner,
aoqi@6880 3659 // so we get a nicely predicted branch right at the start of the check.
aoqi@6880 3660 beq(sub_klass, super_klass, *L_success);
aoqi@6880 3661 delayed()->nop();
aoqi@6880 3662 // Check the supertype display:
aoqi@6880 3663 if (must_load_sco) {
aoqi@6880 3664 // Positive movl does right thing on LP64.
aoqi@8009 3665 lwu(temp_reg, super_klass, sco_offset);
aoqi@6880 3666 super_check_offset = RegisterOrConstant(temp_reg);
aoqi@6880 3667 }
aoqi@6880 3668 dsll(AT, super_check_offset.register_or_noreg(), Address::times_1);
aoqi@6880 3669 daddu(AT, sub_klass, AT);
aoqi@6880 3670 ld(AT, AT, super_check_offset.constant_or_zero()*Address::times_1);
aoqi@6880 3671
aoqi@6880 3672 // This check has worked decisively for primary supers.
aoqi@6880 3673 // Secondary supers are sought in the super_cache ('super_cache_addr').
aoqi@6880 3674 // (Secondary supers are interfaces and very deeply nested subtypes.)
aoqi@6880 3675 // This works in the same check above because of a tricky aliasing
aoqi@6880 3676 // between the super_cache and the primary super display elements.
aoqi@6880 3677 // (The 'super_check_addr' can address either, as the case requires.)
aoqi@6880 3678 // Note that the cache is updated below if it does not help us find
aoqi@6880 3679 // what we need immediately.
aoqi@6880 3680 // So if it was a primary super, we can just fail immediately.
aoqi@6880 3681 // Otherwise, it's the slow path for us (no success at this point).
aoqi@6880 3682
aoqi@6880 3683 if (super_check_offset.is_register()) {
aoqi@8009 3684 beq(super_klass, AT, *L_success);
aoqi@8009 3685 delayed()->nop();
aoqi@8009 3686 addi(AT, super_check_offset.as_register(), -sc_offset);
aoqi@6880 3687 if (L_failure == &L_fallthrough) {
aoqi@8009 3688 beq(AT, R0, *L_slow_path);
aoqi@8009 3689 delayed()->nop();
aoqi@6880 3690 } else {
zhaixiang@9149 3691 bne_far(AT, R0, *L_failure);
aoqi@8009 3692 delayed()->nop();
aoqi@8009 3693 b(*L_slow_path);
aoqi@8009 3694 delayed()->nop();
aoqi@6880 3695 }
aoqi@6880 3696 } else if (super_check_offset.as_constant() == sc_offset) {
aoqi@6880 3697 // Need a slow path; fast failure is impossible.
aoqi@6880 3698 if (L_slow_path == &L_fallthrough) {
aoqi@8009 3699 beq(super_klass, AT, *L_success);
aoqi@8009 3700 delayed()->nop();
aoqi@6880 3701 } else {
aoqi@8009 3702 bne(super_klass, AT, *L_slow_path);
aoqi@8009 3703 delayed()->nop();
aoqi@8009 3704 b(*L_success);
aoqi@8009 3705 delayed()->nop();
aoqi@6880 3706 }
aoqi@6880 3707 } else {
aoqi@6880 3708 // No slow path; it's a fast decision.
aoqi@6880 3709 if (L_failure == &L_fallthrough) {
aoqi@8009 3710 beq(super_klass, AT, *L_success);
aoqi@8009 3711 delayed()->nop();
aoqi@6880 3712 } else {
zhaixiang@9149 3713 bne_far(super_klass, AT, *L_failure);
aoqi@8009 3714 delayed()->nop();
aoqi@8009 3715 b(*L_success);
aoqi@8009 3716 delayed()->nop();
aoqi@6880 3717 }
aoqi@6880 3718 }
aoqi@6880 3719
aoqi@6880 3720 bind(L_fallthrough);
aoqi@6880 3721
aoqi@6880 3722 }
aoqi@6880 3723
aoqi@6880 3724
aoqi@6880 3725 void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
aoqi@6880 3726 Register super_klass,
aoqi@6880 3727 Register temp_reg,
aoqi@6880 3728 Register temp2_reg,
aoqi@6880 3729 Label* L_success,
aoqi@6880 3730 Label* L_failure,
aoqi@6880 3731 bool set_cond_codes) {
zhaixiang@9575 3732 if (temp2_reg == noreg)
zhaixiang@9575 3733 temp2_reg = TSR;
zhaixiang@9575 3734 assert_different_registers(sub_klass, super_klass, temp_reg, temp2_reg);
aoqi@6880 3735 #define IS_A_TEMP(reg) ((reg) == temp_reg || (reg) == temp2_reg)
aoqi@6880 3736
aoqi@6880 3737 Label L_fallthrough;
aoqi@6880 3738 int label_nulls = 0;
aoqi@6880 3739 if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
aoqi@6880 3740 if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
aoqi@6880 3741 assert(label_nulls <= 1, "at most one NULL in the batch");
aoqi@6880 3742
aoqi@6880 3743 // a couple of useful fields in sub_klass:
aoqi@6880 3744 int ss_offset = in_bytes(Klass::secondary_supers_offset());
aoqi@6880 3745 int sc_offset = in_bytes(Klass::secondary_super_cache_offset());
aoqi@6880 3746 Address secondary_supers_addr(sub_klass, ss_offset);
aoqi@6880 3747 Address super_cache_addr( sub_klass, sc_offset);
aoqi@6880 3748
aoqi@6880 3749 // Do a linear scan of the secondary super-klass chain.
aoqi@6880 3750 // This code is rarely used, so simplicity is a virtue here.
aoqi@6880 3751 // The repne_scan instruction uses fixed registers, which we must spill.
aoqi@6880 3752 // Don't worry too much about pre-existing connections with the input regs.
aoqi@6880 3753
aoqi@6880 3754 #ifndef PRODUCT
aoqi@6880 3755 int* pst_counter = &SharedRuntime::_partial_subtype_ctr;
aoqi@6880 3756 ExternalAddress pst_counter_addr((address) pst_counter);
aoqi@6880 3757 NOT_LP64( incrementl(pst_counter_addr) );
aoqi@6880 3758 #endif //PRODUCT
aoqi@6880 3759
aoqi@6880 3760 // We will consult the secondary-super array.
aoqi@6880 3761 ld(temp_reg, secondary_supers_addr);
aoqi@6880 3762 // Load the array length. (Positive movl does right thing on LP64.)
aoqi@6880 3763 lw(temp2_reg, Address(temp_reg, Array<Klass*>::length_offset_in_bytes()));
aoqi@6880 3764 // Skip to start of data.
aoqi@6880 3765 daddiu(temp_reg, temp_reg, Array<Klass*>::base_offset_in_bytes());
aoqi@6880 3766
aoqi@9228 3767 // OpenJDK8 never compresses klass pointers in secondary-super array.
aoqi@6880 3768 Label Loop, subtype;
aoqi@6880 3769 bind(Loop);
aoqi@6880 3770 beq(temp2_reg, R0, *L_failure);
aoqi@6880 3771 delayed()->nop();
aoqi@6880 3772 ld(AT, temp_reg, 0);
aoqi@6880 3773 beq(AT, super_klass, subtype);
aoqi@6880 3774 delayed()->daddi(temp_reg, temp_reg, 1 * wordSize);
aoqi@6880 3775 b(Loop);
aoqi@6880 3776 delayed()->daddi(temp2_reg, temp2_reg, -1);
aoqi@6880 3777
aoqi@6880 3778 bind(subtype);
aoqi@6880 3779 sd(super_klass, super_cache_addr);
aoqi@6880 3780 if (L_success != &L_fallthrough) {
aoqi@6880 3781 b(*L_success);
aoqi@6880 3782 delayed()->nop();
aoqi@6880 3783 }
aoqi@6880 3784
aoqi@6880 3785 // Success. Cache the super we found and proceed in triumph.
aoqi@6880 3786 #undef IS_A_TEMP
aoqi@6880 3787
aoqi@6880 3788 bind(L_fallthrough);
aoqi@6880 3789 }
aoqi@8009 3790
aoqi@6880 3791 void MacroAssembler::get_vm_result(Register oop_result, Register java_thread) {
aoqi@6880 3792 ld(oop_result, Address(java_thread, JavaThread::vm_result_offset()));
aoqi@6880 3793 sd(R0, Address(java_thread, JavaThread::vm_result_offset()));
aoqi@6880 3794 verify_oop(oop_result, "broken oop in call_VM_base");
aoqi@6880 3795 }
aoqi@6880 3796
aoqi@6880 3797 void MacroAssembler::get_vm_result_2(Register metadata_result, Register java_thread) {
aoqi@6880 3798 ld(metadata_result, Address(java_thread, JavaThread::vm_result_2_offset()));
aoqi@6880 3799 sd(R0, Address(java_thread, JavaThread::vm_result_2_offset()));
aoqi@6880 3800 }
aoqi@6880 3801
aoqi@6880 3802 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
aoqi@6880 3803 int extra_slot_offset) {
aoqi@6880 3804 // cf. TemplateTable::prepare_invoke(), if (load_receiver).
aoqi@6880 3805 int stackElementSize = Interpreter::stackElementSize;
aoqi@6880 3806 int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0);
aoqi@6880 3807 #ifdef ASSERT
aoqi@6880 3808 int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1);
aoqi@6880 3809 assert(offset1 - offset == stackElementSize, "correct arithmetic");
aoqi@6880 3810 #endif
aoqi@6880 3811 Register scale_reg = NOREG;
aoqi@6880 3812 Address::ScaleFactor scale_factor = Address::no_scale;
aoqi@6880 3813 if (arg_slot.is_constant()) {
aoqi@6880 3814 offset += arg_slot.as_constant() * stackElementSize;
aoqi@6880 3815 } else {
aoqi@6880 3816 scale_reg = arg_slot.as_register();
aoqi@6880 3817 scale_factor = Address::times_8;
aoqi@6880 3818 }
aoqi@9228 3819 // We don't push RA on stack in prepare_invoke.
aoqi@6880 3820 // offset += wordSize; // return PC is on stack
aoqi@6880 3821 if(scale_reg==NOREG) return Address(SP, offset);
aoqi@6880 3822 else {
aoqi@6880 3823 dsll(scale_reg, scale_reg, scale_factor);
aoqi@6880 3824 daddu(scale_reg, SP, scale_reg);
aoqi@6880 3825 return Address(scale_reg, offset);
aoqi@6880 3826 }
aoqi@6880 3827 }
aoqi@6880 3828
aoqi@6880 3829 SkipIfEqual::~SkipIfEqual() {
aoqi@6880 3830 _masm->bind(_label);
aoqi@6880 3831 }
aoqi@6880 3832
aoqi@6880 3833 void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2) {
aoqi@6880 3834 switch (size_in_bytes) {
aoqi@6880 3835 #ifndef _LP64
aoqi@6880 3836 case 8:
aoqi@6880 3837 assert(dst2 != noreg, "second dest register required");
aoqi@6880 3838 lw(dst, src);
aoqi@6880 3839 lw(dst2, src.plus_disp(BytesPerInt));
aoqi@6880 3840 break;
aoqi@6880 3841 #else
aoqi@6880 3842 case 8: ld(dst, src); break;
aoqi@6880 3843 #endif
aoqi@6880 3844 case 4: lw(dst, src); break;
aoqi@6880 3845 case 2: is_signed ? lh(dst, src) : lhu(dst, src); break;
aoqi@6880 3846 case 1: is_signed ? lb( dst, src) : lbu( dst, src); break;
aoqi@6880 3847 default: ShouldNotReachHere();
aoqi@6880 3848 }
aoqi@6880 3849 }
aoqi@6880 3850
aoqi@6880 3851 void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2) {
aoqi@6880 3852 switch (size_in_bytes) {
aoqi@6880 3853 #ifndef _LP64
aoqi@6880 3854 case 8:
aoqi@6880 3855 assert(src2 != noreg, "second source register required");
aoqi@6880 3856 sw(src, dst);
aoqi@6880 3857 sw(src2, dst.plus_disp(BytesPerInt));
aoqi@6880 3858 break;
aoqi@6880 3859 #else
aoqi@6880 3860 case 8: sd(src, dst); break;
aoqi@6880 3861 #endif
aoqi@6880 3862 case 4: sw(src, dst); break;
aoqi@6880 3863 case 2: sh(src, dst); break;
aoqi@6880 3864 case 1: sb(src, dst); break;
aoqi@6880 3865 default: ShouldNotReachHere();
aoqi@6880 3866 }
aoqi@6880 3867 }
aoqi@6880 3868
aoqi@6880 3869 // Look up the method for a megamorphic invokeinterface call.
aoqi@6880 3870 // The target method is determined by <intf_klass, itable_index>.
aoqi@6880 3871 // The receiver klass is in recv_klass.
aoqi@6880 3872 // On success, the result will be in method_result, and execution falls through.
aoqi@6880 3873 // On failure, execution transfers to the given label.
aoqi@6880 3874 void MacroAssembler::lookup_interface_method(Register recv_klass,
aoqi@6880 3875 Register intf_klass,
aoqi@6880 3876 RegisterOrConstant itable_index,
aoqi@6880 3877 Register method_result,
aoqi@6880 3878 Register scan_temp,
aoqi@9043 3879 Label& L_no_such_interface,
aoqi@9043 3880 bool return_method) {
aoqi@9043 3881 assert_different_registers(recv_klass, intf_klass, scan_temp, AT);
aoqi@9043 3882 assert_different_registers(method_result, intf_klass, scan_temp, AT);
aoqi@9043 3883 assert(recv_klass != method_result || !return_method,
aoqi@9043 3884 "recv_klass can be destroyed when method isn't needed");
aoqi@9043 3885
aoqi@6880 3886 assert(itable_index.is_constant() || itable_index.as_register() == method_result,
aoqi@6880 3887 "caller must use same register for non-constant itable index as for method");
aoqi@6880 3888
aoqi@6880 3889 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
aoqi@6880 3890 int vtable_base = InstanceKlass::vtable_start_offset() * wordSize;
aoqi@6880 3891 int itentry_off = itableMethodEntry::method_offset_in_bytes();
aoqi@6880 3892 int scan_step = itableOffsetEntry::size() * wordSize;
aoqi@6880 3893 int vte_size = vtableEntry::size() * wordSize;
aoqi@6880 3894 Address::ScaleFactor times_vte_scale = Address::times_ptr;
aoqi@6880 3895 assert(vte_size == wordSize, "else adjust times_vte_scale");
aoqi@6880 3896
aoqi@6880 3897 lw(scan_temp, Address(recv_klass, InstanceKlass::vtable_length_offset() * wordSize));
aoqi@6880 3898
aoqi@6880 3899 // %%% Could store the aligned, prescaled offset in the klassoop.
aoqi@6880 3900 dsll(scan_temp, scan_temp, times_vte_scale);
aoqi@6880 3901 daddu(scan_temp, recv_klass, scan_temp);
aoqi@6880 3902 daddiu(scan_temp, scan_temp, vtable_base);
aoqi@6880 3903 if (HeapWordsPerLong > 1) {
aoqi@6880 3904 // Round up to align_object_offset boundary
aoqi@6880 3905 // see code for InstanceKlass::start_of_itable!
aoqi@6880 3906 round_to(scan_temp, BytesPerLong);
aoqi@6880 3907 }
aoqi@6880 3908
aoqi@9043 3909 if (return_method) {
aoqi@9043 3910 // Adjust recv_klass by scaled itable_index, so we can free itable_index.
aoqi@9043 3911 assert(itableMethodEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
aoqi@9043 3912 if (itable_index.is_constant()) {
aoqi@9043 3913 set64(AT, (int)itable_index.is_constant());
aoqi@9043 3914 dsll(AT, AT, (int)Address::times_ptr);
aoqi@9043 3915 } else {
aoqi@9043 3916 dsll(AT, itable_index.as_register(), (int)Address::times_ptr);
aoqi@9043 3917 }
aoqi@9043 3918 daddu(AT, AT, recv_klass);
aoqi@9043 3919 daddiu(recv_klass, AT, itentry_off);
aoqi@6880 3920 }
aoqi@6880 3921
aoqi@6880 3922 Label search, found_method;
aoqi@6880 3923
aoqi@6880 3924 for (int peel = 1; peel >= 0; peel--) {
aoqi@6880 3925 ld(method_result, Address(scan_temp, itableOffsetEntry::interface_offset_in_bytes()));
aoqi@6880 3926
aoqi@6880 3927 if (peel) {
aoqi@6880 3928 beq(intf_klass, method_result, found_method);
zhaixiang@9144 3929 delayed()->nop();
aoqi@6880 3930 } else {
aoqi@6880 3931 bne(intf_klass, method_result, search);
zhaixiang@9144 3932 delayed()->nop();
aoqi@6880 3933 // (invert the test to fall through to found_method...)
aoqi@6880 3934 }
aoqi@6880 3935
aoqi@6880 3936 if (!peel) break;
aoqi@6880 3937
aoqi@6880 3938 bind(search);
aoqi@6880 3939
aoqi@6880 3940 // Check that the previous entry is non-null. A null entry means that
aoqi@6880 3941 // the receiver class doesn't implement the interface, and wasn't the
aoqi@6880 3942 // same as when the caller was compiled.
aoqi@6880 3943 beq(method_result, R0, L_no_such_interface);
zhaixiang@9144 3944 delayed()->nop();
aoqi@6880 3945 daddiu(scan_temp, scan_temp, scan_step);
aoqi@6880 3946 }
aoqi@6880 3947
aoqi@6880 3948 bind(found_method);
aoqi@6880 3949
aoqi@9043 3950 if (return_method) {
aoqi@9043 3951 // Got a hit.
aoqi@9043 3952 lw(scan_temp, Address(scan_temp, itableOffsetEntry::offset_offset_in_bytes()));
aoqi@9644 3953 if (UseLEXT1) {
aoqi@9043 3954 gsldx(method_result, recv_klass, scan_temp, 0);
aoqi@9043 3955 } else {
aoqi@9043 3956 daddu(AT, recv_klass, scan_temp);
zhaixiang@9267 3957 ld(method_result, AT, 0);
aoqi@9043 3958 }
aoqi@6880 3959 }
aoqi@6880 3960 }
aoqi@6880 3961
aoqi@6880 3962 // virtual method calling
aoqi@6880 3963 void MacroAssembler::lookup_virtual_method(Register recv_klass,
aoqi@6880 3964 RegisterOrConstant vtable_index,
aoqi@6880 3965 Register method_result) {
aoqi@6880 3966 Register tmp = GP;
aoqi@6880 3967 push(tmp);
aoqi@6880 3968
aoqi@6880 3969 if (vtable_index.is_constant()) {
aoqi@6880 3970 assert_different_registers(recv_klass, method_result, tmp);
aoqi@6880 3971 } else {
aoqi@6880 3972 assert_different_registers(recv_klass, method_result, vtable_index.as_register(), tmp);
aoqi@6880 3973 }
aoqi@6880 3974 const int base = InstanceKlass::vtable_start_offset() * wordSize;
aoqi@6880 3975 assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
aoqi@6880 3976 if (vtable_index.is_constant()) {
aoqi@6880 3977 set64(AT, vtable_index.as_constant());
aoqi@6880 3978 dsll(AT, AT, (int)Address::times_ptr);
aoqi@6880 3979 } else {
aoqi@6880 3980 dsll(AT, vtable_index.as_register(), (int)Address::times_ptr);
aoqi@6880 3981 }
aoqi@6880 3982 set64(tmp, base + vtableEntry::method_offset_in_bytes());
aoqi@6880 3983 daddu(tmp, tmp, AT);
aoqi@6880 3984 daddu(tmp, tmp, recv_klass);
aoqi@6880 3985 ld(method_result, tmp, 0);
aoqi@6880 3986
aoqi@6880 3987 pop(tmp);
aoqi@6880 3988 }
zhaixiang@9219 3989
zhaixiang@9219 3990 void MacroAssembler::store_for_type_by_register(Register src_reg, Register tmp_reg, int disp, BasicType type, bool wide) {
zhaixiang@9219 3991 switch (type) {
zhaixiang@9219 3992 case T_LONG:
zhaixiang@9219 3993 st_ptr(src_reg, tmp_reg, disp);
zhaixiang@9219 3994 break;
zhaixiang@9219 3995 case T_ARRAY:
zhaixiang@9219 3996 case T_OBJECT:
zhaixiang@9219 3997 if (UseCompressedOops && !wide) {
zhaixiang@9219 3998 sw(src_reg, tmp_reg, disp);
zhaixiang@9219 3999 } else {
zhaixiang@9219 4000 st_ptr(src_reg, tmp_reg, disp);
zhaixiang@9219 4001 }
zhaixiang@9219 4002 break;
zhaixiang@9219 4003 case T_ADDRESS:
zhaixiang@9219 4004 st_ptr(src_reg, tmp_reg, disp);
zhaixiang@9219 4005 break;
zhaixiang@9219 4006 case T_INT:
zhaixiang@9219 4007 sw(src_reg, tmp_reg, disp);
zhaixiang@9219 4008 break;
zhaixiang@9219 4009 case T_CHAR:
zhaixiang@9219 4010 case T_SHORT:
zhaixiang@9219 4011 sh(src_reg, tmp_reg, disp);
zhaixiang@9219 4012 break;
zhaixiang@9219 4013 case T_BYTE:
zhaixiang@9219 4014 case T_BOOLEAN:
zhaixiang@9219 4015 sb(src_reg, tmp_reg, disp);
zhaixiang@9219 4016 break;
zhaixiang@9219 4017 default:
zhaixiang@9219 4018 ShouldNotReachHere();
zhaixiang@9219 4019 }
zhaixiang@9219 4020 }
zhaixiang@9219 4021
zhaixiang@9219 4022 void MacroAssembler::store_for_type(Register src_reg, Address addr, BasicType type, bool wide) {
zhaixiang@9219 4023 Register tmp_reg = T9;
zhaixiang@9219 4024 Register index_reg = addr.index();
zhaixiang@9219 4025 if (index_reg == NOREG) {
zhaixiang@9219 4026 tmp_reg = NOREG;
zhaixiang@9219 4027 }
zhaixiang@9219 4028
zhaixiang@9219 4029 int scale = addr.scale();
zhaixiang@9219 4030 if (tmp_reg != NOREG && scale >= 0) {
zhaixiang@9219 4031 dsll(tmp_reg, index_reg, scale);
zhaixiang@9219 4032 }
zhaixiang@9219 4033
zhaixiang@9219 4034 int disp = addr.disp();
zhaixiang@9227 4035 bool disp_is_simm16 = true;
zhaixiang@9227 4036 if (!Assembler::is_simm16(disp)) {
zhaixiang@9227 4037 disp_is_simm16 = false;
zhaixiang@9227 4038 }
zhaixiang@9219 4039
zhaixiang@9219 4040 Register base_reg = addr.base();
zhaixiang@9219 4041 if (tmp_reg != NOREG) {
zhaixiang@9219 4042 assert_different_registers(tmp_reg, base_reg, index_reg);
zhaixiang@9219 4043 }
zhaixiang@9219 4044
zhaixiang@9219 4045 if (tmp_reg != NOREG) {
zhaixiang@9219 4046 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4047 if (!disp_is_simm16) {
zhaixiang@9227 4048 move(tmp_reg, disp);
zhaixiang@9227 4049 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4050 }
zhaixiang@9227 4051 store_for_type_by_register(src_reg, tmp_reg, disp_is_simm16 ? disp : 0, type, wide);
zhaixiang@9219 4052 } else {
zhaixiang@9227 4053 if (!disp_is_simm16) {
zhaixiang@9227 4054 tmp_reg = T9;
zhaixiang@9227 4055 assert_different_registers(tmp_reg, base_reg);
zhaixiang@9227 4056 move(tmp_reg, disp);
zhaixiang@9227 4057 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4058 }
zhaixiang@9227 4059 store_for_type_by_register(src_reg, disp_is_simm16 ? base_reg : tmp_reg, disp_is_simm16 ? disp : 0, type, wide);
zhaixiang@9219 4060 }
zhaixiang@9219 4061 }
zhaixiang@9219 4062
zhaixiang@9219 4063 void MacroAssembler::store_for_type_by_register(FloatRegister src_reg, Register tmp_reg, int disp, BasicType type) {
zhaixiang@9219 4064 switch (type) {
zhaixiang@9219 4065 case T_DOUBLE:
zhaixiang@9219 4066 sdc1(src_reg, tmp_reg, disp);
zhaixiang@9219 4067 break;
zhaixiang@9219 4068 case T_FLOAT:
zhaixiang@9219 4069 swc1(src_reg, tmp_reg, disp);
zhaixiang@9219 4070 break;
zhaixiang@9219 4071 default:
zhaixiang@9219 4072 ShouldNotReachHere();
zhaixiang@9219 4073 }
zhaixiang@9219 4074 }
zhaixiang@9219 4075
zhaixiang@9219 4076 void MacroAssembler::store_for_type(FloatRegister src_reg, Address addr, BasicType type) {
zhaixiang@9219 4077 Register tmp_reg = T9;
zhaixiang@9219 4078 Register index_reg = addr.index();
zhaixiang@9219 4079 if (index_reg == NOREG) {
zhaixiang@9219 4080 tmp_reg = NOREG;
zhaixiang@9219 4081 }
zhaixiang@9219 4082
zhaixiang@9219 4083 int scale = addr.scale();
zhaixiang@9219 4084 if (tmp_reg != NOREG && scale >= 0) {
zhaixiang@9219 4085 dsll(tmp_reg, index_reg, scale);
zhaixiang@9219 4086 }
zhaixiang@9219 4087
zhaixiang@9219 4088 int disp = addr.disp();
zhaixiang@9227 4089 bool disp_is_simm16 = true;
zhaixiang@9227 4090 if (!Assembler::is_simm16(disp)) {
zhaixiang@9227 4091 disp_is_simm16 = false;
zhaixiang@9227 4092 }
zhaixiang@9219 4093
zhaixiang@9219 4094 Register base_reg = addr.base();
zhaixiang@9219 4095 if (tmp_reg != NOREG) {
zhaixiang@9219 4096 assert_different_registers(tmp_reg, base_reg, index_reg);
zhaixiang@9219 4097 }
zhaixiang@9219 4098
zhaixiang@9219 4099 if (tmp_reg != NOREG) {
zhaixiang@9219 4100 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4101 if (!disp_is_simm16) {
zhaixiang@9227 4102 move(tmp_reg, disp);
zhaixiang@9227 4103 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4104 }
zhaixiang@9227 4105 store_for_type_by_register(src_reg, tmp_reg, disp_is_simm16 ? disp : 0, type);
zhaixiang@9219 4106 } else {
zhaixiang@9227 4107 if (!disp_is_simm16) {
zhaixiang@9227 4108 tmp_reg = T9;
zhaixiang@9227 4109 assert_different_registers(tmp_reg, base_reg);
zhaixiang@9227 4110 move(tmp_reg, disp);
zhaixiang@9227 4111 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4112 }
zhaixiang@9227 4113 store_for_type_by_register(src_reg, disp_is_simm16 ? base_reg : tmp_reg, disp_is_simm16 ? disp : 0, type);
zhaixiang@9219 4114 }
zhaixiang@9219 4115 }
zhaixiang@9219 4116
zhaixiang@9219 4117 void MacroAssembler::load_for_type_by_register(Register dst_reg, Register tmp_reg, int disp, BasicType type, bool wide) {
zhaixiang@9219 4118 switch (type) {
zhaixiang@9219 4119 case T_LONG:
zhaixiang@9219 4120 ld_ptr(dst_reg, tmp_reg, disp);
zhaixiang@9219 4121 break;
zhaixiang@9219 4122 case T_ARRAY:
zhaixiang@9219 4123 case T_OBJECT:
zhaixiang@9219 4124 if (UseCompressedOops && !wide) {
zhaixiang@9219 4125 lwu(dst_reg, tmp_reg, disp);
zhaixiang@9219 4126 } else {
zhaixiang@9219 4127 ld_ptr(dst_reg, tmp_reg, disp);
zhaixiang@9219 4128 }
zhaixiang@9219 4129 break;
zhaixiang@9219 4130 case T_ADDRESS:
zhaixiang@9219 4131 if (UseCompressedClassPointers && disp == oopDesc::klass_offset_in_bytes()) {
zhaixiang@9219 4132 lwu(dst_reg, tmp_reg, disp);
zhaixiang@9219 4133 } else {
zhaixiang@9219 4134 ld_ptr(dst_reg, tmp_reg, disp);
zhaixiang@9219 4135 }
zhaixiang@9219 4136 break;
zhaixiang@9219 4137 case T_INT:
zhaixiang@9219 4138 lw(dst_reg, tmp_reg, disp);
zhaixiang@9219 4139 break;
zhaixiang@9219 4140 case T_CHAR:
zhaixiang@9219 4141 lhu(dst_reg, tmp_reg, disp);
zhaixiang@9219 4142 break;
zhaixiang@9219 4143 case T_SHORT:
zhaixiang@9219 4144 lh(dst_reg, tmp_reg, disp);
zhaixiang@9219 4145 break;
zhaixiang@9219 4146 case T_BYTE:
zhaixiang@9219 4147 case T_BOOLEAN:
zhaixiang@9219 4148 lb(dst_reg, tmp_reg, disp);
zhaixiang@9219 4149 break;
zhaixiang@9219 4150 default:
zhaixiang@9219 4151 ShouldNotReachHere();
zhaixiang@9219 4152 }
zhaixiang@9219 4153 }
zhaixiang@9219 4154
zhaixiang@9219 4155 int MacroAssembler::load_for_type(Register dst_reg, Address addr, BasicType type, bool wide) {
zhaixiang@9219 4156 int code_offset = 0;
zhaixiang@9219 4157 Register tmp_reg = T9;
zhaixiang@9219 4158 Register index_reg = addr.index();
zhaixiang@9219 4159 if (index_reg == NOREG) {
zhaixiang@9219 4160 tmp_reg = NOREG;
zhaixiang@9219 4161 }
zhaixiang@9219 4162
zhaixiang@9219 4163 int scale = addr.scale();
zhaixiang@9219 4164 if (tmp_reg != NOREG && scale >= 0) {
zhaixiang@9219 4165 dsll(tmp_reg, index_reg, scale);
zhaixiang@9219 4166 }
zhaixiang@9219 4167
zhaixiang@9219 4168 int disp = addr.disp();
zhaixiang@9227 4169 bool disp_is_simm16 = true;
zhaixiang@9227 4170 if (!Assembler::is_simm16(disp)) {
zhaixiang@9227 4171 disp_is_simm16 = false;
zhaixiang@9227 4172 }
zhaixiang@9219 4173
zhaixiang@9219 4174 Register base_reg = addr.base();
zhaixiang@9219 4175 if (tmp_reg != NOREG) {
zhaixiang@9219 4176 assert_different_registers(tmp_reg, base_reg, index_reg);
zhaixiang@9219 4177 }
zhaixiang@9219 4178
zhaixiang@9219 4179 if (tmp_reg != NOREG) {
zhaixiang@9219 4180 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4181 if (!disp_is_simm16) {
zhaixiang@9227 4182 move(tmp_reg, disp);
zhaixiang@9227 4183 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4184 }
zhaixiang@9219 4185 code_offset = offset();
zhaixiang@9227 4186 load_for_type_by_register(dst_reg, tmp_reg, disp_is_simm16 ? disp : 0, type, wide);
zhaixiang@9219 4187 } else {
zhaixiang@9227 4188 if (!disp_is_simm16) {
zhaixiang@9227 4189 tmp_reg = T9;
zhaixiang@9227 4190 assert_different_registers(tmp_reg, base_reg);
zhaixiang@9227 4191 move(tmp_reg, disp);
zhaixiang@9227 4192 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4193 }
zhaixiang@9219 4194 code_offset = offset();
zhaixiang@9227 4195 load_for_type_by_register(dst_reg, disp_is_simm16 ? base_reg : tmp_reg, disp_is_simm16 ? disp : 0, type, wide);
zhaixiang@9219 4196 }
zhaixiang@9219 4197
zhaixiang@9219 4198 return code_offset;
zhaixiang@9219 4199 }
zhaixiang@9219 4200
zhaixiang@9219 4201 void MacroAssembler::load_for_type_by_register(FloatRegister dst_reg, Register tmp_reg, int disp, BasicType type) {
zhaixiang@9219 4202 switch (type) {
zhaixiang@9219 4203 case T_DOUBLE:
zhaixiang@9219 4204 ldc1(dst_reg, tmp_reg, disp);
zhaixiang@9219 4205 break;
zhaixiang@9219 4206 case T_FLOAT:
zhaixiang@9219 4207 lwc1(dst_reg, tmp_reg, disp);
zhaixiang@9219 4208 break;
zhaixiang@9219 4209 default:
zhaixiang@9219 4210 ShouldNotReachHere();
zhaixiang@9219 4211 }
zhaixiang@9219 4212 }
zhaixiang@9219 4213
zhaixiang@9219 4214 int MacroAssembler::load_for_type(FloatRegister dst_reg, Address addr, BasicType type) {
zhaixiang@9219 4215 int code_offset = 0;
zhaixiang@9219 4216 Register tmp_reg = T9;
zhaixiang@9219 4217 Register index_reg = addr.index();
zhaixiang@9219 4218 if (index_reg == NOREG) {
zhaixiang@9219 4219 tmp_reg = NOREG;
zhaixiang@9219 4220 }
zhaixiang@9219 4221
zhaixiang@9219 4222 int scale = addr.scale();
zhaixiang@9219 4223 if (tmp_reg != NOREG && scale >= 0) {
zhaixiang@9219 4224 dsll(tmp_reg, index_reg, scale);
zhaixiang@9219 4225 }
zhaixiang@9219 4226
zhaixiang@9219 4227 int disp = addr.disp();
zhaixiang@9227 4228 bool disp_is_simm16 = true;
zhaixiang@9227 4229 if (!Assembler::is_simm16(disp)) {
zhaixiang@9227 4230 disp_is_simm16 = false;
zhaixiang@9227 4231 }
zhaixiang@9219 4232
zhaixiang@9219 4233 Register base_reg = addr.base();
zhaixiang@9219 4234 if (tmp_reg != NOREG) {
zhaixiang@9219 4235 assert_different_registers(tmp_reg, base_reg, index_reg);
zhaixiang@9219 4236 }
zhaixiang@9219 4237
zhaixiang@9219 4238 if (tmp_reg != NOREG) {
zhaixiang@9219 4239 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4240 if (!disp_is_simm16) {
zhaixiang@9227 4241 move(tmp_reg, disp);
zhaixiang@9227 4242 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4243 }
zhaixiang@9219 4244 code_offset = offset();
zhaixiang@9227 4245 load_for_type_by_register(dst_reg, tmp_reg, disp_is_simm16 ? disp : 0, type);
zhaixiang@9219 4246 } else {
zhaixiang@9227 4247 if (!disp_is_simm16) {
zhaixiang@9227 4248 tmp_reg = T9;
zhaixiang@9227 4249 assert_different_registers(tmp_reg, base_reg);
zhaixiang@9227 4250 move(tmp_reg, disp);
zhaixiang@9227 4251 daddu(tmp_reg, base_reg, tmp_reg);
zhaixiang@9227 4252 }
zhaixiang@9219 4253 code_offset = offset();
zhaixiang@9227 4254 load_for_type_by_register(dst_reg, disp_is_simm16 ? base_reg : tmp_reg, disp_is_simm16 ? disp : 0, type);
zhaixiang@9219 4255 }
zhaixiang@9219 4256
zhaixiang@9219 4257 return code_offset;
zhaixiang@9219 4258 }
huangjia@9705 4259
huangjia@9705 4260 void MacroAssembler::clear_jweak_tag(Register possibly_jweak) {
huangjia@9705 4261 const int32_t inverted_jweak_mask = ~static_cast<int32_t>(JNIHandles::weak_tag_mask);
huangjia@9705 4262 STATIC_ASSERT(inverted_jweak_mask == -2); // otherwise check this code
huangjia@9705 4263 // The inverted mask is sign-extended
huangjia@9705 4264 move(AT, inverted_jweak_mask);
huangjia@9705 4265 andr(possibly_jweak, AT, possibly_jweak);
huangjia@9705 4266 }
huangjia@9705 4267
huangjia@9705 4268 void MacroAssembler::resolve_jobject(Register value,
huangjia@9705 4269 Register thread,
huangjia@9705 4270 Register tmp) {
huangjia@9705 4271 assert_different_registers(value, thread, tmp);
huangjia@9705 4272 Label done, not_weak;
huangjia@9705 4273 beq(value, R0, done); // Use NULL as-is.
huangjia@9705 4274 delayed()->nop();
huangjia@9705 4275 move(AT, JNIHandles::weak_tag_mask); // Test for jweak tag.
huangjia@9705 4276 andr(AT, value, AT);
huangjia@9705 4277 beq(AT, R0, not_weak);
huangjia@9705 4278 delayed()->nop();
huangjia@9705 4279 // Resolve jweak.
huangjia@9705 4280 ld(value, value, -JNIHandles::weak_tag_value);
huangjia@9705 4281 verify_oop(value);
huangjia@9705 4282 #if INCLUDE_ALL_GCS
huangjia@9705 4283 if (UseG1GC) {
huangjia@9705 4284 g1_write_barrier_pre(noreg /* obj */,
huangjia@9705 4285 value /* pre_val */,
huangjia@9705 4286 thread /* thread */,
huangjia@9705 4287 tmp /* tmp */,
huangjia@9705 4288 true /* tosca_live */,
huangjia@9705 4289 true /* expand_call */);
huangjia@9705 4290 }
huangjia@9705 4291 #endif // INCLUDE_ALL_GCS
huangjia@9705 4292 b(done);
huangjia@9705 4293 delayed()->nop();
huangjia@9705 4294 bind(not_weak);
huangjia@9705 4295 // Resolve (untagged) jobject.
huangjia@9705 4296 ld(value, value, 0);
huangjia@9705 4297 verify_oop(value);
huangjia@9705 4298 bind(done);
huangjia@9705 4299 }

mercurial