< prev index next >

src/cpu/arm/vm/interp_masm_arm.cpp

Print this page


   1 /*
   2  * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 459 }
 460 
 461 void InterpreterMacroAssembler::set_card(Register card_table_base, Address card_table_addr, Register tmp) {
 462 #ifdef AARCH64
 463   strb(ZR, card_table_addr);
 464 #else
 465   CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
 466   if ((((uintptr_t)ct->byte_map_base & 0xff) == 0)) {
 467     // Card table is aligned so the lowest byte of the table address base is zero.
 468     // This works only if the code is not saved for later use, possibly
 469     // in a context where the base would no longer be aligned.
 470     strb(card_table_base, card_table_addr);
 471   } else {
 472     mov(tmp, 0);
 473     strb(tmp, card_table_addr);
 474   }
 475 #endif // AARCH64
 476 }
 477 
 478 //////////////////////////////////////////////////////////////////////////////////



















































































































































































 479 
 480 
 481 // Java Expression Stack
 482 
 483 void InterpreterMacroAssembler::pop_ptr(Register r) {
 484   assert(r != Rstack_top, "unpredictable instruction");
 485   ldr(r, Address(Rstack_top, wordSize, post_indexed));
 486 }
 487 
 488 void InterpreterMacroAssembler::pop_i(Register r) {
 489   assert(r != Rstack_top, "unpredictable instruction");
 490   ldr_s32(r, Address(Rstack_top, wordSize, post_indexed));
 491   zap_high_non_significant_bits(r);
 492 }
 493 
 494 #ifdef AARCH64
 495 void InterpreterMacroAssembler::pop_l(Register r) {
 496   assert(r != Rstack_top, "unpredictable instruction");
 497   ldr(r, Address(Rstack_top, 2*wordSize, post_indexed));
 498 }


   1 /*
   2  * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 459 }
 460 
 461 void InterpreterMacroAssembler::set_card(Register card_table_base, Address card_table_addr, Register tmp) {
 462 #ifdef AARCH64
 463   strb(ZR, card_table_addr);
 464 #else
 465   CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(Universe::heap()->barrier_set());
 466   if ((((uintptr_t)ct->byte_map_base & 0xff) == 0)) {
 467     // Card table is aligned so the lowest byte of the table address base is zero.
 468     // This works only if the code is not saved for later use, possibly
 469     // in a context where the base would no longer be aligned.
 470     strb(card_table_base, card_table_addr);
 471   } else {
 472     mov(tmp, 0);
 473     strb(tmp, card_table_addr);
 474   }
 475 #endif // AARCH64
 476 }
 477 
 478 //////////////////////////////////////////////////////////////////////////////////
 479 #if INCLUDE_ALL_GCS
 480 
 481 // G1 pre-barrier.
 482 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
 483 // If store_addr != noreg, then previous value is loaded from [store_addr];
 484 // in such case store_addr and new_val registers are preserved;
 485 // otherwise pre_val register is preserved.
 486 void InterpreterMacroAssembler::g1_write_barrier_pre(Register store_addr,
 487                                                      Register new_val,
 488                                                      Register pre_val,
 489                                                      Register tmp1,
 490                                                      Register tmp2) {
 491   Label done;
 492   Label runtime;
 493 
 494   if (store_addr != noreg) {
 495     assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
 496   } else {
 497     assert (new_val == noreg, "should be");
 498     assert_different_registers(pre_val, tmp1, tmp2, noreg);
 499   }
 500 
 501   Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
 502                                         SATBMarkQueue::byte_offset_of_active()));
 503   Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
 504                                   SATBMarkQueue::byte_offset_of_index()));
 505   Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
 506                                    SATBMarkQueue::byte_offset_of_buf()));
 507 
 508   // Is marking active?
 509   assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
 510   ldrb(tmp1, in_progress);
 511   cbz(tmp1, done);
 512 
 513   // Do we need to load the previous value?
 514   if (store_addr != noreg) {
 515     load_heap_oop(pre_val, Address(store_addr, 0));
 516   }
 517 
 518   // Is the previous value null?
 519   cbz(pre_val, done);
 520 
 521   // Can we store original value in the thread's buffer?
 522   // Is index == 0?
 523   // (The index field is typed as size_t.)
 524 
 525   ldr(tmp1, index);           // tmp1 := *index_adr
 526   ldr(tmp2, buffer);
 527 
 528   subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
 529   b(runtime, lt);             // If negative, goto runtime
 530 
 531   str(tmp1, index);           // *index_adr := tmp1
 532 
 533   // Record the previous value
 534   str(pre_val, Address(tmp2, tmp1));
 535   b(done);
 536 
 537   bind(runtime);
 538 
 539   // save the live input values
 540 #ifdef AARCH64
 541   if (store_addr != noreg) {
 542     raw_push(store_addr, new_val);
 543   } else {
 544     raw_push(pre_val, ZR);
 545   }
 546 #else
 547   if (store_addr != noreg) {
 548     // avoid raw_push to support any ordering of store_addr and new_val
 549     push(RegisterSet(store_addr) | RegisterSet(new_val));
 550   } else {
 551     push(pre_val);
 552   }
 553 #endif // AARCH64
 554 
 555   if (pre_val != R0) {
 556     mov(R0, pre_val);
 557   }
 558   mov(R1, Rthread);
 559 
 560   call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
 561 
 562 #ifdef AARCH64
 563   if (store_addr != noreg) {
 564     raw_pop(store_addr, new_val);
 565   } else {
 566     raw_pop(pre_val, ZR);
 567   }
 568 #else
 569   if (store_addr != noreg) {
 570     pop(RegisterSet(store_addr) | RegisterSet(new_val));
 571   } else {
 572     pop(pre_val);
 573   }
 574 #endif // AARCH64
 575 
 576   bind(done);
 577 }
 578 
 579 // G1 post-barrier.
 580 // Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
 581 void InterpreterMacroAssembler::g1_write_barrier_post(Register store_addr,
 582                                                       Register new_val,
 583                                                       Register tmp1,
 584                                                       Register tmp2,
 585                                                       Register tmp3) {
 586 
 587   Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
 588                                         DirtyCardQueue::byte_offset_of_index()));
 589   Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
 590                                    DirtyCardQueue::byte_offset_of_buf()));
 591 
 592   BarrierSet* bs = Universe::heap()->barrier_set();
 593   CardTableModRefBS* ct = (CardTableModRefBS*)bs;
 594   Label done;
 595   Label runtime;
 596 
 597   // Does store cross heap regions?
 598 
 599   eor(tmp1, store_addr, new_val);
 600 #ifdef AARCH64
 601   logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
 602   cbz(tmp1, done);
 603 #else
 604   movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
 605   b(done, eq);
 606 #endif
 607 
 608   // crosses regions, storing NULL?
 609 
 610   cbz(new_val, done);
 611 
 612   // storing region crossing non-NULL, is card already dirty?
 613   const Register card_addr = tmp1;
 614   assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 615 
 616   mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
 617   add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
 618 
 619   ldrb(tmp2, Address(card_addr));
 620   cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
 621   b(done, eq);
 622 
 623   membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
 624 
 625   assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
 626   ldrb(tmp2, Address(card_addr));
 627   cbz(tmp2, done);
 628 
 629   // storing a region crossing, non-NULL oop, card is clean.
 630   // dirty card and log.
 631 
 632   strb(zero_register(tmp2), Address(card_addr));
 633 
 634   ldr(tmp2, queue_index);
 635   ldr(tmp3, buffer);
 636 
 637   subs(tmp2, tmp2, wordSize);
 638   b(runtime, lt); // go to runtime if now negative
 639 
 640   str(tmp2, queue_index);
 641 
 642   str(card_addr, Address(tmp3, tmp2));
 643   b(done);
 644 
 645   bind(runtime);
 646 
 647   if (card_addr != R0) {
 648     mov(R0, card_addr);
 649   }
 650   mov(R1, Rthread);
 651   call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
 652 
 653   bind(done);
 654 }
 655 
 656 #endif // INCLUDE_ALL_GCS
 657 //////////////////////////////////////////////////////////////////////////////////
 658 
 659 
 660 // Java Expression Stack
 661 
 662 void InterpreterMacroAssembler::pop_ptr(Register r) {
 663   assert(r != Rstack_top, "unpredictable instruction");
 664   ldr(r, Address(Rstack_top, wordSize, post_indexed));
 665 }
 666 
 667 void InterpreterMacroAssembler::pop_i(Register r) {
 668   assert(r != Rstack_top, "unpredictable instruction");
 669   ldr_s32(r, Address(Rstack_top, wordSize, post_indexed));
 670   zap_high_non_significant_bits(r);
 671 }
 672 
 673 #ifdef AARCH64
 674 void InterpreterMacroAssembler::pop_l(Register r) {
 675   assert(r != Rstack_top, "unpredictable instruction");
 676   ldr(r, Address(Rstack_top, 2*wordSize, post_indexed));
 677 }


< prev index next >