1 /*
  2  * Copyright (c) 2021, 2022, 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  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "asm/assembler.hpp"
 27 #include "asm/assembler.inline.hpp"
 28 #include "opto/c2_MacroAssembler.hpp"
 29 #include "runtime/basicLock.hpp"
 30 
 31 // TODO: 8 bytes at a time? pre-fetch?
 32 // Compare char[] arrays aligned to 4 bytes.
 33 void C2_MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
 34                                            Register limit, Register result,
 35                                            Register chr1, Register chr2, Label& Ldone) {
 36   Label Lvector, Lloop;
 37 
 38   // if (ary1 == ary2)
 39   //     return true;
 40   cmpoop(ary1, ary2);
 41   b(Ldone, eq);
 42 
 43   // Note: limit contains number of bytes (2*char_elements) != 0.
 44   tst(limit, 0x2); // trailing character ?
 45   b(Lvector, eq);
 46 
 47   // compare the trailing char
 48   sub(limit, limit, sizeof(jchar));
 49   ldrh(chr1, Address(ary1, limit));
 50   ldrh(chr2, Address(ary2, limit));
 51   cmp(chr1, chr2);
 52   mov(result, 0, ne);     // not equal
 53   b(Ldone, ne);
 54 
 55   // only one char ?
 56   tst(limit, limit);
 57   mov(result, 1, eq);
 58   b(Ldone, eq);
 59 
 60   // word by word compare, don't need alignment check
 61   bind(Lvector);
 62 
 63   // Shift ary1 and ary2 to the end of the arrays, negate limit
 64   add(ary1, limit, ary1);
 65   add(ary2, limit, ary2);
 66   neg(limit, limit);
 67 
 68   bind(Lloop);
 69   ldr_u32(chr1, Address(ary1, limit));
 70   ldr_u32(chr2, Address(ary2, limit));
 71   cmp_32(chr1, chr2);
 72   mov(result, 0, ne);     // not equal
 73   b(Ldone, ne);
 74   adds(limit, limit, 2*sizeof(jchar));
 75   b(Lloop, ne);
 76 
 77   // Caller should set it:
 78   // mov(result_reg, 1);  //equal
 79 }
 80 
 81 void C2_MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2) {
 82   assert(VM_Version::supports_ldrex(), "unsupported, yet?");
 83 
 84   Register Rmark      = Rscratch2;
 85 
 86   assert(Roop != Rscratch, "");
 87   assert(Roop != Rmark, "");
 88   assert(Rbox != Rscratch, "");
 89   assert(Rbox != Rmark, "");
 90 
 91   Label fast_lock, done;
 92 
 93   if (DiagnoseSyncOnValueBasedClasses != 0) {
 94     load_klass(Rscratch, Roop);
 95     ldr_u32(Rscratch, Address(Rscratch, Klass::access_flags_offset()));
 96     tst(Rscratch, JVM_ACC_IS_VALUE_BASED_CLASS);
 97     b(done, ne);
 98   }
 99 
100   // TODO: Implement fast-locking.
101   tst(Roop, Roop); // Indicate failure -> take slow path
102   bind(done);
103 
104   // At this point flags are set as follows:
105   //  EQ -> Success
106   //  NE -> Failure, branch to slow path
107 }
108 
109 void C2_MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2) {
110   assert(VM_Version::supports_ldrex(), "unsupported, yet?");
111 
112   Register Rmark      = Rscratch2;
113 
114   assert(Roop != Rscratch, "");
115   assert(Roop != Rmark, "");
116   assert(Rbox != Rscratch, "");
117   assert(Rbox != Rmark, "");
118 
119   Label done;
120 
121   // TODO: Implement fast-unlocking.
122   tst(Roop, Roop); // Indicate failure -> take slow path
123   bind(done);
124 }
125