src/cpu/mips/vm/macroAssembler_mips.cpp

Wed, 20 Sep 2017 09:24:48 +0800

author
fujie
date
Wed, 20 Sep 2017 09:24:48 +0800
changeset 6886
2fa8027581f6
parent 6880
52ea28d233d2
child 7995
67882e9d8b35
permissions
-rw-r--r--

[Interpreter] Remove redundant andi for shift operations.

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

mercurial