Path: blob/master/src/hotspot/cpu/arm/c2_MacroAssembler_arm.cpp
40930 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 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 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "asm/assembler.hpp"26#include "asm/assembler.inline.hpp"27#include "opto/c2_MacroAssembler.hpp"28#include "runtime/basicLock.hpp"2930// TODO: 8 bytes at a time? pre-fetch?31// Compare char[] arrays aligned to 4 bytes.32void C2_MacroAssembler::char_arrays_equals(Register ary1, Register ary2,33Register limit, Register result,34Register chr1, Register chr2, Label& Ldone) {35Label Lvector, Lloop;3637// if (ary1 == ary2)38// return true;39cmpoop(ary1, ary2);40b(Ldone, eq);4142// Note: limit contains number of bytes (2*char_elements) != 0.43tst(limit, 0x2); // trailing character ?44b(Lvector, eq);4546// compare the trailing char47sub(limit, limit, sizeof(jchar));48ldrh(chr1, Address(ary1, limit));49ldrh(chr2, Address(ary2, limit));50cmp(chr1, chr2);51mov(result, 0, ne); // not equal52b(Ldone, ne);5354// only one char ?55tst(limit, limit);56mov(result, 1, eq);57b(Ldone, eq);5859// word by word compare, dont't need alignment check60bind(Lvector);6162// Shift ary1 and ary2 to the end of the arrays, negate limit63add(ary1, limit, ary1);64add(ary2, limit, ary2);65neg(limit, limit);6667bind(Lloop);68ldr_u32(chr1, Address(ary1, limit));69ldr_u32(chr2, Address(ary2, limit));70cmp_32(chr1, chr2);71mov(result, 0, ne); // not equal72b(Ldone, ne);73adds(limit, limit, 2*sizeof(jchar));74b(Lloop, ne);7576// Caller should set it:77// mov(result_reg, 1); //equal78}7980void C2_MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2, Register scratch3) {81assert(VM_Version::supports_ldrex(), "unsupported, yet?");8283Register Rmark = Rscratch2;8485assert(Roop != Rscratch, "");86assert(Roop != Rmark, "");87assert(Rbox != Rscratch, "");88assert(Rbox != Rmark, "");8990Label fast_lock, done;9192if (DiagnoseSyncOnValueBasedClasses != 0) {93load_klass(Rscratch, Roop);94ldr_u32(Rscratch, Address(Rscratch, Klass::access_flags_offset()));95tst(Rscratch, JVM_ACC_IS_VALUE_BASED_CLASS);96b(done, ne);97}9899if (UseBiasedLocking && !UseOptoBiasInlining) {100assert(scratch3 != noreg, "need extra temporary for -XX:-UseOptoBiasInlining");101biased_locking_enter(Roop, Rmark, Rscratch, false, scratch3, done, done);102// Fall through if lock not biased otherwise branch to done103}104105// Invariant: Rmark loaded below does not contain biased lock pattern106107ldr(Rmark, Address(Roop, oopDesc::mark_offset_in_bytes()));108tst(Rmark, markWord::unlocked_value);109b(fast_lock, ne);110111// Check for recursive lock112// See comments in InterpreterMacroAssembler::lock_object for113// explanations on the fast recursive locking check.114// -1- test low 2 bits115movs(Rscratch, AsmOperand(Rmark, lsl, 30));116// -2- test (hdr - SP) if the low two bits are 0117sub(Rscratch, Rmark, SP, eq);118movs(Rscratch, AsmOperand(Rscratch, lsr, exact_log2(os::vm_page_size())), eq);119// If still 'eq' then recursive locking OK120// set to zero if recursive lock, set to non zero otherwise (see discussion in JDK-8153107)121str(Rscratch, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));122b(done);123124bind(fast_lock);125str(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));126127bool allow_fallthrough_on_failure = true;128bool one_shot = true;129cas_for_lock_acquire(Rmark, Rbox, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot);130131bind(done);132133// At this point flags are set as follows:134// EQ -> Success135// NE -> Failure, branch to slow path136}137138void C2_MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2) {139assert(VM_Version::supports_ldrex(), "unsupported, yet?");140141Register Rmark = Rscratch2;142143assert(Roop != Rscratch, "");144assert(Roop != Rmark, "");145assert(Rbox != Rscratch, "");146assert(Rbox != Rmark, "");147148Label done;149150if (UseBiasedLocking && !UseOptoBiasInlining) {151biased_locking_exit(Roop, Rscratch, done);152}153154ldr(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));155// If hdr is NULL, we've got recursive locking and there's nothing more to do156cmp(Rmark, 0);157b(done, eq);158159// Restore the object header160bool allow_fallthrough_on_failure = true;161bool one_shot = true;162cas_for_lock_release(Rmark, Rbox, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot);163164bind(done);165}166167168169