Quelle c2_MacroAssembler_x86.cpp
Sprache: C
|
|
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
*Copyright (c)2020,2022, affiliates. All.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
without even the warranty of MERCHANTABILITYor
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file
* ;if ,to ,
*
* You should have received a copy of the GNU General Public License version
* this ifnot the java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*contactOracle, 500 Parkway, Shores,CA
* or visit www."opto/intrinsicnodehppjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
* questions.
*
*/
#include "precompiled.hpp"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "oops/methodData.hpp"
#include "opto/c2_MacroAssembler.hpp"
#include "opto/intrinsicnode.hpp"
#include "opto/output.hpp"
#include "opto/opcodes.hpp"
#include "opto/subnode.hpp"
#include "runtime/objectMonitor.hpp"
#include /
#ifdef PRODUCT
#define BLOCK_COMMENT
#define STOP(errorjava.lang.StringIndexOutOfBoundsException: Index 68 out of boun ds for length 68
#else
# /Removefor
#define STOPframesize-=;
#endif
// C2 compiled method's prolog code.
void java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0
// WARNING: Initial instruction MUST be 5 bytes or longer so that
will be able to patch out the entry
// code safely. The push to verify stack depth is ok at 5 bytes,
// the frame allocation can be either 3 or 6 bytes. So if we don't do
java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68
// we have no frame. :-(
assert
( (-1))= , frame java.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 81
// Remove word for return addr
framesize -= subptr_imm32 java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 33
stack_bang_size java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
// Calls to C2R adapters often do not accept exceptional returns. // Majik cookie to verify stack depth
// If method sets FPU control word do it now
// stack. But the stack safety zone should account for that.
1, 4468289, 4497237.
if (fldcw(StubRoutines:86:java.lang.StringIndexOutOfBoundsException: Range [69, 66) out of bounds for length 71
()java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
// We always push rbp, so that on return to interpreter rbp, will be
// restored correctly and we can correct the stack.
push(rbp);
// Save caller's stack pointer into RBP if the frame pointer is preserved.
if ( pop(java.lang.StringIndexOutOfBoundsException: Range [13, 11) out of bounds for length 13
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
}
// Remove word for ebp
framesize -= wordSize;
// Create frame
if (framesize) {
r,framesize);
}
} else {
// Create frame (force generation of a 4 byte immediate value)
Label dummy_slow_path
// Save RBP register now.
framesize java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 48
movptr(Address(rsp, framesize), rbp/ real labels actualstub not codejava.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 104
if (PreserveFramePointer) {java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 39
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
if (framesize>0 {
addptr(rbp, framesize
}
}
}
if (VerifyStackAtCalls) { // Majik cookie to verify stack depth
framesize=wordSizejava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
movptr(Address(rsp framesize), int32_t)xbadb100d); 10java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
}
#ifndef _LP64
// If method sets FPU control word do it now
if (fp_mode_24b) {
fldcw(ExternalAddress(StubRoutines::x86: vjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 26
}
if (UseSSE
verify_FPU(0, "FPU stack must be clean on entry");
}
#endif
#ifdef ASSERT
if Vjava.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 27
(
rax;
mov(rax, java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 5
andptr(rax, StackAlignmentInBytes// input: abort_status
,StackAlignmentInBytes-wordSize)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
(ax;
jcc(Assembler::equal, L);
STOP("Stack is not properly aligned! if {
bind(L);
}
#endif
!
testl(abort_status1<);
#ifdef _(java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 108
// Branch if (random & (count// tmp, scr and flags are killed
/ We put the non-hot code of the nmethod entry barrier out-of-line in a stub.
Label dummy_slow_path assert(== ")
Label java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 23
Label* java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Label* continuation = &dummy_continuation;
(!Compile::urrent(-o(-in_scratch_emit_size() java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
// Use real labels from actual stub when not emitting code for the purpose of measuring its sizejava.lang.StringIndexOutOfBoundsException: Range [84, 70) out of bounds for length 85
java.lang.StringIndexOutOfBoundsException: Range [36, 32) out of bounds for length 39
slow_path = (tmpReg)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
continuation /Abortedtransactions 100
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
bs->nmethod_entry_barrier(this, slow_path, continuation);
}
#else
// Don't bother with out-of-line nmethod entry barrier stub for x86_32.
bs->nmethod_entry_barrier(this, NULL /* slow_path */, NULL /* continuation */);
#endif
}
}
void C2_MacroAssembler::emit_entry_barrier_stub(C2EntryBarrierStub* stub java.lang.StringIndexOutOfBoundsException: Range [36, 34) out of bounds for length 36
s-s();
call(RuntimeAddress(StubRoutines:ountIncrRate;
jmp(stub-, ,java.lang.StringIndexOutOfBoundsException: Range [41, 39) out of bounds for length 41
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
int::ntry_barrier_stub_size() {
return 10;
}
inline java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 11
switch (vlen_in_bytes
case : // fall-through
case 8: // fall-through
case :return Assembler:VX_128bit;
case 32: return Assembler::AVX_256bit;
:java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 42
default: {tmpRegjava.lang.StringIndexOutOfBoundsException: Range [39, 36) out of bounds for length 62
ShouldNotReachHere
return Assembler:mov_metadata(,method_data)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
}
}
#if INCLUDE_RTM_OPT(;
// Update rtm_counters based on abort status
// input: abort_status
// rtm_counters (RTMLockingCounters*)
// flags are killed
void C2_MacroAssemblerjava.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
atomic_incptrRTMLockingCountersjava.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 71
ifPrintPreciseRTMLockingStatistics) java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
for (int i = 0; i < RTMLockingCounters::ABORT_STATUS_LIMIT; i++) {
Label check_abort;
testl(abort_status, (1<<i));
java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
bind(check_abort);
}
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
// Branch if (random & (count-1) != 0), count is 2^n
// tmp, scr and flags are killed
java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 109
assert(tmp == rax, "");
assert(
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
andptr(tmp// output: retry_count_Reg decremented by 1
jccb(Assembler::notZero, brLabel);
}
// Perform abort ratio calculation, set no_rtm bit if high ratio
// input: rtm_counters_Reg (RTMLockingCounters* address)
// tmpReg, rtm_counters_Reg and flags are killed
void C2_MacroAssembler:: // if reason is in 0x6 and retry count !
Registerrtm_counters_Reg
::doneRetry
()
java.lang.StringIndexOutOfBoundsException: Range [56, 35) out of bounds for length 57
if (RTMLockingCalculationDelay// output: retry_count_Reg decremented by 1
// Delay calculation
movptrtmpReg()java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 95
testptr(tmpReg, tmpReg);
jccb(Assembler::equalLabelSpinLoop,SpinExitjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
// Abort ratio calculation only if abort_count > RTMAbortThreshold,;
dtransactions java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 47
// All transactions = total_count * RTMTotalCountIncrRate
nsactions> java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 83
movptr(tmpReg, Address(rtm_counters_Reg, RTMLockingCounters::abort_count_offset()));
cmpptr jmpretryLabel);
jccb(Assembler::below bind);
imulptr(tmpReg, tmpReg, 100);
Register scrReg = rtm_counters_Reg;
movptr(scrReg, java.lang.StringIndexOutOfBoundsException: Range [17, 1) out of bounds for length 1
imulptr(scrReg, scrRegvoid::(Register objReg,Register tmpReg Register ,
Register retry_on_abort_count_Reg,
cmpptr(tmpReg, scrReg);
jccb(Assembler::below, L_check_always_rtm1);
if (method_data != NULL) { RTMLockingCounters* stack_rtm_counters,
// set rtm_state to "no rtm" in MDO
mov_metadata(tmpReg, method_data);
Label ,Label&IsInflated
orlAddress :)) );
}
jmpb(_one;
bind(L_check_always_rtm1);
// Reload RTMLockingCounters* address
lea(rtm_counters_Reg, ExternalAddress L_rtm_retry L_decrement_retry,L_on_abort;
bind(L_check_always_rtm2);
movptr(tmpReg, Address(rtm_counters_Reg
cmpptr( movl(retry_on_abort_count_Reg );// Retry on abort
jccb(Assembler: bind(L_rtm_retry
if (java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 3
// set rtm_state to "always rtm" in MDO(tmpReg, markWord::monitor_value); // inflated vs stack-locked|neutral
mov_metadata(tmpReg, method_data);
lock();
orl(Address( (:,IsInflatedjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
}
bind(L_done);
}
// Update counters and perform abort ratio calculation
// input: abort_status_Reg
// rtm_counters_Reg, flags are killed
void C2_MacroAssembler::(,scrReg L_noincrement)java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89
,
java.lang.StringIndexOutOfBoundsException: Range [58, 56) out of bounds for length 71
Metadata java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
bind(_noincrement;
assert( java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
// update rtm counters based on rax value at abort
// reads abort_status_Reg, updates flags
lea(rtm_counters_Reg, ExternalAddress((address andptr(mpReg,markWord::lock_mask_in_place); // look at 2 lock bits
rtm_counters_update(abort_status_Reg, cmpptr(mpReg :unlocked_value); // bits = 01 unlocked
if (jcc(Assemblere,DONE_LABEL));
// Save abort status because abort_status_Reg is used by following code.
if(java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 28
push( (UseRTMXendForLockBusy
}
assert(rtm_counters != NULL, "should movptr(abort_status_Reg,02; // Set the abort status to 2 (so we can retry)
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 3
// restore abort status
if (RTMRetryCountbind(L_on_abort)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
(abort_status_Reg)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
}
}
}
// Retry on abort if abort's status is 0x6: can retry (0x2) | memory conflict (0x4)
// inputs: retry_count_Reg
// : abort_status_Reg
// output: retry_count_Reg decremented by 1
// flags are killed
voidC2_MacroAssembler::rtm_retry_lock_on_abort(Register retry_count_Reg, abort_status_Reg,Label retryLabel){
Label doneRetry // retry on lock abort if abort status is 'can retry' (0x2) or 'memory conflict' (0x4)
abort_status_Reg =rax,")java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
// The abort reason bits are in eax (see all states in rtmLocking.hpp)// Use RTM for inflating locks
// 0x6 = conflict on which we can retry (0x2) | memory conflict (0x4)
// if reason is in 0x6 and retry count != 0 then retry
andptrvoidC2_MacroAssembler:tm_inflated_locking(Register objReg,Register boxReg,Register ,
jccb Register ,Register retry_on_busy_count_Reg
testl(retry_count_Reg, Register retry_on_abort_count_Reg,
jccb(AssemblerRTMLockingCounters* rtm_counters
pause();
decrementl(retry_count_Reg);
jmp(retryLabel);
bind(doneRetry);
}
// Spin and retry if lock is busy,
// inputs: box_Reg (monitor address)
// : retry_count_Reg
// output: retry_count_Reg decremented by 1
// : clear z flag if retry count exceeded
// tmp_Reg, scr_Reg, flags are killed
void assert(==rdx,")java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
tmp_Reg, Register Label& ,0, <nt32_t>(::).value())java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
SpinLoop ,
int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner);
testl(retry_count_Reg, retry_count_Reg);
jccb(Assembler::zero, doneRetry);
decrementl(retry_count_Reg);
movptr(scr_Reg, movl(retry_on_busy_count_Reg, RT) / Retry on lock busy
bind(SpinLoop);
pause();
decrementl(scr_Reg);
jccbbindL_rtm_retry);
movptr(tmp_Reg, Address(box_Reg, owner_offset));
testptr(tmp_Reg, tmp_Reg);
jccb(Assembler: if (rintPreciseRTMLockingStatistics profile_rtm) {
bind(SpinExit);
jmpretryLabel;
bind(doneRetry)if (TMTotalCountIncrRate >1 {
incrementl(retry_count_Reg) // tmpReg, scrReg and flags are killed
}
// Use RTM for normal stack locks
// Input: objReg (object to lock)
voidbranch_on_random_using_rdtsct,RTMTotalCountIncrRate )
Register assert(rtm_counters != NULL, "should not be NULL when";
* ,
Metadata* ()
();
assert(UseRTMForStackLocks, "why call this movptr(tmpReg, Address(objReg, oopDesc::mark_offset_
assert(tmpReg == rax, "");
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 28
ement_retry
if ()
movl(retry_on_abort_count_Regjava.lang.StringIndexOutOfBoundsException: Range [27, 25) out of bounds for length 27
bindLrtm_retry
}
movptr(tmpReg, Address( (PrintPreciseRTMLockingStatistics
testptrtmpReg markWord:monitor_value) // inflated vs stack-locked|neutral
jcc(Assembler::notZero, IsInflatedif(TMRetryCount > 0) {
if (PrintPreciseRTMLockingStatistics
Label L_noincrement;
if (rtm_retry_lock_on_abort,L_rtm_retry)java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
// tmpReg, scrReg and flags are killed
branch_on_random_using_rdtsc(tmpReg
}
assert(stack_rtm_counters != NULL, EAX is theimplicit comparand
atomic_incptr ;
bind(L_noincrement);
}
);
Registerjava.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 30
andptr(tmpReg, markWord::java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 0
cmpptr(tmpReg A: );
jcc(Assembler:equal,DONE_LABELjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
Register abort_status_Reg = tmpReg; // status of abort is stored in RAX
if (UseRTMXendForLockBusyjava.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
xend()endif
movptr
jmp(L_decrement_retry);
}
else {
xabort(0);
}
bind(L_on_abort);
if // See also: java.lang.StringIndexOutOfBoundsException: Range [0, 24) out of bounds for length 2
rtm_profiling(abort_status_Reg,// (rax,=Obj, rbx=Self// indications in the icc.ZFlag. fast_lock and fast_unlock would simply
}
bind(L_decrement_retry);
if (RTMRetryCount > 0) {
// retry on lock abort if abort status is 'can retry' (0x2) or 'memory conflict' (0x4)
rtm_retry_lock_on_abort(retry_on_abort_count_Reg, abort_status_Reg, java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 71
}
}
// Use RTM for inflating locks
// inputs: objReg (object to lock)
// boxReg (on-stack box address (displaced header location) - KILLED)
// tmpReg (ObjectMonitor address + markWord::monitor_value)
void C2_MacroAssembler::rtm_inflated_locking(Register objReg, heir pleasure.
Register scrReg, Register retry_on_busy_count_Reg// to park() or unpark() threads. We'd also need a few more unsafe operators
Register retry_on_abort_count_Reg,
RTMLockingCounters* rtm_counters,
Metadata* method_data, bool profile_rtm,
// Instead, we're stuck with a rather awkward and brittle register assignments below.
//
assert(tmpReg// * Eliminate the sp-proximity tests and just use "== Self" tests instead.
assertt/ Alternately, use a better sp-proximity test.
Label L_rtm_retry, L_decrement_retry, L_on_abort;
int // Either one is sufficient to uniquely identify a thread.
movptr(Address(boxReg, 0//
movptr(boxReg, tmpReg)// object is locked by the calling thread but the waitlist is empty.
if (RTMRetryCount > 0) {
movl(java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 2
movl(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort
bind(// So we have branches to// Instead, it might be better to have C2 pass a "FailureLabel"
}
if (PrintPreciseRTMLockingStatistics || profile_rtm// FailureLabel
// box: on-stack box // rax,: tmp -- KILLED
if(TMTotalCountIncrRate >1 {
// tmpReg, scrReg and flags are killed
branch_on_random_using_rdtsc(tmpReg, java.lang.StringIndexOutOfBoundsException: Range [72, 71) out of bounds for length 72
}
assert(rtm_counters // Ensure the register assignments are disjoint
atomic_incptr(((address)tm_counters->total_count_addr()), scrReg);
bind(L_noincrement);
}
xbegin
trtmpReg,Address(objReg oopDesc:m());
movptr(tmpReg, Address(tmpReg, owner_offset));
testptr(tmpReg, tmpReg);
jccAssembler:z, )
if (UseRTMXendForLockBusy {
xend()assert(cx2Reg =noreg";
( ,scrReg);
}
else {
xabort(;
}
bind(L_on_abort);
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 73
if (java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
rtm_profiling(abort_status_Reg, scrReg, rtm_counters, method_data, java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 20
}
if (RTMRetryCount > 0) {
// retry on lock abort if abort status is 'can retry' (0x2) or 'memory conflict' (0x4)// * stack-locked
rtm_retry_lock_on_abort(retry_on_abort_count_Reg, abort_status_Reg, L_rtm_retry);
}
//
testptr(tmpReg, tmpReg)// = sp-proximity test generates false-negative
jccb(Assembler:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// Appears unlocked - try to swing _owner from null to non-null.
s which the implicit .
#ifdef _LP64
= r15_thread
#else
scrReg);
Register threadReg = (, )java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
#endif
lock();#
cmpxchgptr if( & use_rtm
if( > 0) java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
// success done else retry
jccbAssembler::equal, DONE_LABEL) ;
bind(L_decrement_retry);
// Spin and retry if lock is busy.
rtm_retry_lock_on_busy(retry_on_busy_count_Reg, boxReg, tmpReg, scrReg, L_rtm_retry)DONE_LABEL IsInflated)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
}
else {
bind(L_decrement_retry);
}
}
#endif // INCLUDE_RTM_OPT
// fast_lock and fast_unlock used by C2
// Because the transitions from emitted code to the runtime
// monitorenter/exit helper stubs are so slow it's critical that
// we inline both the stack-locking fast path and the inflated fast path.
//
// See also: cmpFastLock and cmpFastUnlock.
//
// What follows is a specialized inline transliteration of the code
// in enter() and exit(). If we're concerned about I$ bloat another
// option would be to emit TrySlowEnter and TrySlowExit methods
// at startup-time. These methods would accept arguments as
// (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure
// indications in the icc.ZFlag. fast_lock and fast_unlock would simply
// marshal the arguments and emit calls to TrySlowEnter and TrySlowExit.
// In practice, however, the # of lock sites is bounded and is usually small.
// Besides the call overhead, TrySlowEnter and TrySlowExit might suffer
// if the processor uses simple bimodal branch predictors keyed by EIP
// Since the helper routines would be called from multiple synchronization
// sites.
//
// An even better approach would be write "MonitorEnter()" and "MonitorExit()"
// in java - using j.u.c and unsafe - and just bind the lock and unlock sites
// to those specialized methods. That'd give us a mostly platform-independent
// implementation that the JITs could optimize and inline at their pleasure.
// Done correctly, the only time we'd need to cross to native could would be
// to park() or unpark() threads. We'd also need a few more unsafe operators
// to (a) prevent compiler-JIT reordering of non-volatile accesses, and
// (b) explicit barriers or fence operations.
//
// TODO:
//
// * Arrange for C2 to pass "Self" into fast_lock and fast_unlock in one of the registers (scr).
// This avoids manifesting the Self pointer in the fast_lock and fast_unlock terminals.
// Given TLAB allocation, Self is usually manifested in a register, so passing it into
// the lock operators would typically be faster than reifying Self.
//
// * Ideally I'd define the primitives as:
// fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED.
// fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED
// Unfortunately ADLC bugs prevent us from expressing the ideal form.
// Instead, we're stuck with a rather awkward and brittle register assignments below.
// Furthermore the register assignments are overconstrained, possibly resulting in
// sub-optimal code near the synchronization site.
//
// * Eliminate the sp-proximity tests and just use "== Self" tests instead.
// Alternately, use a better sp-proximity test.
//
// * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value.
// Either one is sufficient to uniquely identify a thread.
// TODO: eliminate use of sp in _owner and use get_thread(tr) instead.
//
// * Intrinsify notify() and notifyAll() for the common cases where the
// object is locked by the calling thread but the waitlist is empty.
// avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll().
//
// * use jccb and jmpb instead of jcc and jmp to improve code density.
// But beware of excessive branch density on AMD Opterons.
//
// * Both fast_lock and fast_unlock set the ICC.ZF to indicate success
// or failure of the fast path. If the fast path fails then we pass
// control to the slow path, typically in C. In fast_lock and
// fast_unlock we often branch to DONE_LABEL, just to find that C2
// will emit a conditional branch immediately after the node.
// So we have branches to branches and lots of ICC.ZF games.
// Instead, it might be better to have C2 pass a "FailureLabel"
// into fast_lock and fast_unlock. In the case of success, control
// will drop through the node. ICC.ZF is undefined at exit.
// In the case of failure, the node will branch directly to the
// FailureLabel
// obj: object to lock
// box: on-stack box address (displaced header location) - KILLED
// rax,: tmp -- KILLED
// scr: tmp -- KILLED
java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 84
RTMLockingCounters* rtm_counters,
Metadata* method_data,
bool use_rtm, bool profile_rtm) {
// Ensure the register assignments are disjoint
assert(tmpReg = rax,");
if (use_rtm) {
assert_different_registers(objReg, boxReg, tmpReg, scrReg, cx1Reg, cx2Reg);
} else {
assert(cx2Reg == noreg, "");
assert_different_registers(objReg, boxReg, tmpReg, scrReg)/
}
// Possible cases that we'll encounter in fast_lock
// ------------------------------------------------
// * Inflated
// -- unlocked
// -- Locked
// = by self movq(, tmpReg);
// = by other
// * stack-locked
java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 18
// = sp-proximity test hits
// = sp-proximity test generates false-negative
// -- by other
//
Label IsInflated, DONE_LABEL, NO_COUNT, COUNT;
if ( // Propagate.ZF into DONE_LABEL
cx1Reg;
movl(tmpReg, java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 0
testl(tmpReg, JVM_ACC_IS_VALUE_BASED_CLASS);
jcc(Assembler::notZero, DONE_LABEL);
}
#ifINCLUDE_RTM_OPT
if (UseRTMForStackLocks && use_rtm) {
assert(!UseHeavyMonitors, "+UseHeavyMonitors and +UseRTMForStackLocks are mutually exclusive");
rtm_stack_locking(objReg, tmpReg, scrReg, cx2Reg,
stack_rtm_counters, method_data, profile_rtm,
}
#endif // INCLUDE_RTM_OPT
movptr(tmpReg, Address(objReg, oopDesc:
testptr(, markWord::monitor_value);
jccb(Assembler::notZero, IsInflated);
if (!UseHeavyMonitors) {
ing ...
orptr (tmpReg, markWord::unlocked_value);
movptr(Address(boxReg, 0), tmpReg) bind(COUNT);
lock();
cmpxchgptr(boxReg, Address(objReg, oopDesc:: get_thread()java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
jcc(Assembler::equal, COUNT); // Success
// Recursive locking.
// The object is stack-locked: markword contains stack pointer to BasicLock.
// Locked by current thread if difference with current SP is less than one page.
subptr(tmpReg, rsp);
// Next instruction set ZFlag == 1 (Success) if difference is less then one page.
andptr(tmpReg, (int32_t) ( // At NO_COUNT the icc ZFlag is set as follows ...
movptr(Address(boxReg, 0), tmpReg);
} else {
// Clear ZF so that we take the slow path at the DONE label. objReg is known to be not 0.
testptr(objReg, objReg);
}
jmp(DONE_LABEL);
bind(IsInflated);
// The object is inflated. tmpReg contains pointer to ObjectMonitor* + markWord::monitor_value
#if INCLUDE_RTM_OPT
// Use the same RTM locking code in 32- and 64-bit VM.
if (use_rtm) {
rtm_inflated_locking(objReg, boxReg// interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
rtm_counters, method_data, profile_rtm, DONE_LABEL);
} else {
#endif // INCLUDE_RTM_OPT
#ifndef _LP64
// The object is inflated.
// boxReg refers to the on-stack BasicLock in the current frame.
// We'd like to write:
// set box->_displaced_header = markWord::unused_mark(). Any non-0 value suffices.
// This is convenient but results a ST-before-CAS penalty. The following CAS suffers
// additional latency as we have another ST in the store buffer that must drain.
// avoid ST-before-CAS
// register juggle because we need tmpReg for cmpxchgptr below
movptr(scrReg, boxReg);
movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2]// B() doesn't have provably balanced locking so it runs in the interpreter.
// Optimistic form: consider XORL tmpReg,tmpReg
is still locked by A().
// Appears unlocked - try to swing _owner from null to non-null.
// Ideally, I'd manifest "Self" with get_thread and then attempt
// to CAS the register containing Self into m->Owner.// should not be unlocked by "normal" java-level locking and vice-versa. The specification
// But we don't have enough registers, so instead we can either try to CAS
// rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds
// we later store "Self" into m->Owner. Transiently storing a stack address// In the interest of performance we elide m->Owner==Self check in unlock.
// (rsp or the address of the box) into m->owner is harmless.
// Invariant: tmpReg = 0. tmpReg is EAX which theimplicit cmpxchg comparand.
lock();
cmpxchgptr(scrReg, Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
movptrAddress( 0) 3); -_isplaced_header = 3
// If we weren't able to swing _owner from NULL to the BasicLock
// then take the slow path.
jccb (Assembler::notZero,
// update _owner from BasicLock to thread
get_thread (scrReg); if (UseRTMForStackLocks &&use_rtm) {
asse(!UseHeavyMonitors, "+UseHeavyMonitors and +UseRTMForStackLocks are mutually exclusive");
xorptr(Label L_regular_unlock
// If the CAS fails we can either retry or pass control to the slow path.
// We use the latter tactic.
// Pass the CAS result in the icc.ZFlag into DONE_LABEL
// If the CAS was successful ...
// Self has acquired the lock
// Invariant: m->_recursions should already be 0, so we don't need to explicitly set it.
// Intentional fall-through into DONE_LABEL ...
#else // _LP64
// It's inflated and we use scrReg for ObjectMonitor* in this section.
movq(scrReg tmpReg)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
xorq( );
lock();
cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)))java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 3
// Unconditionally set box->_displaced_header = markWord::unused_mark().
thisstyle of movptr will r10 which typically .
movptr( (::zero,COUNT)
// Propagate ICC.ZF from CAS above into DONE_LABEL.
java.lang.StringIndexOutOfBoundsException: Range [2, 6) out of bounds for length 3
cmpptr(r15_thread, rax); // Check if we are already the owner (recursive lock)
jccb(Assembler::notEqual, NO_COUNT); // If not recursive, ZF = 0 at this point (fail)
incq(Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(recursions)));
xorq(rax, rax); // Set ZF = 1 (success) for recursive lock, denoting locking success
#endif // _LP64
#if INCLUDE_RTM_OPT
} // use_rtm()
#
bind(DONE_LABEL);
// ZFlag == 1 count in fast path
// ZFlag == 0 count in slow path
jccb(Assembler::notZero, NO_COUNT); // jump if ZFlag == 0
bindCOUNT)
unt monitors infastpath
#ifndef _LP64
(tmpReg)java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
incrementl:held_monitor_count_offset())
#else // _LP64
incrementq(Address(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 11
#endif
xorl(tmpReg, tmpReg); // Set ZF == 1
bind(NO_COUNT);
// At NO_COUNT the icc ZFlag is set as follows ...
// fast_unlock uses the same protocol.
// ZFlag == 1 -> Success
// ZFlag == 0 -> Failure - force control through the slow path
}
// obj: object to unlock
// box: box address (displaced header location), killed. Must be EAX.
// tmp: killed, cannot be obj nor box.
//
// Some commentary on balanced locking:
//
// fast_lock and fast_unlock are emitted only for provably balanced lock sites.
// Methods that don't have provably balanced locking are forced to run in the
// interpreter - such methods won't be compiled to use fast_lock and fast_unlock.
// The interpreter provides two properties:
// I1: At return-time the interpreter automatically and quietly unlocks any
// objects acquired the current activation (frame). Recall that the
// interpreter maintains an on-stack list of locks currently held by
// a frame.
// I2: If a method attempts to unlock an object that is not held by the
// the frame the interpreter throws IMSX.
//
// Lets say A(), which has provably balanced locking, acquires O and then calls B().
// B() doesn't have provably balanced locking so it runs in the interpreter.
// Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O
// is still locked by A().
//
// The only other source of unbalanced locking would be JNI. The "Java Native Interface:
// Programmer's Guide and Specification" claims that an object locked by jni_monitorenter
// should not be unlocked by "normal" java-level locking and vice-versa. The specification
// doesn't specify what will occur if a program engages in such mixed-mode locking, however.
// Arguably given that the spec legislates the JNI case as undefined our implementation
// could reasonably *avoid* checking owner in fast_unlock().
// In the interest of performance we elide m->Owner==Self check in unlock.
// A perfectly viable alternative is to elide the owner check except when
// Xcheck:jni is enabled.
void C2_MacroAssembler:: movptr(boxReg, Address(tmpReg OM_OFFSET_NO_MONITOR_VALUE_TAG()));
assert( = rax ");
assert_different_registers(objReg, boxReg, tmpReg);
DONE_LABEL Stacked, OUNT,NO_COUNT;
#if INCLUDE_RTM_OPT
if (java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 21
assert(!UseHeavyMonitors, "+UseHeavyMonitors;
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0
movptrtmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())) / fetch
andptr(tmpReg jccbAssembler::equal, LNotRecursive);
cmpptr(tmpReg, markWord::unlocked_value); // bits = 01 unlocked
jccb(Assembler::otEqual, L_regular_unlock); // if !HLE RegularLock
xend(); // otherwise end...
jmp(); // ... and we're done
bind(java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
ejava.lang.StringIndexOutOfBoundsException: Range [6, 7) out of bounds for length 6
if (!UseHeavyMonitors// Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
cmpptrAddress(oxReg, ) );// Examine the displaced header
jcc (Assembler::zero, COUNT); // 0 indicates recursive stack-lock
}
objReg oopDesc:mark_offset_in_bytes))); /Examine theobject' markword
if (!UseHeavyMonitors) {
testptr(tmpReg, markWord::monitor_value); // Inflated?
jccb (Assembler::.
}
// It's inflated.
#ifINCLUDE_RTM_OPT
if (use_rtm) {
Label L_regular_inflated_unlockboxReg ;
java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 76
testptr(boxReg, boxReg);
jccb(Assembler::notZero, L_regular_inflated_unlock
java.lang.StringIndexOutOfBoundsException: Range [86, 87) out of bounds for length 86
jmpb(lock) rsp0,0;
bind(L_regular_inflated_unlock);
}
#endif
// Despite our balanced locking property we still check that m->_owner == Self
// as java routines or native JNI code called by this thread might
// have released the lock.
// state in _succ so we can avoid fetching EntryList|cxq.
//
// If there's no contention try a 1-0 exit. That is, exit without
// a costly MEMBAR or CAS. See synchronizer.cpp for details on how
// we detect and recover from the race that the 1-0 exit admits.
//
// Conceptually fast_unlock() must execute a STST|LDST "release" barrier
// before it STs null into _owner, releasing the lock. Updates
// to data protected by the critical section must be visible before
// we drop the lock (and thus before any other thread could acquire
// the lock and observe the fields protected by the lock).
// IA32's memory-model is SPO, so STs are ordered with respect to// length while by virtue of passing control into the slow path.
// See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html.
# lock()
// Note that we could employ various encoding schemes to reduce
below currently ) to just 2or.
// Refer to the comments in synchronizer.cpp.
// In practice the chain of fetches doesn't seem to impact performance, however.
xorptr(boxReg, boxReg);
orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG/ weredone (andexit asuccess)
A:otZero,DONE_LABEL);
movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG// Intentional fall-through into slow path
orptr(boxReg, Address(tmpReg, bind(LGoSlowPath)java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
jccb (Assembler:
movptr(Address ( 0;
jmpb (DONE_LABEL);
#else // _LP64
// It's inflated
Label CheckSucc, (java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 20
cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG((recursions)),0)
jccb(Assembler:equal,LNotRecursive);
// Recursive inflated unlock
decq(Address(tmpReg, java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 19
jmpb(LSuccess);
bind(LNotRecursive);
(boxReg t, c))java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
orptr( tmpReg,OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList));
jccb (Assembler::notZero, CheckSucc);
// Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address(tmpReg, java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 13
jmpb (ONE_LABEL);
// Try to avoid passing control into the slow_path ...
bind (CheckSucc);
// The following optional optimization can be elided if necessary// _LP64
slow
// The code reduces the window for a race, however,
// and thus benefits performance.
cmpptrAddresstmpReg,OM_OFFSET_NO_MONITOR_VALUE_TAGsucc)) NULL_WORD;
jccb (Assembler::zero, LGoSlowPath);
// Without cast to int32_t this style of movptr will destroy r10 which is typically obj.
movptr(Address// Generic instructions support for
// Memory barrier/fence
// Dekker pivot point -- fulcrum : ST Owner; MEMBAR; LD Succ
// Instead of MFENCE we use a dummy locked add of 0 to the top-of-stack.
// This is faster on Nehalem and AMD Shanghai/Barcelona.
// See https://blogs.oracle.com/dave/entry/instruction_selection_for_volatile_fences:(,
/
// (mov box,0; xchgq box, &m->Owner; LD _succ) .
lock(; Address(, );
cmpptr(Address(tmpReg
jccb (Assembler::notZero, java.lang.StringIndexOutOfBoundsException: Range [0, 37) out of bounds for length 1
// Rare inopportune interleaving - race.
// The successor vanished in the small window above.
// The lock is contended -- (cxq|EntryList) != null -- and there's no apparent successor.ExternalAddress(StubRoutines::x86::ector_double_sign_mask()), vector_len, noreg);
// We need to ensure progress and succession.
/ Try to reacquire the .
// If that fails then the new owner is responsible for succession and thisassert( =Op_NegVD,opcode Op_NegD);
// thread needs to take no further action and can exit via the fast path (success).
// If the re-acquire succeeds then pass control into the slow path.
// As implemented, this latter mode is horrible because we generated more
// coherence traffic on the lock *and* artificially extended the critical section
// length while by virtue of passing control into the slow path.
// box is really RAX -- the following CMPXCHG depends on that binding
// cmpxchg R,[M] is equivalent to rax = CAS(M,rax,R)
lock(;
cmpxchgptr(r15_thread, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)));
// There's no successor so we tried to regrab the lock.
// If that didn't work, then another thread grabbed the
// lock so we're done (and exit was a success).
(ssembler:: LSuccess)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
slow
bind( ,(:x86::java.lang.StringIndexOutOfBoundsException: Range [80, 78) out of bounds for length 102
(boxReg, );// set ICC.ZF=0 to indicate failure
jmpb (DONE_LABEL);
bind (LSuccess);
testl (boxReg, 0); // set ICC.ZF=1 to indicate success
jmpb (DONE_LABEL);
#endif
if (!UseHeavyMonitors) {
bind (Stacked);
movptr(tmpReg, Address (boxReg, 0)); // re-fetch
lock();
cmpxchgptr(tmpReg, Address(objReg, oopDesc::mark_offset_in_bytes())); // Uses RAX which is box
// Intentional fall-thru into DONE_LABEL
}
bind(DONE_LABEL);
// ZFlag == 1 count in fast path
o {
(:notZero NO_COUNT)java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
bind}(elem_bt =) {
// Count monitors in fast path,)
#ifndefelem_bt required);
get_thread(tmpReg);
decrementl(Address(tmpReg, (tmp == xmm0, "required;
#else // _LP64
((r15_thread,JavaThread:java.lang.StringIndexOutOfBoundsException: Range [71, 70) out of bounds for length 75
#endif
eg;// Set ZF == 1
bind}
}
//-------------------------------------------------------------------------------------------
// Generic instructions support for use in .ad files C2 code generation
:opcodejava.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 80
if (dstpmaxswdst,src;
movdqu(dst, src_t== T_INT {
}
if (opcode = Op_AbsVD) {
andpd(dst, ExternalAddresselem_bt=T_LONG, ")
} else {
assert((opcode == Op_NegVD),"opcode should ;
xorpd(dst, ExternalAddress(StubRoutines::x86::vector_double_sign_flip()), noreg);
}
}
void C2_MacroAssembler::vabsnegd(int opcode, XMMRegister}
if (opcode =
vandpd(dst, src, ExternalAddress
} :(int opcode elem_bt,
assert((opcode == Op_NegVD),"opcode should dst, src1, java.lang.StringIndexOutOfBoundsException: Range [80, 79) out of bounds for length 85
vxorpd(dst ExternalAddress:x:), ,)
}
}
void C2_MacroAssembler::vabsnegf(int opcode, ( = ){
if (dst != src) {
movdqu(dst, vpminsb(dstsrc1 src2, )
}
if (opcode == Op_AbsVF) {
andps(dst, ExternalAddress(StubRoutines::x86::vector_float_sign_mask()), dst, ,;
} if eTINT {
assert((opcode =r d src1,src2,vlen_enc)
} else {
}
}
void C2_MacroAssembler::vabsnegf( if (UseAVX > 2 && (vlen_enc ==Assembler::AVX_512bit || VM_Version::supports_avx512vl())) {
if (opcode == Op_AbsVF) {
vandps(dst, )
} else {
assert((opcode == Op_NegVF),"opcode assert_different_registers(dst, src1,(dst, src1, src2;
vxorps(dst src,ExternalAddress:x86:ector_float_sign_flip)) vector_len,);
}
}
void: , dstjava.lang.StringIndexOutOfBoundsException: Range [92, 91) out of bounds for length 115
assert(vpmaxsbdst,src1,src2 java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 41
assert(tmp dst src2, java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 41
ifopcode = ) {
if (elem_bt == java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 12
pminsb(dst, src) vlen_enc==AssemblerAVX_512bit | VM_Version:s() {
} if (lem_bt ==T_SHORT
pminsw(dst, src);
} else if (elem_bt == assert_different_regist(st src1src2)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
pminsd(dst, java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
} else {
assert(elem_bt == T_LONG, // Float/Double min max
void C2_MacroAssembler::vminmax_fp(int opcode, BasicType elem_bt,
assert_different_registers(dst, src, tmp);XMMRegisterdst a, XMMRegister ,
movdqu(xmm0, dst);
pcmpgtq(XMMRegistertmp XMMRegisteratmp, java.lang.StringIndexOutOfBoundsException: Range [86, 81) out of bounds for length 87
blendvpd(dst, assert(UseAVX > 0, "required");
}
{ // opcode == Op_MaxV
if (elem_bt == T_BYTEopcode ==Op_MaxV |opcode == Op_MaxReductionV, "";
pmaxsb(dst, src);
( = {
pmaxsw(dst, src);
} else if (elem_bt ==ers(, b , atmp, btmp);
pmaxsd(dst, src);
} else {
assert(elem_bt == T_LONGvminps( java.lang.StringIndexOutOfBoundsException: Range [38, 36) out of bounds for length 38
assert} (! & !)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
assert_different_registers(dst, src,atmp ,b b ;
movdqu(xmm0, src);
pcmpgtq(xmm0, dst);
java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 42
}
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 3
}
void } else ifis_double_wordbtmp, b, a, a, vlen_enc);
XMMRegister dst, XMMRegister src1, XMMRegister src2,
int vlen_enc) {
assert(opcode == Op_MinV || opcode == vminpd(tmp, atmp,btmp,vlen_enc);
if (opcode == Op_MinV) (tmp ,java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 59
if (elem_bt == T_BYTE) {
vpminsb(dst, src1, src2, vpminsb(dst, src1, src2, vlen_encbtmp,b a,b, len_enc);
} elseelem_bt == T_SHORT) {
vpminsw(dst, src1, src2, vlen_enc);
vmaxpd(tmp, atmp, btmp, vlen_enc);
vpminsd(dst, src1, src2 vcmppd(btmp, atmp Assembler::UNORD_Q, len_enc);
} else {
assert(elem_bt == T_LONG, "required");
if (java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 3
vpminsq(dst, src1, src2, intopcode elem_bt
else
assert_different_registers(dst, src1, src2);
vpcmpgtqd,src1 ,);
vblendvpd(dst, src1, ){
}
}
} else UseAVX >2 "equired)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
if (elem_bt == T_BYTE) {
vpmaxsb(,src1, src2, ;
} else if (elem_bt
pmaxsw(,src1,src2
} else if (elem_bt == T_INT) {
vpmaxsd(dst, java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
} else {
asserte= T_LONG, "required";
if (UseAVX > 2 && (vlen_enc == Assemblerevblendmpsatmp,ktmpa,b,merge, len_enc)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
vpmaxsqdst, src2, len_enc);
} else {
assert_different_registers(dst, src1, src2);
vpcmpgtqdst, ,,java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 44
vblendvpd(dstevpmovd2m(ktmp,b,;
}
}
}
}
// Float/Double min max
voidC2_MacroAssembler:vminmax_fpopcode, java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
XMMRegister dst, XMMRegisterevmovdqul(st ktmp,atmp,java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 33
XMMRegister tmp, XMMRegister atmp, XMMRegister btmp,
int vlen_encevmovdquq(,ktmp,java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 33
assert(opcode == Op_MinV || opcode == Op_MinReductionV ||
opcode == Op_MaxV || opcode == Op_MaxReductionV, "sanity");
assert(elem_bt == || = T_DOUBLE "sanity";
assert_different_registers(a, b, tmp, atmp, btmp);
evblendmpd(atmp, ktmp, a, b, merge, vlen_enc);
bool is_double_word = is_double_word_type(elem_bt);
if(is_double_word && is_min) {
vblendvps(atmp, a, b, a, vlen_enc);
vblendvps(btmp ,a , vlen_enc);
vminps(tmp, atmp, btmp, vlen_enc);
( ,atmp, :, vlen_enc);
vblendvps(dst, tmp, atmp, btmp, vlen_enc);
} ( & !java.lang.StringIndexOutOfBoundsException: Range [40, 39) out of bounds for length 42
vblendvps java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 99
vblendvps(atmp, a, b, b, vlen_enc);
vmaxps(tmp, atmp btmp, vlen_enc);
vcmpps(btmp, atmp, atmp, Assembler::java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 19
vblendvps(dst, tmp, atmp{
} else if (is_double_word && is_min) {
vblendvpdatmp,a , , vlen_enc;
vblendvpd(btmp, b, a, a, vlen_enc dst,zero)
vminpd(,java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 38
vcmppd(, ,atmp AssemblerUNORD_Q vlen_enc);
vblendvpd(dst, tmp, atmp, btmp, vlen_enc);
} else {
jcc(Asjcc(::above, DONE_LABEL)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
( , a, ,vlen_enc);
vblendvpd(atmp = )
t,)
vcmppd(btmpjccAssemblerparity, // handle special case NaN, if argument NaN, return NaN
vblendvpd(dst, tmpjcc(:a )
}
}
void C2_MacroAssembler::evminmax_fp(int opcode, java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 23
)
UseAVX )
assert(opcode == Op_MinV || opcode == Op_MinReductionV ||
opcode d,src )
assert(elem_bt == T_FLOAT || }
assert_different_registers(dst, java.lang.StringIndexOutOfBoundsException: Range [24, 22) out of bounds for length 96
bool is_min
bool is_double_word = java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
bool merge = true;
if (!is_double_word && is_min) {
(,vlen_enc;
evblendmps(atmp, ktmp, a, b, merge, vlen_enc);
evblendmps(btmp, ktmp, b, a, merge, vlen_enc);
vminps(dst,atmp btmp,vlen_enc);
evcmpps(ktmp, k0, atmp, atmp, Assembler::UNORD_Q, vlen_enc);
evmovdqul }else {
} vpmovzxwddst, ;
evpmovd2m(ktmp, b, vlen_enc);
evblendmps(atmp, ktmp, a, java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
btmp java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 50
vmaxps(dst, atmp, btmp, vlen_enc) o =Op_RotateLeftV{
evcmpps(ktmp, k0, java.lang.StringIndexOutOfBoundsException: Range [0, 26) out of bounds for length 25
(st , atmp,,vlen_enc)
} else if (is_double_word}
evpmovq2m(ktmp, a, vlen_enc);
evblendmpd(atmp, ktmp, a, b, merge }
evblendmpd(btmp
, ,java.lang.StringIndexOutOfBoundsException: Range [38, 36) out of bounds for length 38
evcmppd(}{
evmovdquqd,ktmp,merge )
} else {
assertis_double_wordis_min sanity)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
evpmovq2m(ktmp java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Range [0, 14) out of bounds for length 0
(btmp, ktmp b,a, merge, vlen_enc);
vmaxpd(dst, atmp, btmp, vlen_enc);
evcmppd(ktmp k0,atmp, atmp,Assembler:UNORD_Q,vlen_enc);
evmovdquq(dst, ktmp, atmp, merge, vlen_enc);
}
}
// Float/Double signum
void C2_MacroAssembler::signum_fp(int ,,,java.lang.StringIndexOutOfBoundsException: Range [44, 42) out of bounds for length 44
assert(opcode == Op_SignumF || (, src shift vector_len;
Label DONE_LABEL;
opcode={
assert(UseSSE > 0, "required");
ucomiss( )java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
jcc(Assembler::equal, evprorvd(dst, src, shift, vect)
jcc(Assembler::parity, DONE_LABEL); // handle special case NaN, if argument NaN, return NaN(etype =T_LONG, "xpected type T_LONG");
movflt(dst, one);
jcc(Assembler::above, DONE_LABEL);
xorps(dst, ExternalAddress
} else
assert(UseSSE > 1
ucomisd(dst zero);
jcc(Assembler::equal, DONE_LABEL); // handle special case +0.0/-0.0, if argument is +0.0/-0.0, return argument opcode=) java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
}else
movdblassert(opcode==Op_URShiftVI)" should Op_URShiftVI";
jcc( )java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
xorpddst (:x86:() )java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
}
bind(DONE_LABEL);
}
java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 80
(s [)java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
} else {
pmovzxbw(dst, src);
}
}
C2_MacroAssembler dst,XMMRegistersrc vector_len) {
if (sign) {
vpmovsxbw(dst, src, vector_len);
}else{
vpmovzxbw(dst, src, vector_len);
}
}
void C2_MacroAssembler::vextendbd(bool else java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
if (sign) {
ctor_len)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
} else {
vpmovzxbd(dst, src, vector_len);
}
}
:java.lang.StringIndexOutOfBoundsException: Range [44, 38) out of bounds for length 96
if (sign) { Op_LShiftVI: vpsllddst,src,,vlen_enc; break
case :vpsrld(st srcshift vlen_enc);break;
} else {
vpmovzxwd(st src, vector_len);
}
}
void C2_MacroAssembler::vprotate_imm
int void C2_MacroAssembler::vshiftw(int opcode, XM, shift java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
if (opcode == Op_RotateLeftV) {
if etype
evprold(dst, src, shift, vector_len);
} else {
assert(etype = T_LONG "xpected type T_LONG");
evprolq(dst, src, shift, vector_len);
}
}else {
assert(opcode == Op_RotateRightV, "opcode should be Op_RotateRightV");
case:java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
evprord(java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 0
} else {
assert(etype == T_LONG, "expected type T_LONG");
evprorq(dst, src, shift,java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
}
}
:(ntopcode java.lang.StringIndexOutOfBoundsException: Range [64, 58) out of bounds for length 99
caseOp_RShiftVSvpsraw(dst,src shift,vlen_enc) breakjava.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
caseOp_LShiftVB:// fall-through
java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 64
evprolvd case://fall-through
} else {
assert(etype == T_LONG, "expected type T_LONG");
evprolvq(dst, src,default:assert(false"s, NodeClassNames[opcode]);
}
} else {
assert(opcode == java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
C2_MacroAssembler:vshiftq opcode XMMRegisterdst,XMMRegister shift) {
evprorvd(dst, src, shift, vector_len);
} else {
assert=, "
case:,;;
}
}
}
void C2_MacroAssembler::vshiftd_imm(int opcode,
if (opcode =java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (opcode == Op_RShiftVL) {
} else if (opcode == Op_LShiftVI) {
pslld(dst,shift;
} else {
(opcode = Op_URShiftVI)"pcode should be Op_URShiftVI");
psrld(dst, shift);
}
}
void assert((opcode"pcodejava.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 69
switch (opcode) {
case void C2_MacroAssemblerint,XMMRegister , shift vlen_enc){
case pslld,shift); ;
case Op_URShiftVI: psrld(dstcase :evpsraqdst, src ,;java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
default: assert(false
}
}
voidvoid C2_MacroAssemblervshiftq_imm(int opcode, XMMRegister dst, XMMRegister nds, int shift, int vector_len) {
if (opcode==Op_RShiftVI){
vpsrad(dst, nds, shift, vector_len);
} else if (opcode == Op_LShiftVI) {
vpslld(dst, nds, shift, vector_len);
}else{
assert((opcode else if(= Op_LShiftVL)
vpsrldd ;
}
}
XMMRegisterdstXMMRegister,XMMRegister int){
switch (opcode) {
case Op_RShiftVI:vpsrad(dst,src, java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 64
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
:(stsrc, vlen_enc) break
:assert(alse,"s,NodeClassNames[opcode]);
}
}
void C2_MacroAssembler::vshiftw(int opcode, XMMRegister case Op_RShiftVS:// fall-through
switch(pcodejava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
case case Op_LShiftVB
case Op_RShiftVS: psraw(dst dst,src,shift vlen_enc;breakjava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
caseOp_LShiftVB:
case Op_LShiftVS: psllw caseOp_URShiftVI: vpsrlvd(dst, src, shift, vlen_enc); break;
case Op_URShiftVS: // fall-through
case Op_URShiftVB: psrlw(dstjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
default: assert(false, "%s", NodeClassNames[opcode]);
}
}
:vint opcode ,XMMRegistersrc, ,int){
switch (opcode) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
case Op_RShiftVS: vpsraw(dst, src, shift, vlen_enc); break;
case Op_LShiftVB: // fall-through
case Op_LShiftVS: vpsllw(dst, src, shift,
case Op_URShiftVS:
dst vlen_enc)break
default: assert(false, "%s",}
}
}
void C2_MacroAssembler assertU >2,"";
switch (opcode) {
case Op_RShiftVL: psrlq(dst, shift); break; // using srl to implement sra on pre-avs512 systems
case Op_LShiftVL: psllq(dst, shift); break;
case Op_URShiftVL: psrlq(dst, shift); break;
(mp= ," used)
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
void C2_MacroAssembler::vshiftq_imm(int opcode,
if (opcode == Op_RShiftVL) {
psrlq(dstvpsrlvq(dst, src, shift, vlen_enc);
} else if (opcode == Op_LShiftVL) {
psllq(st,shift)
} else {
assert((pcode= Op_URShiftVL),"opcode should be Op_URShiftVL");
psrlq(dst, shift);
vpsubq(,,tmp)
}
void C2_MacroAssembler: case Op_LShiftVL java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
vpsllvq,src,shift,vlen_enc)
case Op_RShiftVL: break;
case Op_LShiftVL: Op_URShiftVL: {
case Op_URShiftVL: vpsrlq(dst, src, shift, vlen_enc); break;
defaultd , )
}
}
void C2_MacroAssembler::vshiftq_imm(int opcode, java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 3
if (opcode// Variable shift src by shift using vtmp and scratch as TEMPs giving word result in dst
evpsraqdst java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 41
} else if (opcode == Op_LShiftVL) {
vpsllq((dst,nds,shift vector_len)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
} else {
assert),"opcodeshould be Op_URShiftVL");
vpsrlq(dst, nds, shift, vector_len);
}
}
void C2_MacroAssembler::varshiftd(int opcode, XMMRegister dst, XMMRegister src, XMMRegister shift, int vlen_enc) {
switch (opcode) {
_RShiftVB: / fall-through
case Op_RShiftVS: vpmovzxbd(vtmp, shift, 1);
case Op_RShiftVI: vpsravd(dst, src varshiftd(opcode,dst dst, vtmp,1;
case Op_LShiftVB: // fall-through
case Op_LShiftVS: // fall-through
case Op_LShiftVI: vpsllvd(dst, src, shift, vlen_enc); break;
case Op_URShiftVB (,java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 31
case Op_URShiftVS: // fall-through
case Op_URShiftVI:// Variable shift src by shift using vtmp and scratch as TEMPs giving byte result in dst
]);
}
}
void C2_MacroAssembler::varshiftw assert(opcode = Op_LShiftVB |
) {
case Op_RShiftVB: // fall-through
case Op_RShiftVS evpsravw( ,shift,vlen_enc) break;
case Op_LShiftVB: // fall-through
case Op_LShiftVS: evpsllvw(dstintext_vector_len +1java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
vpand,dst ExternalAddressStubRoutines:::ector_short_to_byte_mask),ext_vector_len,noreg;
case Op_URShiftVS: evpsrlvw(dst, src, shift, vlen_enc); break;
default: assert(false, "%s", vpackuswb(dst, dst, vtmp, vector_len);
}
}
,, java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
assert(
switch (opcode) {
casevoid i(java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 87
U >){
assert(tmp == xnoreg, "not used");
if ;
vlen_enc = Assembler::AVX_512bit;
}
evpsravq(dst, src, shift, case:
} java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
vmovdqutmp,(:x86::ector_long_sign_mask)java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 82
vpsrlvq( pinsrq(st val,idx);
vpsrlvq(tmp, tmp, shift, vlen_enc);
or(st,dsttmp vlen_enc);
vpsubq(dst, dst, tmp, vlen_enc);
}
break;
assert(alse,Should notreach here");
case Op_LShiftVL
assert(tmp == xnoreg, "not used");
vpsllvq(dst, src, void C2_MacroAssembler::vinsert typ dst,XMMRegister src,Registerval,intidx){
break;
}
case Op_URShiftVL: {
assert (dst val ;
vpsrlvq(dst, src, shift, vlen_enc);
break;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
default
}
}
// Variable shift src by shift using vtmp and scratch as TEMPs giving word result in dst
void C2_MacroAssembler::varshiftbw(int opcode, XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len, java.lang.StringIndexOutOfBoundsException: Index 127 out of bounds for length 12
assert(opcode == java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 12
opcode == Op_RShiftVB ||
opcode ==java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
bool opcode ;
assert(vector_len == 0, "required");
(,dst ,)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
vpmovzxbd(vtmpshift,1;
varshiftd(opcode, dst, java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
vpand(dst, dst, (, :),vector_len;
vextracti128_highjava.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 16
vpackusdw(, dst,vtmp,0;
}
// Variable shift src by shift using vtmp and scratch as TEMPs giving byte result in dst
void C2_MacroAssembler vgatherdpd(st, :) mask vector_len
assert(java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 12
opcode == Op_RShiftVB ||
opcode == Op_URShiftVB, "%s", NodeClassNames }
bool sign = (opcode != Op_URShiftVB);
int ext_vector_len = vector_len
vextendbw(sign, dst, , ext_vector_len);
vpmovzxbw(vtmp, shift, ext_vector_len);
varshiftw(opcodeswitch(typ){
vpand( case T_:
if (vector_len evpgatherdd(dst,mask,Address(, idx, Address:times_4), vector_len);
vextracti128_high(vtmp, dst);
vpackuswb(dst, dst, vtmp java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 17
};
vextracti64x4_highvtmp,;
vpackuswb(dst, dst, vtmp, vector_len);
vpermq(dst, dst, 0xD8, vector_len (,, :java.lang.StringIndexOutOfBoundsException: Range [65, 64) out of bounds for length 79
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
:insert dst java.lang.StringIndexOutOfBoundsException: Range [75, 71) out of bounds for length 87
switch(typ) {
case T_BYTE
pinsrb(dst, val, idx);
break;
case T_SHORT:
pinsrw(dst, val, casejava.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 15
break;
case T_INT:
pinsrd(dst, val, idx);
break;
case T_LONG:
pinsrq(st, val idx)
break;
default:
assertfalse" not .)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
break;
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
void C2_MacroAssembler::vinsert(BasicType typ, java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 45
switch(
case T_BYTE:
vpinsrb(dst, src, val, idx);
break;
case T_SHORT:
vpinsrw(dst, src, val, idx);
break;
case T_INT:
vpinsrd(dst, src, val, idx)(,;
break;
case /* nothing to do */ break;
vpinsrq(dst, src, val, idx);
break;
default:
assert(false,"Should not reach here.");
break;
}
}
case: d ) ;
switch(typdefault: assertfalse, "s", type2name(elem_bttype2name(lem_bt)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
} else
vpgatherdd(dst, Address(base, idx, Address::times_4), mask, vector_len);
break;
case T_FLOAT:
vgatherdps(dst, Address(basevpxor (st dst dst,vlen_enc);
break;
case T_LONG:
vpgatherdq(dst,Addressbase idx,Address:times_8),mask vector_len)java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
break;
case T_DOUBLE:
dst, Address(base, idx, Address::times_8), mask, vector_len);
break;
T_SHORT:vpmovsxbw(dst, , vlen_enc) breakjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
assert(false,"Should not reach here.");
break;
}
}
void C2_MacroAssembler::evgather( case :vpmovsxbq(dst, dst, vlen_enc); break;
switch(typ) {
case T_INT:
evpgatherdd(dst, mask, Address(base, idx, Address::times_4), vector_len);
break;
case T_FLOAT:
evgatherdps(dst, mask, Address(base, idx, Address::times_4), vector_len);
break;
caseT_LONG:
evpgatherdq(dst, mask, Address(base, idx, java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 17
break;
case T_DOUBLE:
evgatherdpd(dst, mask, Address(base, idx, Address::times_8), vector_len);
break;
default:
assertfalse,"hould reach here.");
break;
}
}
void C2_MacroAssembler (xtmp, xtmp,xtmp, vlen_enc);
switch(typ) {
_INT
evpscatterdd( evpmovb2m(st xtmp,vlen_enc);
break;
case T_FLOAT:
evscatterdps(Address(base, idx, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
break;
caseswitchvlen_in_bytes
base:times_8 mask src,vector_len);
break;
case T_DOUBLE:
Address,java.lang.StringIndexOutOfBoundsException: Range [57, 54) out of bounds for length 80
break
default:
assert(false,"Should not reach here case 32:vmovdqu(dst, src); break;
break;
}
}
void }
if (vlen_in_bytes <= 16) {
xor (dst, dst);
psubb(dst, src);
switch (elem_bt) {
case void C2_MacroAsse:load_vector( dstAddressLiteral src,intvlen_in_bytes,Register rscratch) {
T_SHORT: pmovsxbw(dst,dst; break;
case T_INT: java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 0
;
case T_LONG: pmovsxbq(dst, java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 10
load_v(,rscratch0,vlen_in_bytesjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
(falses,type2name);
}
} else {
assert(!is_legacy || !is_subword_type(elem_bt) || vlen_in_bytes < :(){
int vlen_enc = vector_length_encoding(java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 23
vpxordst,dst dst ;
vpsubb(dst, dst, src, is_legacy ? AVX_256bit : vlen_enc);
switch (elem_bt java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 32
case T_BYTE: /* nothing to do */ break;src )
case T_SHORT: (dst );
case T_INT: vpmovsxbd(dst, dst
case :vpmovsxbddst ,vlen_enc; ;
case T_LONG: vpmovsxbq(dst, dst, vlen_enc); vpbroadcastdd,src,)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
case T_DOUBLE: vpmovsxbq(dst, dst, vlen_enc); break;
default: assert(false, "%s", } else if (VM_Version::supports_sse3()
}
}
}
void C2_MacroAssembler::load_vector_mask(KRegister dst,movq(dst,src);
if (novlbwdq) {
vpmovsxbd(tmpsrc, vlen_enc);
evpcmpd(dst, k0, xtmp, ExternalAddress(StubRoutines::x86::java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 27
Assembler
} else {
vpxor(xtmp, xtmp, xtmp, vlen_enc) // The iota indices are ordered by type B/S/I/L/F/D, and the offset between two types is 64.
vpsubb, src,vlen_enc)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
evpmovb2m(st, ,)
}
}
void C2_MacroAssembler::load_vector ExternalAddressaddrStubRoutines::vector_iota_indices()+offset);
switchvlen_in_bytes java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
case 4: movdl(dst, src); break;
case 8: movq(dst, src); break;
case 16void ::reduce_operation_128(BasicType , int ,XMMRegister dst, XMMRegister src) {
case 32: vmovdqu(dst, src); break;
case: evmovdquld, src,Assembler::VX_512bit);break;
default: ShouldNotReachHere();
}
}
void C2_MacroAssembler::load_vector(XMMRegister dst, AddressLiteral src, int vlen_in_bytes, Register java.lang.StringIndexOutOfBoundsException: Index 103 out of bounds for length 50
assert(rscratch != noreg || always_reachableOp_XorReductionV: pxor(st,src; break
if (reachable(src)) {
load_vector(dst, java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 20
} else {
lea(rscratch, src);
load_vector(dst, Address(rscratch, 0), vlen_in_bytes);
}
}
void C2_MacroAssembler::load_constant_vector(BasicType bt, XMMRegister dst, InternalAddress src, int vlen) {
int vlen_enc = vector_length_encoding(vlen);
if (:supports_avx) java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
if (=T_LONG{
if (VM_Version::supports_avx2()) {
vpbroadcastq(dst, src, vlen_enc);
} else {
vmovddup(dst, src, vlen_enc);
}
}elseif( = T_DOUBLE{
if (vlen_enc != Assembler::AVX_128bit) {
vbroadcastsd(dst, src, vlen_enc, noreg);
} else {
vmovddup(dst, src, vlen_enc);
}
} else {
if (VM_Version::supports_avx2() && java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
vpbroadcastd(dst, src, vlen_enc):java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 51
} else {
vbroadcastss(dst, src (dst ; ;
}
}
} else if (VM_Version::supports_sse3()) {
movddup(dst, src);
}else{
movq(dst default: assert(false,"rong type");
if (vlen break;
punpcklqdq(st dst)
}
}
}
void case (src) breakjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
// The iota indices are ordered by type B/S/I/L/F/D, and the offset between two types is 64.
int offset = exact_log2(type2aelembytes(bt)) << 6;
if (is_floating_point_type(bt)) {
offset + 128;
}
ExternalAddressStubRoutinesx86:( )java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
load_vector java.lang.StringIndexOutOfBoundsException: Range [43, 41) out of bounds for length 59
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
// Reductions for vectors of bytes, shorts, ints, longs, floats, and doubles.
void C2_MacroAssembler::java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 1
int vector_len = Assembler::AVX_128bit;
switch (opcode) {
case Op_AndReductionV: pand(dst6bit;
case Op_OrReductionV: por (dst, src); break;
case Op_XorReductionV: pxor(dst, src); break;
case Op_MinReductionV:
switch (typ) {
case T_BYTE: pminsb(dst, src); break;
case T_SHORT :vpand(, src1 ,vector_lenbreakjava.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
case T_INT: pminsd(dst, src); break;
switch(){
vpminsq(dst, dst, src, Assembler::AVX_128bit); break;
default: assert(false, "wrong type");
}
break;
case Op_MaxReductionV:
switch (yp {
case T_BYTE: pmaxsb(dst, src); break;
caseT_SHORT: pmaxsw(dst, src; break;
case T_INT: pmaxsd(dst, src); break;
case T_LONG: assertUseAVX >2,"equired");
vpmaxsq(dst, dst, src, Assembler::AVX_128bit); break;
default: assert(false java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
}
break;
:addssdst );break;
case Op_AddReductionVD: addsd(dst, src); break;
case case T_SHORT:(dst,src1,src2 vector_len); break;
switch (typ) {
T_BYTE (dst,src);
case T_SHORT: paddw(dst, src); break;
case T_INT: case T_LONG: assert(UseAVX >2 "equired";
default: assert(false, "wrong type");
}
break;
case Op_AddReductionVL:}
case Op_MulReductionVF: java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 12
case Op_MulReductionVD: mulsd( T_BYTE: vpaddb( src2 vector_len); break;
case Op_MulReductionVI:
switch (typ) {
case (,src;break;
case T_INT: pmulld(dst, src); default: assert(false, "wrong ty
default: assert(false, "wrong type");
}
break;
case Op_MulReductionVL: assert(UseAVX > 2, "required");
(,dst,src vector_len; break
default: false,"rong opcode";
}
}
void C2_MacroAssembler::reduce_operation_256(BasicType typ, break;
vector_len =Assembler::AVX_256bit;
switch (opcode) {
case Op_AndReductionV vpand(dst,src1, src2, vector_len);break;
case Op_OrReductionV: vpor (dst, src1, src2, vector_len); break;
case Op_XorReductionV: vpxor(dst
case Op_MinReductionVjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
switch XMMRegister,XMMRegisterjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
:vpminsb, src1 src2 vector_len) breakjava.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
case case Op_AddReductionVF
case T_INT: vpminsd( reduceF(opcode, vlen, dst, src, vtmp1java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
case T_LONG: assert(UseAVX case Op_AddReductionVD
vpminsq(dst , src2, vector_len);break;
default: assert(false, "wrong type");
}
break;
case Op_MaxReductionV:
switch default:assert(false, "wrong opcode");
case T_BYTE: vpmaxsb(dst, src1, src2, java.lang.StringIndexOutOfBoundsException: Range [0, 63) out of bounds for length 3
case T_SHORT: vpmaxsw(dst, src1, src2, vector_len); break;
case T_INT: vpmaxsd(dst, src1, src2, vector_len); break;
case T_LONG: assert( >2,"")
vpmaxsq(dst, src1, src2, vector_len); break;
default: assert( XMMRegisterXMMRegister
}
break;
case :
switch (typ) {
case T_BYTE: vpaddb(dst, src1, src2, vector_len); break;
case T_SHORT: vpaddw(dst, src1, src2, vector_len); break;
case T_INT: vpaddd(dst, src1, src2, vector_len);
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 1
}
break;
caseOp_AddReductionVL vpaddq(dst,src1,,src2,vector_len); break;
case Op_MulReductionVI:
switch (typ) {
case T_SHORT: vpmullw(dst, src1 XMMRegistervtmp1,XMMRegister vtmp2) {
case T_INT: vpmulld(dst, src1, src2, vector_len); break;
default: assert(false, "wrong type");
}
break;
ullq,,;break
default: assert(false, "case32 mulreduce32B ,,vtmp1,vtmp2) ;
}
}
:assert, " vector length");
XMMRegister dst, XMMRegister src,
XMMRegister vtmp1, XMMRegister vtmp2) {
switch (opcode) {
case Op_MulReductionVF:
reduceF(opcode, vlen, dst, src, vtmp1, vtmp2);
;
case Op_AddReductionVD:
Op_MulReductionVD
reduceD(8 ( java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 69
;
default: assert(false, "wrong opcode");
}
}
:java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 53
Register dst}
XMMRegister vtmp1, void C2_MacroAssembler::reduceI(int opcode, int vlen
switch (vlen) {
case 8: XMMRegister vtmp1, XMMRegister vtmp2) {
case 16: reduce16B(opcode, dst, (len) {
case 32:(pcode,dst, src1 src2 ) break;
case 64: reduce64B(opcode, dst, src1, src2, vtmp1, vtmp2); break;
default (,"wrong "java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
}
}
vlen,
Register dst, Register src1, XMMRegister src2,
XMMRegister vtmp1, XMMRegister vtmp2) {
switch (vlen) {
mulreduce8Bopcode, , ,vtmp2);
case 16: mulreduce16B(opcode, dst, src1, Register dst, RegistXMMRegister src2,
case 32: mulreduce32B( XMMRegister vtmp1,XMMRegister vtmp2) {
case 64: mulreduce64B(opcode, dst, src1, src2, vtmp1, vtmp2); switch (vlen) {
default: assert(false, "wrong vector length");
}
}
void C2_MacroAssembler 8:reduce8L(opcode, dst, src1, src2, vtmp1, vtmp2); break;
Register dst, Register src1, XMMRegister src2,
XMMRegister vtmp1, XMMRegister vtmp2) {
switch (vlen) {
#ndif// LP64
case 8: reduce8S (opcode, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
case 16:reduce16Sopcode,dst src1,src2, vtmp1, vtmp2); break;
case 32: reduce32S(opcode, dst, src1, src2, vtmp1, vtmp2); break;
default: assert(false, "wrong vector length");
}
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
void C2_MacroAssembler::reduceI(int opcode, int vlen,
Register dst, Register src1, XMMRegister src2,
XMMRegister vtmp1,XMMRegister vtmp2) {
switch (vlen) {
case 2: reduce2I (opcode, dst, src1, src2, vtmp1, vtmp2 opcode ,);
(pcode dst, src1, ,vtmp1, vtmp2); break;
case 8: reduce8I (opcode, dst, src1, src2, vtmp1, vtmp2) reduce8Fopcode, dst,src vtmp1, vtmp2);
case 16: reduce16I(opcode, dst, src1, src2, vtmp1, vtmp2); break break;
default: reduce16F(opc,dst,src vtmp1, vtmp2);
}
}
#
void java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 3
XMMRegister vtmp1, XMMRegister vtmp2) {
switch (len)java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
case 2: reduce2L(opcode, dst, java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 34
case 4: reduce4L(opcode, dst, src1, src2, vtmp1, vtmp2); break;
case 8: reduce8L( case 4:
default: assert(false, "wrong vector length");
}
}
#endif // _LP64
void break;
switch (vlen) {
:
assert(vtmp2 == xnoreg, }
reduce2F(opcode, dst, src, vtmp1);
break;
case 4:
assert(vtmp2 == xnoreg, "");
reduce4F(opcode, dst, :reduce2I, ,Register vtmp1 vtmp2)java.lang.StringIndexOutOfBoundsException: Index 131 out of bounds for length 131
break;
case 8:
8(opcode,dst , vtmp1, vtmp2);
break;
case 16:
reduce16F(opcode, dst, src, vtmp1, vtmp2);
break;
default:assert(false,wrong vector length";
}
}
void C2_MacroAssembler }
switch ( movdl(vtmp2,);
case 2:
assert(vtmp2 == xnoreg, "");
reduce2D(opcode, dst, src, vtmp1);
break;
case :
reduce4D(opcode, dst, src, vtmp1, vtmp2)if(opcode = Op_AddReductionVI {
break;
case 8:
reduce8D(opcode, dst, src, vtmp1, vtmp2);
break;
default: assert(false, "wrong vector length");
}
}
pshufd(tmp2,src2 0xE;
if (opcode == Op_AddReductionVI) {
(tmp1! ) {
movdqu(vtmp1, src2);
}
phaddd(vtmp1, vtmp1);
} else {
pshufd(vtmp1, src2, 0x1);
void ::reduce8Iintopcode, dst,Register ,XMMRegister src2,XMMRegister vtmp1, XMMRegister vtmp2) {
}
movdl if (pcode ==Op_AddReductionVI {
reduce_operation_128(T_INT, opcode, vtmp1, vtmp2);
movdl(dst,vtmp1);
}
void:reduce4Ii , , src2XMMRegister,XMMRegister
if (opcode == Op_AddReductionVI) {
if (vtmp1 != src2) {
movdqu(vtmp1, src2);
}
phaddd(vtmp1, src2);
, vtmp2);
} else {
vtmp2,src2 0;
reduce_operation_128(T_INT, java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 3
reduce2I(opcode, dst, src1:reduce16I(nt opcode dst src1, src2 ,XMMRegistervtmp2java.lang.StringIndexOutOfBoundsException: Index 132 out of bounds for length 132
}
}
void C2_MacroAssembler::reduce8I(int opcode, reduce8I(opcode, dst, src1, vtmp2, vtmp1, vtmp2)
if (opcode == Op_AddReductionVI) {
vphaddd(vtmp1, ler::educe8B opcode,Register, Register src1,XMMRegister src2,XMMRegister vtmp1, XMMRegister vtmp2) {
vextracti128_high(vtmp2, vtmp1);
vpaddd(vtmp1, vtmp1, vtmp2, Assembler::java.lang.StringIndexOutOfBoundsException: Range [2, 53) out of bounds for length 52
reduce2I(psrldqvtmp1,)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}else
vextracti128_high(java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 23
reduce_operation_128(T_INT, opcode, vtmp1, src2);
);
}
}
C2_MacroAssembler:reduce16I( ,Register dst,Register , src2,XMMRegister vtmp1, vtmp2){
vextracti64x4_high(vtmp2, src2);
reduce_operation_256(T_INT, opcode, vtmp2, vtmp2, src2);
reduce8I(opcode, dst, src1, vtmp2, vtmp1, vtmp2);
}
void C2_MacroAssembler::reduce8B(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2) {
pshufd(vtmp2, src2, 0x1);
reduce_operation_128(T_BYTE, opcode, vtmp2, src2);
movdqu(vtmp1, vtmp2);
psrldq(vtmp1, 2);
reduce_operation_128 pshufd(vtmp1,src2 0xE;
movdqu(vtmp2, vtmp1);
psrldq(vtmp2, 1);
reduce_operation_128(T_BYTE,opcode, vtmp1, vtmp2);
movdl(vtmp2, src1);
pmovsxbd(vtmp1, }
reduce_operation_128(T_INT, opcode, vtmp1, vtmp2);
pextrb(dst, vtmp1, 0x0);
movsbl(dst, dst)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}
voidC2_MacroAssembler:reduce16B( Register dst,Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2) {
pshufd( reduce16B(opcode, dst, src1, vtmp2, vtmp1, vtmp2);
reduce_operation_128(T_BYTE, opcode, vtmp1, src2);
reduce8B(opcode, dst, src1, vtmp1, vtmp1java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
void C2_MacroAssembler::reduce32B(int opcode, Register dst, Register src1, XMMRegister src2,
vextracti128_high(tmp2 src2);
reduce_operation_128(T_BYTE, opcode, vtmp2,
reduce16B(pcode,dst src1,vtmp2, vtmp1,vtmp2);
}
void C2_MacroAssembler::reduce64B
vextracti64x4_high
void C2_MacroAssembler::mulreduce16B(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2) { | |