7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "asm/macroAssembler.inline.hpp"
26 #include "gc/shared/cardTable.hpp"
27 #include "gc/shared/cardTableModRefBS.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "nativeInst_sparc.hpp"
30 #include "oops/instanceOop.hpp"
31 #include "oops/method.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/methodHandles.hpp"
35 #include "runtime/frame.inline.hpp"
36 #include "runtime/handles.inline.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubCodeGenerator.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "runtime/thread.inline.hpp"
41 #ifdef COMPILER2
42 #include "opto/runtime.hpp"
43 #endif
44
45 // Declaration and definition of StubGenerator (no .hpp file).
46 // For a more detailed description of the stub routine structure
|
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #include "precompiled.hpp"
25 #include "asm/macroAssembler.inline.hpp"
26 #include "gc/shared/cardTable.hpp"
27 #include "gc/shared/cardTableBarrierSet.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "nativeInst_sparc.hpp"
30 #include "oops/instanceOop.hpp"
31 #include "oops/method.hpp"
32 #include "oops/objArrayKlass.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "prims/methodHandles.hpp"
35 #include "runtime/frame.inline.hpp"
36 #include "runtime/handles.inline.hpp"
37 #include "runtime/sharedRuntime.hpp"
38 #include "runtime/stubCodeGenerator.hpp"
39 #include "runtime/stubRoutines.hpp"
40 #include "runtime/thread.inline.hpp"
41 #ifdef COMPILER2
42 #include "opto/runtime.hpp"
43 #endif
44
45 // Declaration and definition of StubGenerator (no .hpp file).
46 // For a more detailed description of the stub routine structure
|
859 }
860 if (count->is_global()) {
861 __ mov(count, L1);
862 }
863 __ mov(addr->after_save(), O0);
864 // Get the count into O1
865 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
866 __ delayed()->mov(count->after_save(), O1);
867 if (addr->is_global()) {
868 __ mov(L0, addr);
869 }
870 if (count->is_global()) {
871 __ mov(L1, count);
872 }
873 __ restore();
874
875 __ bind(filtered);
876 DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
877 }
878 break;
879 case BarrierSet::CardTableModRef:
880 break;
881 default:
882 ShouldNotReachHere();
883 }
884 }
885 //
886 // Generate post-write barrier for array.
887 //
888 // Input:
889 // addr - register containing starting address
890 // count - register containing element count
891 // tmp - scratch register
892 //
893 // The input registers are overwritten.
894 //
895 void gen_write_ref_array_post_barrier(Register addr, Register count,
896 Register tmp) {
897 BarrierSet* bs = Universe::heap()->barrier_set();
898
899 switch (bs->kind()) {
900 case BarrierSet::G1BarrierSet:
901 {
902 // Get some new fresh output registers.
903 __ save_frame(0);
904 __ mov(addr->after_save(), O0);
905 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));
906 __ delayed()->mov(count->after_save(), O1);
907 __ restore();
908 }
909 break;
910 case BarrierSet::CardTableModRef:
911 {
912 CardTableModRefBS* ctbs = barrier_set_cast<CardTableModRefBS>(bs);
913 CardTable* ct = ctbs->card_table();
914 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
915 assert_different_registers(addr, count, tmp);
916
917 Label L_loop, L_done;
918
919 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
920
921 __ sll_ptr(count, LogBytesPerHeapOop, count);
922 __ sub(count, BytesPerHeapOop, count);
923 __ add(count, addr, count);
924 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
925 __ srl_ptr(addr, CardTable::card_shift, addr);
926 __ srl_ptr(count, CardTable::card_shift, count);
927 __ sub(count, addr, count);
928 AddressLiteral rs(ct->byte_map_base());
929 __ set(rs, tmp);
930 __ BIND(L_loop);
931 __ stb(G0, tmp, addr);
|
859 }
860 if (count->is_global()) {
861 __ mov(count, L1);
862 }
863 __ mov(addr->after_save(), O0);
864 // Get the count into O1
865 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
866 __ delayed()->mov(count->after_save(), O1);
867 if (addr->is_global()) {
868 __ mov(L0, addr);
869 }
870 if (count->is_global()) {
871 __ mov(L1, count);
872 }
873 __ restore();
874
875 __ bind(filtered);
876 DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
877 }
878 break;
879 case BarrierSet::CardTableBarrierSet:
880 break;
881 default:
882 ShouldNotReachHere();
883 }
884 }
885 //
886 // Generate post-write barrier for array.
887 //
888 // Input:
889 // addr - register containing starting address
890 // count - register containing element count
891 // tmp - scratch register
892 //
893 // The input registers are overwritten.
894 //
895 void gen_write_ref_array_post_barrier(Register addr, Register count,
896 Register tmp) {
897 BarrierSet* bs = Universe::heap()->barrier_set();
898
899 switch (bs->kind()) {
900 case BarrierSet::G1BarrierSet:
901 {
902 // Get some new fresh output registers.
903 __ save_frame(0);
904 __ mov(addr->after_save(), O0);
905 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));
906 __ delayed()->mov(count->after_save(), O1);
907 __ restore();
908 }
909 break;
910 case BarrierSet::CardTableBarrierSet:
911 {
912 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
913 CardTable* ct = ctbs->card_table();
914 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
915 assert_different_registers(addr, count, tmp);
916
917 Label L_loop, L_done;
918
919 __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
920
921 __ sll_ptr(count, LogBytesPerHeapOop, count);
922 __ sub(count, BytesPerHeapOop, count);
923 __ add(count, addr, count);
924 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
925 __ srl_ptr(addr, CardTable::card_shift, addr);
926 __ srl_ptr(count, CardTable::card_shift, count);
927 __ sub(count, addr, count);
928 AddressLiteral rs(ct->byte_map_base());
929 __ set(rs, tmp);
930 __ BIND(L_loop);
931 __ stb(G0, tmp, addr);
|