This commit is contained in:
David Dehaven 2015-07-07 12:26:59 -07:00
commit 79324abda0
682 changed files with 113654 additions and 5785 deletions

View File

@ -313,3 +313,4 @@ ff3fc75f3214ad7e03595be1b0d0f38d887b6f0e jdk9-b66
5b500c93ce4822d47061cd518ff3f72d9d8cb5b5 jdk9-b68
d69c968463f0ae5d0b45de3fc14fe65171b23948 jdk9-b69
43d0179ee9de3bfffae3417f09e07eb6d8efc963 jdk9-b70
f66c185284727f6e6ffd27e9c45ed2dd9da0a691 jdk9-b71

View File

@ -313,3 +313,4 @@ f546760134eb861fcfecd4ce611b0040b0d25a6a jdk9-b67
70e4272790b6199e9ca89df2758ff9cb58ec4125 jdk9-b68
1bcfd6b8726582cff5a42dbfc75903e36f9dd4fe jdk9-b69
eed77fcd77711fcdba05f18fc22f37d86efb243c jdk9-b70
c706ef5ea5da00078dc5e4334660315f7d99c15b jdk9-b71

View File

@ -4364,7 +4364,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1434614912
DATE_WHEN_GENERATED=1435822080
###############################################################################
#
@ -42961,7 +42961,7 @@ $as_echo "$as_me: WARNING: X11 is not used, so --with-x is ignored" >&2;}
if test "x$x_libraries" = xNONE; then
if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then
x_libraries="$SYSROOT/usr/X11R6/lib"
elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
elif test -f "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
x_libraries="$SYSROOT/usr/lib64"
elif test -f "$SYSROOT/usr/lib/libX11.so"; then
x_libraries="$SYSROOT/usr/lib"

View File

@ -113,7 +113,7 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
if test "x$x_libraries" = xNONE; then
if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then
x_libraries="$SYSROOT/usr/X11R6/lib"
elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
elif test -f "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
x_libraries="$SYSROOT/usr/lib64"
elif test -f "$SYSROOT/usr/lib/libX11.so"; then
x_libraries="$SYSROOT/usr/lib"

View File

@ -1188,28 +1188,11 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
OTHER_JDK="$OTHER/install/jdk"
OTHER_JRE="$OTHER/install/jre"
echo "Selecting install images for compare"
elif [ -d "$THIS/deploy/jdk" -o -d "$THIS/deploy/images/jdk" ] \
&& [ -d "$OTHER/deploy/jdk" -o -d "$OTHER/deploy/images/jdk" ]; then
if [ -d "$THIS/deploy/images/jdk" ]; then
THIS_JDK="$THIS/deploy/images/jdk"
THIS_JRE="$THIS/deploy/images/jre"
else
THIS_JDK="$THIS/deploy/jdk"
THIS_JRE="$THIS/deploy/jre"
fi
if [ -d "$OTHER/deploy/images/jdk" ]; then
OTHER_JDK="$OTHER/deploy/images/jdk"
OTHER_JRE="$OTHER/deploy/images/jre"
else
OTHER_JDK="$OTHER/deploy/jdk"
OTHER_JRE="$OTHER/deploy/jre"
fi
echo "Selecting deploy images for compare"
elif [ -d "$THIS/deploy/images/jdk" ] && [ -d "$OTHER/deploy/jdk" ]; then
THIS_JDK="$THIS/deploy/jdk"
THIS_JRE="$THIS/deploy/jre"
OTHER_JDK="$OTHER/deploy/jdk"
OTHER_JRE="$OTHER/deploy/jre"
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/deploy/images/jdk" ]; then
THIS_JDK="$THIS/images/jdk"
THIS_JRE="$THIS/images/jre"
OTHER_JDK="$OTHER/deploy/images/jdk"
OTHER_JRE="$OTHER/deploy/images/jre"
echo "Selecting deploy images for compare"
elif [ -d "$THIS/images/jdk" ] && [ -d "$OTHER/images/jdk" ]; then
THIS_JDK="$THIS/images/jdk"
@ -1221,30 +1204,28 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
echo "No common images found."
exit 1
fi
echo " $THIS_JDK"
echo " $OTHER_JDK"
if [ -d "$THIS/deploy/jdk-bundle" -o -d "$THIS/deploy/images/jdk-bundle" ] \
&& [ -d "$OTHER/deploy/jdk-bundle" -o -d "$OTHER/deploy/images/jdk-bundle" ]; then
if [ -d "$THIS/images/jdk-bundle" -o -d "$THIS/deploy/images/jdk-bundle" ] \
&& [ -d "$OTHER/images/jdk-bundle" -o -d "$OTHER/deploy/images/jdk-bundle" ]; then
if [ -d "$THIS/deploy/images/jdk-bundle" ]; then
THIS_JDK_BUNDLE="$THIS/deploy/images/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/deploy/images/jre-bundle"
else
THIS_JDK_BUNDLE="$THIS/deploy/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/deploy/jre-bundle"
THIS_JDK_BUNDLE="$THIS/images/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/images/jre-bundle"
fi
if [ -d "$OTHER/deploy/images/jdk-bundle" ]; then
OTHER_JDK_BUNDLE="$OTHER/deploy/images/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/deploy/images/jre-bundle"
else
OTHER_JDK_BUNDLE="$OTHER/deploy/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/deploy/jre-bundle"
OTHER_JDK_BUNDLE="$OTHER/images/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/images/jre-bundle"
fi
echo "Also comparing deploy macosx bundles"
elif [ -d "$THIS/images/jdk-bundle" ] && [ -d "$OTHER/images/jdk-bundle" ]; then
THIS_JDK_BUNDLE="$THIS/images/jdk-bundle"
THIS_JRE_BUNDLE="$THIS/images/jre-bundle"
OTHER_JDK_BUNDLE="$OTHER/images/jdk-bundle"
OTHER_JRE_BUNDLE="$OTHER/images/jre-bundle"
echo "Also comparing macosx bundles"
echo " $THIS_JDK_BUNDLE"
echo " $OTHER_JDK_BUNDLE"
fi
if [ -d "$THIS/deploy/bundles" -o -d "$THIS/deploy/images/bundles" ] \
@ -1262,19 +1243,21 @@ if [ "$SKIP_DEFAULT" != "true" ]; then
echo "Also comparing deploy javadoc bundles"
fi
if [ -d "$THIS/deploy/JavaAppletPlugin.plugin" -o -d "$THIS/deploy/images/JavaAppletPlugin.plugin" ] \
&& [ -d "$OTHER/deploy/JavaAppletPlugin.plugin" -o -d "$OTHER/deploy/images/JavaAppletPlugin.plugin" ]; then
if [ -d "$THIS/deploy/images/bundles" ]; then
if [ -d "$THIS/images/JavaAppletPlugin.plugin" ] \
&& [ -d "$OTHER/images/JavaAppletPlugin.plugin" -o -d "$OTHER/deploy/images/JavaAppletPlugin.plugin" ]; then
if [ -d "$THIS/images/JavaAppletPlugin.plugin" ]; then
THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/images/JavaAppletPlugin.plugin"
else
THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/images/JavaAppletPlugin.plugin"
else
THIS_DEPLOY_APPLET_PLUGIN_DIR="$THIS/deploy/JavaAppletPlugin.plugin"
fi
if [ -d "$OTHER/deploy/images/bundles" ]; then
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/images/JavaAppletPlugin.plugin"
if [ -d "$OTHER/images/JavaAppletPlugin.plugin" ]; then
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/images/JavaAppletPlugin.plugin"
else
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/JavaAppletPlugin.plugin"
OTHER_DEPLOY_APPLET_PLUGIN_DIR="$OTHER/deploy/images/JavaAppletPlugin.plugin"
fi
echo "Also comparing deploy applet image"
echo " $THIS_DEPLOY_APPLET_PLUGIN_DIR"
echo " $OTHER_DEPLOY_APPLET_PLUGIN_DIR"
fi
if [ -d "$OTHER/images" ]; then

View File

@ -313,3 +313,4 @@ afc1e295c4bf83f9a5dd539c29914edd4a754a3f jdk9-b65
8efad64f40eb8cd4df376c0a5275892eeb396bbd jdk9-b68
de8acedcb5b5870f1dc54cba575aaa5d33897ea2 jdk9-b69
e7cf01990ed366bd493080663259281e91ce223b jdk9-b70
cd39ed501fb0504554a7f58ac6cf3dd2b64afec0 jdk9-b71

View File

@ -65,7 +65,7 @@ import org.omg.CORBA.ValueMember;
import sun.corba.Bridge;
/**
* A ObjectStreamClass describes a class that can be serialized to a stream
* An ObjectStreamClass describes a class that can be serialized to a stream
* or a class that was serialized to a stream. It contains the name
* and the serialVersionUID of the class.
* <br>
@ -788,9 +788,9 @@ public class ObjectStreamClass implements java.io.Serializable {
/* Compare the base class names of streamName and localName.
*
* @return Return true iff the base class name compare.
* @parameter streamName Fully qualified class name.
* @parameter localName Fully qualified class name.
* @parameter pkgSeparator class names use either '.' or '/'.
* @param streamName Fully qualified class name.
* @param localName Fully qualified class name.
* @param pkgSeparator class names use either '.' or '/'.
*
* Only compare base class name to allow package renaming.
*/

View File

@ -656,9 +656,9 @@ public class ObjectStreamClass_1_3_1 implements java.io.Serializable {
/* Compare the base class names of streamName and localName.
*
* @return Return true iff the base class name compare.
* @parameter streamName Fully qualified class name.
* @parameter localName Fully qualified class name.
* @parameter pkgSeparator class names use either '.' or '/'.
* @param streamName Fully qualified class name.
* @param localName Fully qualified class name.
* @param pkgSeparator class names use either '.' or '/'.
*
* Only compare base class name to allow package renaming.
*/

View File

@ -27,10 +27,10 @@ package org.omg.CORBA;
/**
* This Helper class is used to facilitate the marshalling of <tt>Bounds</tt>.
* This Helper class is used to facilitate the marshalling of {@code Bounds}.
* For more information on Helper files, see
* <a href="doc-files/generatedfiles.html#helper">
* "Generated Files: Helper Files"</a>.<P>
* "Generated Files: Helper Files"</a>.
*/
abstract public class BoundsHelper

View File

@ -28,10 +28,10 @@ package org.omg.CORBA.ORBPackage;
/**
* This Helper class is used to facilitate the marshalling of
* <tt>ORBPackage/InvalidName</tt>.
* {@code ORBPackage/InvalidName}.
* For more information on Helper files, see
* <a href="doc-files/generatedfiles.html#helper">
* "Generated Files: Helper Files"</a>.<P>
* "Generated Files: Helper Files"</a>.
*/
abstract public class InvalidNameHelper

View File

@ -28,10 +28,10 @@ package org.omg.CORBA.TypeCodePackage;
/**
* This Helper class is used to facilitate the marshalling of
* <tt>TypeCodePackage/BadKind</tt>.
* {@code TypeCodePackage/BadKind}.
* For more information on Helper files, see
* <a href="doc-files/generatedfiles.html#helper">
* "Generated Files: Helper Files"</a>.<P>
* "Generated Files: Helper Files"</a>.
*/
abstract public class BadKindHelper

View File

@ -28,10 +28,10 @@ package org.omg.CORBA.TypeCodePackage;
/**
* This Helper class is used to facilitate the marshalling of
* <tt>TypeCodePackage/Bounds</tt>.
* {@code TypeCodePackage/Bounds}.
* For more information on Helper files, see
* <a href="doc-files/generatedfiles.html#helper">
* "Generated Files: Helper Files"</a>.<P>
* "Generated Files: Helper Files"</a>.
*/
abstract public class BoundsHelper

View File

@ -473,3 +473,4 @@ d47dfabd16d48eb96a451edd1b61194a39ee0eb5 jdk9-b67
11af3990d56c97b40318bc1f20608e86f051a3f7 jdk9-b68
ff0929a59ced0e144201aa05819ae2e47d6f2c61 jdk9-b69
8672e9264db30c21504063932dbc374eabc287a1 jdk9-b70
07c6b035d68b0c41b1dcd442157b50b41a2551e9 jdk9-b71

View File

@ -58,6 +58,7 @@ sun.jvm.hotspot.debugger.cdbg.basic.x86 \
sun.jvm.hotspot.debugger.dummy \
sun.jvm.hotspot.debugger.linux \
sun.jvm.hotspot.debugger.linux.amd64 \
sun.jvm.hotspot.debugger.linux.aarch64 \
sun.jvm.hotspot.debugger.linux.ppc64 \
sun.jvm.hotspot.debugger.linux.x86 \
sun.jvm.hotspot.debugger.posix \
@ -65,6 +66,7 @@ sun.jvm.hotspot.debugger.posix.elf \
sun.jvm.hotspot.debugger.ppc64 \
sun.jvm.hotspot.debugger.proc \
sun.jvm.hotspot.debugger.proc.amd64 \
sun.jvm.hotspot.debugger.proc.aarch64 \
sun.jvm.hotspot.debugger.proc.ppc64 \
sun.jvm.hotspot.debugger.proc.sparc \
sun.jvm.hotspot.debugger.proc.x86 \
@ -91,11 +93,13 @@ sun.jvm.hotspot.oops \
sun.jvm.hotspot.prims \
sun.jvm.hotspot.runtime \
sun.jvm.hotspot.runtime.amd64 \
sun.jvm.hotspot.runtime.aarch64 \
sun.jvm.hotspot.runtime.bsd \
sun.jvm.hotspot.runtime.bsd_amd64 \
sun.jvm.hotspot.runtime.bsd_x86 \
sun.jvm.hotspot.runtime.linux \
sun.jvm.hotspot.runtime.linux_amd64 \
sun.jvm.hotspot.runtime.linux_aarch64 \
sun.jvm.hotspot.runtime.linux_ppc64 \
sun.jvm.hotspot.runtime.linux_sparc \
sun.jvm.hotspot.runtime.linux_x86 \
@ -149,16 +153,19 @@ sun/jvm/hotspot/debugger/dummy/*.java \
sun/jvm/hotspot/debugger/linux/*.java \
sun/jvm/hotspot/debugger/linux/ppc64/*.java \
sun/jvm/hotspot/debugger/linux/x86/*.java \
sun/jvm/hotspot/debugger/linux/aarch64/*.java \
sun/jvm/hotspot/debugger/posix/*.java \
sun/jvm/hotspot/debugger/posix/elf/*.java \
sun/jvm/hotspot/debugger/ppc64/*.java \
sun/jvm/hotspot/debugger/proc/*.java \
sun/jvm/hotspot/debugger/proc/amd64/*.java \
sun/jvm/hotspot/debugger/proc/aarch64/*.java \
sun/jvm/hotspot/debugger/proc/ppc64/*.java \
sun/jvm/hotspot/debugger/proc/sparc/*.java \
sun/jvm/hotspot/debugger/proc/x86/*.java \
sun/jvm/hotspot/debugger/remote/*.java \
sun/jvm/hotspot/debugger/remote/amd64/*.java \
sun/jvm/hotspot/debugger/remote/aarch64/*.java \
sun/jvm/hotspot/debugger/remote/ppc64/*.java \
sun/jvm/hotspot/debugger/remote/sparc/*.java \
sun/jvm/hotspot/debugger/remote/x86/*.java \
@ -178,11 +185,13 @@ sun/jvm/hotspot/opto/*.java \
sun/jvm/hotspot/prims/*.java \
sun/jvm/hotspot/runtime/*.java \
sun/jvm/hotspot/runtime/amd64/*.java \
sun/jvm/hotspot/runtime/aarch64/*.java \
sun/jvm/hotspot/runtime/bsd/*.java \
sun/jvm/hotspot/runtime/bsd_amd64/*.java \
sun/jvm/hotspot/runtime/bsd_x86/*.java \
sun/jvm/hotspot/runtime/linux/*.java \
sun/jvm/hotspot/runtime/linux_amd64/*.java \
sun/jvm/hotspot/runtime/linux_aarch64/*.java \
sun/jvm/hotspot/runtime/linux_ppc64/*.java \
sun/jvm/hotspot/runtime/linux_sparc/*.java \
sun/jvm/hotspot/runtime/linux_x86/*.java \

View File

@ -53,6 +53,10 @@
#include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
#endif
#ifdef aarch64
#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
#endif
static jfieldID p_ps_prochandle_ID = 0;
static jfieldID threadList_ID = 0;
static jfieldID loadObjectList_ID = 0;
@ -368,7 +372,7 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#endif
#ifdef aarch64
#define NPRGREG 32
#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG
#endif
#if defined(sparc) || defined(sparcv9)
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
@ -473,6 +477,13 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLo
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
{
int i;
for (i = 0; i < 31; i++)
regs[i] = gregs.regs[i];
regs[REG_INDEX(SP)] = gregs.sp;
regs[REG_INDEX(PC)] = gregs.pc;
}
#endif /* aarch64 */
#ifdef ppc64

View File

@ -53,14 +53,15 @@ $(ARCH)/LinuxDebuggerLocal.o: LinuxDebuggerLocal.c
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
sun.jvm.hotspot.debugger.x86.X86ThreadContext \
sun.jvm.hotspot.debugger.sparc.SPARCThreadContext \
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext \
sun.jvm.hotspot.debugger.aarch64.AARCH64ThreadContext
$(GCC) $(CFLAGS) $< -o $@
$(ARCH)/sadis.o: ../../share/native/sadis.c
$(JAVAH) -jni -classpath ../../../build/classes -d $(ARCH) \
sun.jvm.hotspot.asm.Disassembler
$(GCC) $(CFLAGS) $< -o $@
$(ARCH)/%.o: %.c
$(GCC) $(CFLAGS) $< -o $@

View File

@ -72,6 +72,7 @@ combination of ptrace and /proc calls.
#define user_regs_struct pt_regs
#endif
#if defined(aarch64)
#include <asm/ptrace.h>
#define user_regs_struct user_pt_regs
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,7 @@
// Linux does not have the proc service library, though it does provide the
// thread_db library which can be used to manipulate threads without having
// to know the details of LinuxThreads or NPTL
// to know the details of NPTL
// copied from Solaris "proc_service.h"
typedef enum {

View File

@ -983,19 +983,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
curFrame.getFP(),
anno));
} else {
if (VM.getVM().getCPU().equals("x86") || VM.getVM().getCPU().equals("amd64")) {
// For C2, which has null frame pointers on x86/amd64
CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
Address sp = curFrame.getSP();
if (Assert.ASSERTS_ENABLED) {
Assert.that(cb.getFrameSize() > 0, "CodeBlob must have non-zero frame size");
}
annoPanel.addAnnotation(new Annotation(sp,
sp.addOffsetTo(cb.getFrameSize()),
anno));
} else {
Assert.that(VM.getVM().getCPU().equals("ia64"), "only ia64 should reach here");
// For C2, which has null frame pointers on x86/amd64/aarch64
CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
Address sp = curFrame.getSP();
if (Assert.ASSERTS_ENABLED) {
Assert.that(cb.getFrameSize() > 0, "CodeBlob must have non-zero frame size");
}
annoPanel.addAnnotation(new Annotation(sp,
sp.addOffsetTo(cb.getFrameSize()),
anno));
}
// Add interpreter frame annotations

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.aarch64;
import java.lang.annotation.Native;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
/** Specifies the thread context on aarch64 platforms; only a sub-portion
* of the context is guaranteed to be present on all operating
* systems. */
public abstract class AARCH64ThreadContext implements ThreadContext {
// Taken from /usr/include/asm/sigcontext.h on Linux/AARCH64.
// NOTE: the indices for the various registers must be maintained as
// listed across various operating systems. However, only a small
// subset of the registers' values are guaranteed to be present (and
// must be present for the SA's stack walking to work)
// One instance of the Native annotation is enough to trigger header generation
// for this file.
@Native
public static final int R0 = 0;
public static final int R1 = 1;
public static final int R2 = 2;
public static final int R3 = 3;
public static final int R4 = 4;
public static final int R5 = 5;
public static final int R6 = 6;
public static final int R7 = 7;
public static final int R8 = 8;
public static final int R9 = 9;
public static final int R10 = 10;
public static final int R11 = 11;
public static final int R12 = 12;
public static final int R13 = 13;
public static final int R14 = 14;
public static final int R15 = 15;
public static final int R16 = 16;
public static final int R17 = 17;
public static final int R18 = 18;
public static final int R19 = 19;
public static final int R20 = 20;
public static final int R21 = 21;
public static final int R22 = 22;
public static final int R23 = 23;
public static final int R24 = 24;
public static final int R25 = 25;
public static final int R26 = 26;
public static final int R27 = 27;
public static final int R28 = 28;
public static final int FP = 29;
public static final int LR = 30;
public static final int SP = 31;
public static final int PC = 32;
public static final int NPRGREG = 33;
private long[] data;
public AARCH64ThreadContext() {
data = new long[NPRGREG];
}
public int getNumRegisters() {
return NPRGREG;
}
public String getRegisterName(int index) {
switch (index) {
case LR: return "lr";
case SP: return "sp";
case PC: return "pc";
default:
return "r" + index;
}
}
public void setRegister(int index, long value) {
data[index] = value;
}
public long getRegister(int index) {
return data[index];
}
public CFrame getTopFrame(Debugger dbg) {
return null;
}
/** This can't be implemented in this class since we would have to
* tie the implementation to, for example, the debugging system */
public abstract void setRegisterAsAddress(int index, Address value);
/** This can't be implemented in this class since we would have to
* tie the implementation to, for example, the debugging system */
public abstract Address getRegisterAsAddress(int index);
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,12 +32,14 @@ import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.debugger.amd64.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.sparc.*;
import sun.jvm.hotspot.debugger.ppc64.*;
import sun.jvm.hotspot.debugger.linux.x86.*;
import sun.jvm.hotspot.debugger.linux.amd64.*;
import sun.jvm.hotspot.debugger.linux.sparc.*;
import sun.jvm.hotspot.debugger.linux.ppc64.*;
import sun.jvm.hotspot.debugger.linux.aarch64.*;
import sun.jvm.hotspot.utilities.*;
class LinuxCDebugger implements CDebugger {
@ -106,6 +109,13 @@ class LinuxCDebugger implements CDebugger {
Address pc = context.getRegisterAsAddress(PPC64ThreadContext.PC);
if (pc == null) return null;
return new LinuxPPC64CFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
} else if (cpu.equals("aarch64")) {
AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
if (fp == null) return null;
Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
if (pc == null) return null;
return new LinuxAARCH64CFrame(dbg, fp, pc);
} else {
// Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
ThreadContext context = (ThreadContext) thread.getContext();

View File

@ -0,0 +1,86 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.linux.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.linux.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.cdbg.basic.*;
final public class LinuxAARCH64CFrame extends BasicCFrame {
public LinuxAARCH64CFrame(LinuxDebugger dbg, Address fp, Address pc) {
super(dbg.getCDebugger());
this.fp = fp;
this.pc = pc;
this.dbg = dbg;
}
// override base class impl to avoid ELF parsing
public ClosestSymbol closestSymbolToPC() {
// try native lookup in debugger.
return dbg.lookup(dbg.getAddressValue(pc()));
}
public Address pc() {
return pc;
}
public Address localVariableBase() {
return fp;
}
public CFrame sender(ThreadProxy thread) {
AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
Address rsp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
if ((fp == null) || fp.lessThan(rsp)) {
return null;
}
// Check alignment of fp
if (dbg.getAddressValue(fp) % (2 * ADDRESS_SIZE) != 0) {
return null;
}
Address nextFP = fp.getAddressAt(0 * ADDRESS_SIZE);
if (nextFP == null || nextFP.lessThanOrEqual(fp)) {
return null;
}
Address nextPC = fp.getAddressAt(1 * ADDRESS_SIZE);
if (nextPC == null) {
return null;
}
return new LinuxAARCH64CFrame(dbg, nextFP, nextPC);
}
// package/class internals only
private static final int ADDRESS_SIZE = 8;
private Address pc;
private Address sp;
private Address fp;
private LinuxDebugger dbg;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.linux.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.linux.*;
public class LinuxAARCH64ThreadContext extends AARCH64ThreadContext {
private LinuxDebugger debugger;
public LinuxAARCH64ThreadContext(LinuxDebugger debugger) {
super();
this.debugger = debugger;
}
public void setRegisterAsAddress(int index, Address value) {
setRegister(index, debugger.getAddressValue(value));
}
public Address getRegisterAsAddress(int index) {
return debugger.newAddress(getRegister(index));
}
}

View File

@ -31,11 +31,13 @@ import java.lang.reflect.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.proc.amd64.*;
import sun.jvm.hotspot.debugger.proc.aarch64.*;
import sun.jvm.hotspot.debugger.proc.sparc.*;
import sun.jvm.hotspot.debugger.proc.ppc64.*;
import sun.jvm.hotspot.debugger.proc.x86.*;
import sun.jvm.hotspot.debugger.ppc64.*;
import sun.jvm.hotspot.debugger.amd64.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.sparc.*;
import sun.jvm.hotspot.debugger.x86.*;
import sun.jvm.hotspot.utilities.*;
@ -88,6 +90,10 @@ public class ProcDebuggerLocal extends DebuggerBase implements ProcDebugger {
threadFactory = new ProcAMD64ThreadFactory(this);
pcRegIndex = AMD64ThreadContext.RIP;
fpRegIndex = AMD64ThreadContext.RBP;
} else if (cpu.equals("aarch64")) {
threadFactory = new ProcAARCH64ThreadFactory(this);
pcRegIndex = AARCH64ThreadContext.PC;
fpRegIndex = AARCH64ThreadContext.FP;
} else if (cpu.equals("ppc64")) {
threadFactory = new ProcPPC64ThreadFactory(this);
pcRegIndex = PPC64ThreadContext.PC;

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.proc.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.proc.*;
import sun.jvm.hotspot.utilities.*;
public class ProcAARCH64Thread implements ThreadProxy {
private ProcDebugger debugger;
private int id;
public ProcAARCH64Thread(ProcDebugger debugger, Address addr) {
this.debugger = debugger;
// FIXME: the size here should be configurable. However, making it
// so would produce a dependency on the "types" package from the
// debugger package, which is not desired.
this.id = (int) addr.getCIntegerAt(0, 4, true);
}
public ProcAARCH64Thread(ProcDebugger debugger, long id) {
this.debugger = debugger;
this.id = (int) id;
}
public ThreadContext getContext() throws IllegalThreadStateException {
ProcAARCH64ThreadContext context = new ProcAARCH64ThreadContext(debugger);
long[] regs = debugger.getThreadIntegerRegisterSet(id);
if (Assert.ASSERTS_ENABLED) {
Assert.that(regs.length == AARCH64ThreadContext.NPRGREG, "size mismatch");
}
for (int i = 0; i < regs.length; i++) {
context.setRegister(i, regs[i]);
}
return context;
}
public boolean canSetContext() throws DebuggerException {
return false;
}
public void setContext(ThreadContext context)
throws IllegalThreadStateException, DebuggerException {
throw new DebuggerException("Unimplemented");
}
public String toString() {
return "t@" + id;
}
public boolean equals(Object obj) {
if ((obj == null) || !(obj instanceof ProcAARCH64Thread)) {
return false;
}
return (((ProcAARCH64Thread) obj).id == id);
}
public int hashCode() {
return id;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.proc.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.proc.*;
public class ProcAARCH64ThreadContext extends AARCH64ThreadContext {
private ProcDebugger debugger;
public ProcAARCH64ThreadContext(ProcDebugger debugger) {
super();
this.debugger = debugger;
}
public void setRegisterAsAddress(int index, Address value) {
setRegister(index, debugger.getAddressValue(value));
}
public Address getRegisterAsAddress(int index) {
return debugger.newAddress(getRegister(index));
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.proc.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.proc.*;
public class ProcAARCH64ThreadFactory implements ProcThreadFactory {
private ProcDebugger debugger;
public ProcAARCH64ThreadFactory(ProcDebugger debugger) {
this.debugger = debugger;
}
public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
return new ProcAARCH64Thread(debugger, threadIdentifierAddr);
}
public ThreadProxy createThreadWrapper(long id) {
return new ProcAARCH64Thread(debugger, id);
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.remote.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.remote.*;
import sun.jvm.hotspot.utilities.*;
public class RemoteAARCH64Thread extends RemoteThread {
public RemoteAARCH64Thread(RemoteDebuggerClient debugger, Address addr) {
super(debugger, addr);
}
public RemoteAARCH64Thread(RemoteDebuggerClient debugger, long id) {
super(debugger, id);
}
public ThreadContext getContext() throws IllegalThreadStateException {
RemoteAARCH64ThreadContext context = new RemoteAARCH64ThreadContext(debugger);
long[] regs = (addr != null)? debugger.getThreadIntegerRegisterSet(addr) :
debugger.getThreadIntegerRegisterSet(id);
if (Assert.ASSERTS_ENABLED) {
Assert.that(regs.length == AARCH64ThreadContext.NPRGREG, "size of register set must match");
}
for (int i = 0; i < regs.length; i++) {
context.setRegister(i, regs[i]);
}
return context;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.remote.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.debugger.remote.*;
public class RemoteAARCH64ThreadContext extends AARCH64ThreadContext {
private RemoteDebuggerClient debugger;
public RemoteAARCH64ThreadContext(RemoteDebuggerClient debugger) {
super();
this.debugger = debugger;
}
public void setRegisterAsAddress(int index, Address value) {
setRegister(index, debugger.getAddressValue(value));
}
public Address getRegisterAsAddress(int index) {
return debugger.newAddress(getRegister(index));
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.debugger.remote.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.remote.*;
public class RemoteAARCH64ThreadFactory implements RemoteThreadFactory {
private RemoteDebuggerClient debugger;
public RemoteAARCH64ThreadFactory(RemoteDebuggerClient debugger) {
this.debugger = debugger;
}
public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) {
return new RemoteAARCH64Thread(debugger, threadIdentifierAddr);
}
public ThreadProxy createThreadWrapper(long id) {
return new RemoteAARCH64Thread(debugger, id);
}
}

View File

@ -49,7 +49,6 @@ import sun.jvm.hotspot.types.*;
public abstract class Generation extends VMObject {
private static long reservedFieldOffset;
private static long virtualSpaceFieldOffset;
private static CIntegerField levelField;
protected static final int K = 1024;
// Fields for class StatRecord
private static Field statRecordField;
@ -75,7 +74,6 @@ public abstract class Generation extends VMObject {
reservedFieldOffset = type.getField("_reserved").getOffset();
virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset();
levelField = type.getCIntegerField("_level");
// StatRecord
statRecordField = type.getField("_stat_record");
type = db.lookupType("Generation::StatRecord");
@ -130,14 +128,6 @@ public abstract class Generation extends VMObject {
}
}
public GenerationSpec spec() {
return ((GenCollectedHeap) VM.getVM().getUniverse().heap()).spec(level());
}
public int level() {
return (int) levelField.getValue(addr);
}
public int invocations() {
return getStatRecord().getInvocations();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -357,12 +357,6 @@ public abstract class Frame implements Cloneable {
// FIXME: avoiding implementing this for now if possible
// public void interpreter_frame_set_monitor_end(BasicObjectLock* value);
// public void interpreter_frame_verify_monitor(BasicObjectLock* value) const;
//
// Tells whether the current interpreter_frame frame pointer
// corresponds to the old compiled/deoptimized fp
// The receiver used to be a top level frame
// public boolean interpreter_frame_equals_unpacked_fp(intptr_t* fp);
//--------------------------------------------------------------------------------
// Method and constant pool cache:
//

View File

@ -35,6 +35,7 @@ import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_ppc64.LinuxPPC64JavaThreadPDAccess;
import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
@ -91,6 +92,8 @@ public class Threads {
access = new LinuxSPARCJavaThreadPDAccess();
} else if (cpu.equals("ppc64")) {
access = new LinuxPPC64JavaThreadPDAccess();
} else if (cpu.equals("aarch64")) {
access = new LinuxAARCH64JavaThreadPDAccess();
} else {
try {
access = (JavaThreadPDAccess)

View File

@ -0,0 +1,244 @@
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.interpreter.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.aarch64.*;
/** <P> Should be able to be used on all aarch64 platforms we support
(Linux/aarch64) to implement JavaThread's "currentFrameGuess()"
functionality. Input is an AARCH64ThreadContext; output is SP, FP,
and PC for an AARCH64Frame. Instantiation of the AARCH64Frame is
left to the caller, since we may need to subclass AARCH64Frame to
support signal handler frames on Unix platforms. </P>
<P> Algorithm is to walk up the stack within a given range (say,
512K at most) looking for a plausible PC and SP for a Java frame,
also considering those coming in from the context. If we find a PC
that belongs to the VM (i.e., in generated code like the
interpreter or CodeCache) then we try to find an associated FP.
We repeat this until we either find a complete frame or run out of
stack to look at. </P> */
public class AARCH64CurrentFrameGuess {
private AARCH64ThreadContext context;
private JavaThread thread;
private Address spFound;
private Address fpFound;
private Address pcFound;
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.runtime.aarch64.AARCH64Frame.DEBUG")
!= null;
public AARCH64CurrentFrameGuess(AARCH64ThreadContext context,
JavaThread thread) {
this.context = context;
this.thread = thread;
}
/** Returns false if not able to find a frame within a reasonable range. */
public boolean run(long regionInBytesToSearch) {
Address sp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
Address pc = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
if (sp == null) {
// Bail out if no last java frame either
if (thread.getLastJavaSP() != null) {
setValues(thread.getLastJavaSP(), thread.getLastJavaFP(), null);
return true;
}
return false;
}
Address end = sp.addOffsetTo(regionInBytesToSearch);
VM vm = VM.getVM();
setValues(null, null, null); // Assume we're not going to find anything
if (vm.isJavaPCDbg(pc)) {
if (vm.isClientCompiler()) {
// If the topmost frame is a Java frame, we are (pretty much)
// guaranteed to have a viable FP. We should be more robust
// than this (we have the potential for losing entire threads'
// stack traces) but need to see how much work we really have
// to do here. Searching the stack for an (SP, FP) pair is
// hard since it's easy to misinterpret inter-frame stack
// pointers as base-of-frame pointers; we also don't know the
// sizes of C1 frames (not registered in the nmethod) so can't
// derive them from SP.
setValues(sp, fp, pc);
return true;
} else {
if (vm.getInterpreter().contains(pc)) {
if (DEBUG) {
System.out.println("CurrentFrameGuess: choosing interpreter frame: sp = " +
sp + ", fp = " + fp + ", pc = " + pc);
}
setValues(sp, fp, pc);
return true;
}
// For the server compiler, FP is not guaranteed to be valid
// for compiled code. In addition, an earlier attempt at a
// non-searching algorithm (see below) failed because the
// stack pointer from the thread context was pointing
// (considerably) beyond the ostensible end of the stack, into
// garbage; walking from the topmost frame back caused a crash.
//
// This algorithm takes the current PC as a given and tries to
// find the correct corresponding SP by walking up the stack
// and repeatedly performing stackwalks (very inefficient).
//
// FIXME: there is something wrong with stackwalking across
// adapter frames...this is likely to be the root cause of the
// failure with the simpler algorithm below.
for (long offset = 0;
offset < regionInBytesToSearch;
offset += vm.getAddressSize()) {
try {
Address curSP = sp.addOffsetTo(offset);
Frame frame = new AARCH64Frame(curSP, null, pc);
RegisterMap map = thread.newRegisterMap(false);
while (frame != null) {
if (frame.isEntryFrame() && frame.entryFrameIsFirst()) {
// We were able to traverse all the way to the
// bottommost Java frame.
// This sp looks good. Keep it.
if (DEBUG) {
System.out.println("CurrentFrameGuess: Choosing sp = " + curSP + ", pc = " + pc);
}
setValues(curSP, null, pc);
return true;
}
frame = frame.sender(map);
}
} catch (Exception e) {
if (DEBUG) {
System.out.println("CurrentFrameGuess: Exception " + e + " at offset " + offset);
}
// Bad SP. Try another.
}
}
// Were not able to find a plausible SP to go with this PC.
// Bail out.
return false;
/*
// Original algorithm which does not work because SP was
// pointing beyond where it should have:
// For the server compiler, FP is not guaranteed to be valid
// for compiled code. We see whether the PC is in the
// interpreter and take care of that, otherwise we run code
// (unfortunately) duplicated from AARCH64Frame.senderForCompiledFrame.
CodeCache cc = vm.getCodeCache();
if (cc.contains(pc)) {
CodeBlob cb = cc.findBlob(pc);
// See if we can derive a frame pointer from SP and PC
// NOTE: This is the code duplicated from AARCH64Frame
Address saved_fp = null;
int llink_offset = cb.getLinkOffset();
if (llink_offset >= 0) {
// Restore base-pointer, since next frame might be an interpreter frame.
Address fp_addr = sp.addOffsetTo(VM.getVM().getAddressSize() * llink_offset);
saved_fp = fp_addr.getAddressAt(0);
}
setValues(sp, saved_fp, pc);
return true;
}
*/
}
} else {
// If the current program counter was not known to us as a Java
// PC, we currently assume that we are in the run-time system
// and attempt to look to thread-local storage for saved SP and
// FP. Note that if these are null (because we were, in fact,
// in Java code, i.e., vtable stubs or similar, and the SA
// didn't have enough insight into the target VM to understand
// that) then we are going to lose the entire stack trace for
// the thread, which is sub-optimal. FIXME.
if (DEBUG) {
System.out.println("CurrentFrameGuess: choosing last Java frame: sp = " +
thread.getLastJavaSP() + ", fp = " + thread.getLastJavaFP());
}
if (thread.getLastJavaSP() == null) {
return false; // No known Java frames on stack
}
// The runtime has a nasty habit of not saving fp in the frame
// anchor, leaving us to grovel about in the stack to find a
// plausible address. Fortunately, this only happens in
// compiled code; there we always have a valid PC, and we always
// push LR and FP onto the stack as a pair, with FP at the lower
// address.
pc = thread.getLastJavaPC();
fp = thread.getLastJavaFP();
sp = thread.getLastJavaSP();
if (fp == null) {
CodeCache cc = vm.getCodeCache();
if (cc.contains(pc)) {
CodeBlob cb = cc.findBlob(pc);
if (DEBUG) {
System.out.println("FP is null. Found blob frame size " + cb.getFrameSize());
}
// See if we can derive a frame pointer from SP and PC
long link_offset = cb.getFrameSize() - 2 * VM.getVM().getAddressSize();
if (link_offset >= 0) {
fp = sp.addOffsetTo(link_offset);
}
}
}
setValues(sp, fp, null);
return true;
}
}
public Address getSP() { return spFound; }
public Address getFP() { return fpFound; }
/** May be null if getting values from thread-local storage; take
care to call the correct AARCH64Frame constructor to recover this if
necessary */
public Address getPC() { return pcFound; }
private void setValues(Address sp, Address fp, Address pc) {
spFound = sp;
fpFound = fp;
pcFound = pc;
}
}

View File

@ -0,0 +1,555 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime.aarch64;
import java.util.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
/** Specialization of and implementation of abstract methods of the
Frame class for the aarch64 family of CPUs. */
public class AARCH64Frame extends Frame {
private static final boolean DEBUG;
static {
DEBUG = System.getProperty("sun.jvm.hotspot.runtime.aarch64.AARCH64Frame.DEBUG") != null;
}
// All frames
private static final int LINK_OFFSET = 0;
private static final int RETURN_ADDR_OFFSET = 1;
private static final int SENDER_SP_OFFSET = 2;
// Interpreter frames
private static final int INTERPRETER_FRAME_MIRROR_OFFSET = 2; // for native calls only
private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
private static int INTERPRETER_FRAME_MDX_OFFSET; // Non-core builds only
private static int INTERPRETER_FRAME_CACHE_OFFSET;
private static int INTERPRETER_FRAME_LOCALS_OFFSET;
private static int INTERPRETER_FRAME_BCX_OFFSET;
private static int INTERPRETER_FRAME_INITIAL_SP_OFFSET;
private static int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET;
private static int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
// Entry frames
private static int ENTRY_FRAME_CALL_WRAPPER_OFFSET = -8;
// Native frames
private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET = 2;
private static VMReg fp = new VMReg(29);
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
INTERPRETER_FRAME_BCX_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1;
INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
}
// an additional field beyond sp and pc:
Address raw_fp; // frame pointer
private Address raw_unextendedSP;
private AARCH64Frame() {
}
private void adjustForDeopt() {
if ( pc != null) {
// Look for a deopt pc and if it is deopted convert to original pc
CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
if (cb != null && cb.isJavaMethod()) {
NMethod nm = (NMethod) cb;
if (pc.equals(nm.deoptHandlerBegin())) {
if (Assert.ASSERTS_ENABLED) {
Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
}
// adjust pc if frame is deoptimized.
pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
deoptimized = true;
}
}
}
}
public AARCH64Frame(Address raw_sp, Address raw_fp, Address pc) {
this.raw_sp = raw_sp;
this.raw_unextendedSP = raw_sp;
this.raw_fp = raw_fp;
this.pc = pc;
adjustUnextendedSP();
// Frame must be fully constructed before this call
adjustForDeopt();
if (DEBUG) {
System.out.println("AARCH64Frame(sp, fp, pc): " + this);
dumpStack();
}
}
public AARCH64Frame(Address raw_sp, Address raw_fp) {
this.raw_sp = raw_sp;
this.raw_unextendedSP = raw_sp;
this.raw_fp = raw_fp;
this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
adjustUnextendedSP();
// Frame must be fully constructed before this call
adjustForDeopt();
if (DEBUG) {
System.out.println("AARCH64Frame(sp, fp): " + this);
dumpStack();
}
}
public AARCH64Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
this.raw_sp = raw_sp;
this.raw_unextendedSP = raw_unextendedSp;
this.raw_fp = raw_fp;
this.pc = pc;
adjustUnextendedSP();
// Frame must be fully constructed before this call
adjustForDeopt();
if (DEBUG) {
System.out.println("AARCH64Frame(sp, unextendedSP, fp, pc): " + this);
dumpStack();
}
}
public Object clone() {
AARCH64Frame frame = new AARCH64Frame();
frame.raw_sp = raw_sp;
frame.raw_unextendedSP = raw_unextendedSP;
frame.raw_fp = raw_fp;
frame.pc = pc;
frame.deoptimized = deoptimized;
return frame;
}
public boolean equals(Object arg) {
if (arg == null) {
return false;
}
if (!(arg instanceof AARCH64Frame)) {
return false;
}
AARCH64Frame other = (AARCH64Frame) arg;
return (AddressOps.equal(getSP(), other.getSP()) &&
AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) &&
AddressOps.equal(getFP(), other.getFP()) &&
AddressOps.equal(getPC(), other.getPC()));
}
public int hashCode() {
if (raw_sp == null) {
return 0;
}
return raw_sp.hashCode();
}
public String toString() {
return "sp: " + (getSP() == null? "null" : getSP().toString()) +
", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) +
", fp: " + (getFP() == null? "null" : getFP().toString()) +
", pc: " + (pc == null? "null" : pc.toString());
}
// accessors for the instance variables
public Address getFP() { return raw_fp; }
public Address getSP() { return raw_sp; }
public Address getID() { return raw_sp; }
// FIXME: not implemented yet
public boolean isSignalHandlerFrameDbg() { return false; }
public int getSignalNumberDbg() { return 0; }
public String getSignalNameDbg() { return null; }
public boolean isInterpretedFrameValid() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(isInterpretedFrame(), "Not an interpreted frame");
}
// These are reasonable sanity checks
if (getFP() == null || getFP().andWithMask(0x3) != null) {
return false;
}
if (getSP() == null || getSP().andWithMask(0x3) != null) {
return false;
}
if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) {
return false;
}
// These are hacks to keep us out of trouble.
// The problem with these is that they mask other problems
if (getFP().lessThanOrEqual(getSP())) {
// this attempts to deal with unsigned comparison above
return false;
}
if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) {
// stack frames shouldn't be large.
return false;
}
return true;
}
// FIXME: not applicable in current system
// void patch_pc(Thread* thread, address pc);
public Frame sender(RegisterMap regMap, CodeBlob cb) {
AARCH64RegisterMap map = (AARCH64RegisterMap) regMap;
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}
// Default is we done have to follow them. The sender_for_xxx will
// update it accordingly
map.setIncludeArgumentOops(false);
if (isEntryFrame()) return senderForEntryFrame(map);
if (isInterpretedFrame()) return senderForInterpreterFrame(map);
if(cb == null) {
cb = VM.getVM().getCodeCache().findBlob(getPC());
} else {
if (Assert.ASSERTS_ENABLED) {
Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
}
}
if (cb != null) {
return senderForCompiledFrame(map, cb);
}
// Must be native-compiled frame, i.e. the marshaling code for native
// methods that exists in the core system.
return new AARCH64Frame(getSenderSP(), getLink(), getSenderPC());
}
private Frame senderForEntryFrame(AARCH64RegisterMap map) {
if (DEBUG) {
System.out.println("senderForEntryFrame");
}
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}
// Java frame called from C; skip all C frames and return top C
// frame of that chunk as the sender
AARCH64JavaCallWrapper jcw = (AARCH64JavaCallWrapper) getEntryFrameCallWrapper();
if (Assert.ASSERTS_ENABLED) {
Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
}
AARCH64Frame fr;
if (jcw.getLastJavaPC() != null) {
fr = new AARCH64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC());
} else {
fr = new AARCH64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP());
}
map.clear();
if (Assert.ASSERTS_ENABLED) {
Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
}
return fr;
}
//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
private void adjustUnextendedSP() {
// If we are returning to a compiled MethodHandle call site, the
// saved_fp will in fact be a saved value of the unextended SP. The
// simplest way to tell whether we are returning to such a call site
// is as follows:
CodeBlob cb = cb();
NMethod senderNm = (cb == null) ? null : cb.asNMethodOrNull();
if (senderNm != null) {
// If the sender PC is a deoptimization point, get the original
// PC. For MethodHandle call site the unextended_sp is stored in
// saved_fp.
if (senderNm.isDeoptMhEntry(getPC())) {
// DEBUG_ONLY(verifyDeoptMhOriginalPc(senderNm, getFP()));
raw_unextendedSP = getFP();
}
else if (senderNm.isDeoptEntry(getPC())) {
// DEBUG_ONLY(verifyDeoptOriginalPc(senderNm, raw_unextendedSp));
}
else if (senderNm.isMethodHandleReturn(getPC())) {
raw_unextendedSP = getFP();
}
}
}
private Frame senderForInterpreterFrame(AARCH64RegisterMap map) {
if (DEBUG) {
System.out.println("senderForInterpreterFrame");
}
Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
// We do not need to update the callee-save register mapping because above
// us is either another interpreter frame or a converter-frame, but never
// directly a compiled frame.
// 11/24/04 SFG. With the removal of adapter frames this is no longer true.
// However c2 no longer uses callee save register for java calls so there
// are no callee register to find.
if (map.getUpdateMap())
updateMapWithSavedLink(map, addressOfStackSlot(LINK_OFFSET));
return new AARCH64Frame(sp, unextendedSP, getLink(), getSenderPC());
}
private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) {
map.setLocation(fp, savedFPAddr);
}
private Frame senderForCompiledFrame(AARCH64RegisterMap map, CodeBlob cb) {
if (DEBUG) {
System.out.println("senderForCompiledFrame");
}
//
// NOTE: some of this code is (unfortunately) duplicated AARCH64CurrentFrameGuess
//
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}
// frame owned by optimizing compiler
if (Assert.ASSERTS_ENABLED) {
Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size");
}
Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize());
// The return_address is always the word on the stack
Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize());
// This is the saved value of FP which may or may not really be an FP.
// It is only an FP if the sender is an interpreter frame.
Address savedFPAddr = senderSP.addOffsetTo(- SENDER_SP_OFFSET * VM.getVM().getAddressSize());
if (map.getUpdateMap()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
// outside of update_register_map.
map.setIncludeArgumentOops(cb.callerMustGCArguments());
if (cb.getOopMaps() != null) {
ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
}
// Since the prolog does the save and restore of FP there is no oopmap
// for it so we must fill in its location as if there was an oopmap entry
// since if our caller was compiled code there could be live jvm state in it.
updateMapWithSavedLink(map, savedFPAddr);
}
return new AARCH64Frame(senderSP, savedFPAddr.getAddressAt(0), senderPC);
}
protected boolean hasSenderPD() {
return true;
}
public long frameSize() {
return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
}
public Address getLink() {
try {
if (DEBUG) {
System.out.println("Reading link at " + addressOfStackSlot(LINK_OFFSET)
+ " = " + addressOfStackSlot(LINK_OFFSET).getAddressAt(0));
}
return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
} catch (Exception e) {
if (DEBUG)
System.out.println("Returning null");
return null;
}
}
// FIXME: not implementable yet
//inline void frame::set_link(intptr_t* addr) { *(intptr_t **)addr_at(link_offset) = addr; }
public Address getUnextendedSP() { return raw_unextendedSP; }
// Return address:
public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
public Address getSenderPC() { return getSenderPCAddr().getAddressAt(0); }
// return address of param, zero origin index.
public Address getNativeParamAddr(int idx) {
return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
}
public Address getSenderSP() { return addressOfStackSlot(SENDER_SP_OFFSET); }
public Address addressOfInterpreterFrameLocals() {
return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
}
private Address addressOfInterpreterFrameBCX() {
return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET);
}
public int getInterpreterFrameBCI() {
// FIXME: this is not atomic with respect to GC and is unsuitable
// for use in a non-debugging, or reflective, system. Need to
// figure out how to express this.
Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
Address methodHandle = addressOfInterpreterFrameMethod().getAddressAt(0);
Method method = (Method)Metadata.instantiateWrapperFor(methodHandle);
return bcpToBci(bcp, method);
}
public Address addressOfInterpreterFrameMDX() {
return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET);
}
// FIXME
//inline int frame::interpreter_frame_monitor_size() {
// return BasicObjectLock::size();
//}
// expression stack
// (the max_stack arguments are used by the GC; see class FrameClosure)
public Address addressOfInterpreterFrameExpressionStack() {
Address monitorEnd = interpreterFrameMonitorEnd().address();
return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize());
}
public int getInterpreterFrameExpressionStackDirection() { return -1; }
// top of expression stack
public Address addressOfInterpreterFrameTOS() {
return getSP();
}
/** Expression stack from top down */
public Address addressOfInterpreterFrameTOSAt(int slot) {
return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
}
public Address getInterpreterFrameSenderSP() {
if (Assert.ASSERTS_ENABLED) {
Assert.that(isInterpretedFrame(), "interpreted frame expected");
}
return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
}
// Monitors
public BasicObjectLock interpreterFrameMonitorBegin() {
return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET));
}
public BasicObjectLock interpreterFrameMonitorEnd() {
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
if (Assert.ASSERTS_ENABLED) {
// make sure the pointer points inside the frame
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");
Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
}
return new BasicObjectLock(result);
}
public int interpreterFrameMonitorSize() {
return BasicObjectLock.size();
}
// Method
public Address addressOfInterpreterFrameMethod() {
return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET);
}
// Constant pool cache
public Address addressOfInterpreterFrameCPCache() {
return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET);
}
// Entry frames
public JavaCallWrapper getEntryFrameCallWrapper() {
return new AARCH64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0));
}
protected Address addressOfSavedOopResult() {
// offset is 2 for compiler2 and 3 for compiler1
return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
VM.getVM().getAddressSize());
}
protected Address addressOfSavedReceiver() {
return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
}
private void dumpStack() {
for (Address addr = getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
AddressOps.lt(addr, getSP());
addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
System.out.println(addr + ": " + addr.getAddressAt(0));
}
System.out.println("-----------------------");
for (Address addr = getSP();
AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
System.out.println(addr + ": " + addr.getAddressAt(0));
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime.aarch64;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
public class AARCH64JavaCallWrapper extends JavaCallWrapper {
private static AddressField lastJavaFPField;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("JavaFrameAnchor");
lastJavaFPField = type.getAddressField("_last_Java_fp");
}
public AARCH64JavaCallWrapper(Address addr) {
super(addr);
}
public Address getLastJavaFP() {
return lastJavaFPField.getValue(addr.addOffsetTo(anchorField.getOffset()));
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime.aarch64;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.*;
public class AARCH64RegisterMap extends RegisterMap {
/** This is the only public constructor */
public AARCH64RegisterMap(JavaThread thread, boolean updateMap) {
super(thread, updateMap);
}
protected AARCH64RegisterMap(RegisterMap map) {
super(map);
}
public Object clone() {
AARCH64RegisterMap retval = new AARCH64RegisterMap(this);
return retval;
}
// no PD state to clear or copy:
protected void clearPD() {}
protected void initializePD() {}
protected void initializeFromPD(RegisterMap map) {}
protected Address getLocationPD(VMReg reg) { return null; }
}

View File

@ -0,0 +1,132 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.runtime.linux_aarch64;
import java.io.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.aarch64.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.runtime.aarch64.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
public class LinuxAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
private static AddressField lastJavaFPField;
private static AddressField osThreadField;
// Field from OSThread
private static CIntegerField osThreadThreadIDField;
// This is currently unneeded but is being kept in case we change
// the currentFrameGuess algorithm
private static final long GUESS_SCAN_RANGE = 128 * 1024;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("JavaThread");
osThreadField = type.getAddressField("_osthread");
Type anchorType = db.lookupType("JavaFrameAnchor");
lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
Type osThreadType = db.lookupType("OSThread");
osThreadThreadIDField = osThreadType.getCIntegerField("_thread_id");
}
public Address getLastJavaFP(Address addr) {
return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
}
public Address getLastJavaPC(Address addr) {
return null;
}
public Address getBaseOfStackPointer(Address addr) {
return null;
}
public Frame getLastFramePD(JavaThread thread, Address addr) {
Address fp = thread.getLastJavaFP();
if (fp == null) {
return null; // no information
}
return new AARCH64Frame(thread.getLastJavaSP(), fp);
}
public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
return new AARCH64RegisterMap(thread, updateMap);
}
public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
ThreadProxy t = getThreadProxy(addr);
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread);
if (!guesser.run(GUESS_SCAN_RANGE)) {
return null;
}
if (guesser.getPC() == null) {
return new AARCH64Frame(guesser.getSP(), guesser.getFP());
} else {
return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
}
}
public void printThreadIDOn(Address addr, PrintStream tty) {
tty.print(getThreadProxy(addr));
}
public void printInfoOn(Address threadAddr, PrintStream tty) {
tty.print("Thread id: ");
printThreadIDOn(threadAddr, tty);
// tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
}
public Address getLastSP(Address addr) {
ThreadProxy t = getThreadProxy(addr);
AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
return context.getRegisterAsAddress(AARCH64ThreadContext.SP);
}
public ThreadProxy getThreadProxy(Address addr) {
// Addr is the address of the JavaThread.
// Fetch the OSThread (for now and for simplicity, not making a
// separate "OSThread" class in this package)
Address osThreadAddr = osThreadField.getValue(addr);
// Get the address of the _thread_id from the OSThread
Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
JVMDebugger debugger = VM.getVM().getDebugger();
return debugger.getThreadForIdentifierAddress(threadIdAddr);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,10 @@
package sun.jvm.hotspot.utilities;
public interface AltPlatformInfo {
// Additional cpu types can be tested via this interface
// Additional cpu types can be tested via this interface
public boolean knownCPU(String cpu);
}
// Mangle a cpu name if necessary
public String getCPU(String cpu);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -52,27 +52,54 @@ public class PlatformInfo {
}
}
/* Returns "sparc" for SPARC based platforms and "x86" for x86 based
platforms. Otherwise returns the value of os.arch. If the value
is not recognized as supported, an exception is thrown instead. */
public static boolean knownCPU(String cpu) {
final String[] KNOWN =
new String[] {"i386", "x86", "x86_64", "amd64", "sparc", "sparcv9", "ppc64", "aarch64"};
for(String s : KNOWN) {
if(s.equals(cpu))
return true;
}
return false;
}
/* Returns "sparc" for SPARC based platforms "x86" for x86 based
platforms and x86_64 for 64bit x86 based platform. Otherwise
returns the value of os.arch. If the value is not recognized as supported,
an exception is thrown instead. */
public static String getCPU() throws UnsupportedPlatformException {
String cpu = System.getProperty("os.arch");
if (cpu.equals("i386") || cpu.equals("x86")) {
return "x86";
} else if (cpu.equals("sparc") || cpu.equals("sparcv9")) {
return "sparc";
} else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64") || cpu.equals("ppc64") || cpu.equals("aarch64")) {
return cpu;
} else {
try {
Class pic = Class.forName("sun.jvm.hotspot.utilities.PlatformInfoClosed");
AltPlatformInfo api = (AltPlatformInfo)pic.newInstance();
if (api.knownCPU(cpu)) {
return cpu;
}
} catch (Exception e) {}
throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
// Let any additional CPU mangling fire first
try {
Class pic = Class.forName("sun.jvm.hotspot.utilities.PlatformInfoClosed");
AltPlatformInfo api = (AltPlatformInfo) pic.newInstance();
if (api.knownCPU(cpu)) {
return api.getCPU(cpu);
}
} catch (Exception e) {
// Ignored
}
// Check that CPU is supported
if (!knownCPU(cpu)) {
throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
}
// Tweeks
if (cpu.equals("i386"))
return "x86";
if (cpu.equals("sparcv9"))
return "sparc";
if (cpu.equals("x86_64"))
return "amd64";
return cpu;
}
// this main is invoked from Makefile to make platform specific agent Makefile(s).

View File

@ -84,11 +84,11 @@ public class PointerLocation {
}
public boolean isInNewGen() {
return ((gen != null) && (gen.level() == 0));
return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(0)));
}
public boolean isInOldGen() {
return ((gen != null) && (gen.level() == 1));
return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(1)));
}
public boolean inOtherGen() {
@ -207,8 +207,6 @@ public class PointerLocation {
tty.print("In new generation ");
} else if (isInOldGen()) {
tty.print("In old generation ");
} else if (gen != null) {
tty.print("In Generation " + getGeneration().level());
} else {
tty.print("In unknown section of Java heap");
}

View File

@ -263,14 +263,19 @@ endif
$(DtraceOutDir):
mkdir $(DtraceOutDir)
# When building using a devkit, dtrace cannot find the correct preprocessor so
# we run it explicitly before runing dtrace.
$(DtraceOutDir)/hotspot.h: $(DTRACE_COMMON_SRCDIR)/hotspot.d | $(DtraceOutDir)
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_COMMON_SRCDIR)/hotspot.d
$(QUIETLY) $(CC) -E $(DTRACE_OPTS) -I. -x c $(DTRACE_COMMON_SRCDIR)/hotspot.d > $(DtraceOutDir)/hotspot.d
$(QUIETLY) $(DTRACE_PROG) -h -o $@ -s $(DtraceOutDir)/hotspot.d
$(DtraceOutDir)/hotspot_jni.h: $(DTRACE_COMMON_SRCDIR)/hotspot_jni.d | $(DtraceOutDir)
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_COMMON_SRCDIR)/hotspot_jni.d
$(QUIETLY) $(CC) -E $(DTRACE_OPTS) -I. -x c $(DTRACE_COMMON_SRCDIR)/hotspot_jni.d > $(DtraceOutDir)/hotspot_jni.d
$(QUIETLY) $(DTRACE_PROG) -h -o $@ -s $(DtraceOutDir)/hotspot_jni.d
$(DtraceOutDir)/hs_private.h: $(DTRACE_COMMON_SRCDIR)/hs_private.d | $(DtraceOutDir)
$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -h -o $@ -s $(DTRACE_COMMON_SRCDIR)/hs_private.d
$(QUIETLY) $(CC) -E $(DTRACE_OPTS) -I. -x c $(DTRACE_COMMON_SRCDIR)/hs_private.d > $(DtraceOutDir)/hs_private.d
$(QUIETLY) $(DTRACE_PROG) -h -o $@ -s $(DtraceOutDir)/hs_private.d
dtrace_gen_headers: $(DtraceOutDir)/hotspot.h $(DtraceOutDir)/hotspot_jni.h $(DtraceOutDir)/hs_private.h

View File

@ -56,13 +56,14 @@ all_debug_universal:
universalize: $(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
$(RM) -r $(EXPORT_PATH)/lib/{i386,amd64}
LIPO ?= lipo
# Package built libraries in a universal binary
$(UNIVERSAL_LIPO_LIST):
BUILT_LIPO_FILES="`find $(EXPORT_LIB_DIR)/{i386,amd64}/$(subst $(EXPORT_LIB_DIR)/,,$@) 2>/dev/null`" || test $$? = "1"; \
if [ -n "$${BUILT_LIPO_FILES}" ]; then \
$(MKDIR) -p $(shell dirname $@); \
lipo -create -output $@ $${BUILT_LIPO_FILES}; \
$(LIPO) -create -output $@ $${BUILT_LIPO_FILES}; \
fi

View File

@ -44,6 +44,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/compiler/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/bsd/x86/*.java \
@ -55,6 +56,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ia64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/ppc64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/linux/sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/posix/*.java \
@ -63,6 +65,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/ppc64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/ppc64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/proc/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/*.java \
@ -70,6 +73,7 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/ppc64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/remote/aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/win32/coff/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/debugger/windbg/*.java \
@ -92,11 +96,13 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/prims/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/bsd_x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_amd64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_aarch64/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_x86/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_sparc/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/runtime/linux_ppc64/*.java \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -526,16 +526,6 @@ frame frame::sender(RegisterMap* map) const {
return frame(sender_sp(), link(), sender_pc());
}
bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) {
assert(is_interpreted_frame(), "must be interpreter frame");
Method* method = interpreter_frame_method();
// When unpacking an optimized frame the frame pointer is
// adjusted with:
int diff = (method->max_locals() - method->size_of_parameters()) *
Interpreter::stackElementWords;
return _fp == (fp - diff);
}
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
// QQQ
#ifdef CC_INTERP

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -84,7 +84,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
#ifdef BUILTIN_SIM
#define UseBuiltinSim true
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(bool, NotifySimulator, UseBuiltinSim, \
"tell the AArch64 sim where we are in method code") \
@ -112,7 +112,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
#define NotifySimulator false
#define UseSimulatorCache false
#define DisableBCCheck true
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(bool, NearCpool, true, \
"constant pool is close to instructions") \

View File

@ -2934,41 +2934,40 @@ void MacroAssembler::cmpptr(Register src1, Address src2) {
cmp(src1, rscratch1);
}
void MacroAssembler::store_check(Register obj) {
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
store_check_part_1(obj);
store_check_part_2(obj);
}
void MacroAssembler::store_check(Register obj, Address dst) {
store_check(obj);
}
void MacroAssembler::store_check(Register obj) {
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
// split the store check operation so that other instructions can be scheduled inbetween
void MacroAssembler::store_check_part_1(Register obj) {
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
lsr(obj, obj, CardTableModRefBS::card_shift);
}
void MacroAssembler::store_check_part_2(Register obj) {
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
// The calculation for byte_map_base is as follows:
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
// So this essentially converts an address to a displacement and
// it will never need to be relocated.
lsr(obj, obj, CardTableModRefBS::card_shift);
// FIXME: It's not likely that disp will fit into an offset so we
// don't bother to check, but it could save an instruction.
intptr_t disp = (intptr_t) ct->byte_map_base;
mov(rscratch1, disp);
strb(zr, Address(obj, rscratch1));
assert(CardTableModRefBS::dirty_card_val() == 0, "must be");
{
ExternalAddress cardtable((address) ct->byte_map_base);
unsigned long offset;
adrp(rscratch1, cardtable, offset);
assert(offset == 0, "byte_map_base is misaligned");
}
if (UseCondCardMark) {
Label L_already_dirty;
ldrb(rscratch2, Address(obj, rscratch1));
cbz(rscratch2, L_already_dirty);
strb(zr, Address(obj, rscratch1));
bind(L_already_dirty);
} else {
strb(zr, Address(obj, rscratch1));
}
}
void MacroAssembler::load_klass(Register dst, Register src) {

View File

@ -719,10 +719,6 @@ public:
#endif // INCLUDE_ALL_GCS
// split store_check(Register obj) to enhance instruction interleaving
void store_check_part_1(Register obj);
void store_check_part_2(Register obj);
// oop manipulations
void load_klass(Register dst, Register src);
void store_klass(Register dst, Register src);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2120,6 +2120,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
save_native_result(masm, ret_type, stack_slots);
}
__ mov(c_rarg2, rthread);
__ lea(c_rarg1, Address(sp, lock_slot_offset * VMRegImpl::stack_slot_size));
__ mov(c_rarg0, obj_reg);
@ -2128,7 +2129,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ ldr(r19, Address(rthread, in_bytes(Thread::pending_exception_offset())));
__ str(zr, Address(rthread, in_bytes(Thread::pending_exception_offset())));
rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), 2, 0, 1);
rt_call(masm, CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), 3, 0, 1);
#ifdef ASSERT
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -190,6 +190,11 @@ void VM_Version::get_processor_features() {
}
}
if (UseGHASHIntrinsics) {
warning("GHASH intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
if (FLAG_IS_DEFAULT(UseCRC32Intrinsics)) {
UseCRC32Intrinsics = true;
}

View File

@ -63,7 +63,7 @@ define_pd_global(size_t, CMSYoungGenPerWorker, 16*M); // Default max size of CM
define_pd_global(uintx, TypeProfileLevel, 111);
// Platform dependent flag handling: flags only defined on this platform.
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
/* Load poll address from thread. This is used to implement per-thread */ \
/* safepoints on platforms != IA64. */ \

View File

@ -2475,7 +2475,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
// Slow case of monitor enter.
// Inline a special case of call_VM that disallows any pending_exception.
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), r_oop, r_box);
// Arguments are (oop obj, BasicLock* lock, JavaThread* thread).
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), r_oop, r_box, R16_thread);
__ asm_assert_mem8_is_zero(thread_(pending_exception),
"no pending exception allowed on exit from SharedRuntime::complete_monitor_unlocking_C", 0);

View File

@ -176,6 +176,11 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
if (UseGHASHIntrinsics) {
warning("GHASH intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
if (UseSHA) {
warning("SHA instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseSHA, false);
@ -505,7 +510,8 @@ void VM_Version::determine_section_size() {
void VM_Version::determine_features() {
#if defined(ABI_ELFv2)
const int code_size = (num_features+1+2*7)*BytesPerInstWord; // TODO(asmundak): calculation is incorrect.
// 1 InstWord per call for the blr instruction.
const int code_size = (num_features+1+2*1)*BytesPerInstWord;
#else
// 7 InstWords for each call (function descriptor + blr instruction).
const int code_size = (num_features+1+2*7)*BytesPerInstWord;
@ -540,7 +546,8 @@ void VM_Version::determine_features() {
a->popcntw(R7, R5); // code[6] -> popcntw
a->fcfids(F3, F4); // code[7] -> fcfids
a->vand(VR0, VR0, VR0); // code[8] -> vand
a->lqarx_unchecked(R7, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m
// arg0 of lqarx must be an even register, (arg1 + arg2) must be a multiple of 16
a->lqarx_unchecked(R6, R3_ARG1, R4_ARG2, 1); // code[9] -> lqarx_m
a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher
a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
a->tcheck(0); // code[12] -> tcheck
@ -572,7 +579,8 @@ void VM_Version::determine_features() {
// Execute code. Illegal instructions will be replaced by 0 in the signal handler.
VM_Version::_is_determine_features_test_running = true;
(*test)((address)mid_of_test_area, (uint64_t)0);
// We must align the first argument to 16 bytes because of the lqarx check.
(*test)((address)align_size_up((intptr_t)mid_of_test_area, 16), (uint64_t)0);
VM_Version::_is_determine_features_test_running = false;
// determine which instructions are legal.
@ -614,12 +622,12 @@ void VM_Version::config_dscr() {
MacroAssembler* a = new MacroAssembler(&cb);
// Emit code.
uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->emit_fd();
uint64_t (*get_dscr)() = (uint64_t(*)())(void *)a->function_entry();
uint32_t *code = (uint32_t *)a->pc();
a->mfdscr(R3);
a->blr();
void (*set_dscr)(long) = (void(*)(long))(void *)a->emit_fd();
void (*set_dscr)(long) = (void(*)(long))(void *)a->function_entry();
a->mtdscr(R3);
a->blr();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -129,6 +129,7 @@ class Assembler : public AbstractAssembler {
flog3_op3 = 0x36,
edge_op3 = 0x36,
fsrc_op3 = 0x36,
xmulx_op3 = 0x36,
impdep2_op3 = 0x37,
stpartialf_op3 = 0x37,
jmpl_op3 = 0x38,
@ -220,6 +221,8 @@ class Assembler : public AbstractAssembler {
mdtox_opf = 0x110,
mstouw_opf = 0x111,
mstosw_opf = 0x113,
xmulx_opf = 0x115,
xmulxhi_opf = 0x116,
mxtod_opf = 0x118,
mwtos_opf = 0x119,
@ -1212,6 +1215,9 @@ public:
void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); }
void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); }
void xmulx(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulx_opf) | rs2(s2)); }
void xmulxhi(Register s1, Register s2, Register d) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(xmulx_op3) | rs1(s1) | opf(xmulxhi_opf) | rs2(s2)); }
// Crypto SHA instructions
void sha1() { sha1_only(); emit_int32( op(arith_op) | op3(sha_op3) | opf(sha1_opf)); }

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -599,12 +599,6 @@ bool frame::is_valid_stack_pointer(intptr_t* valid_sp, intptr_t* sp) {
return next_younger_sp_or_null(valid_sp, sp) != NULL;
}
bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) {
assert(is_interpreted_frame(), "must be interpreter frame");
return this->fp() == fp;
}
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
#ifdef CC_INTERP
// Is there anything to do?

View File

@ -81,7 +81,7 @@ define_pd_global(size_t, CMSYoungGenPerWorker, 16*M); // default max size of CM
define_pd_global(uintx, TypeProfileLevel, 111);
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(intx, UseVIS, 99, \
"Highest supported VIS instructions set on Sparc") \

View File

@ -4786,6 +4786,130 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
/* Single and multi-block ghash operations */
address generate_ghash_processBlocks() {
__ align(CodeEntryAlignment);
Label L_ghash_loop, L_aligned, L_main;
StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
address start = __ pc();
Register state = I0;
Register subkeyH = I1;
Register data = I2;
Register len = I3;
__ save_frame(0);
__ ldx(state, 0, O0);
__ ldx(state, 8, O1);
// Loop label for multiblock operations
__ BIND(L_ghash_loop);
// Check if 'data' is unaligned
__ andcc(data, 7, G1);
__ br(Assembler::zero, false, Assembler::pt, L_aligned);
__ delayed()->nop();
Register left_shift = L1;
Register right_shift = L2;
Register data_ptr = L3;
// Get left and right shift values in bits
__ sll(G1, LogBitsPerByte, left_shift);
__ mov(64, right_shift);
__ sub(right_shift, left_shift, right_shift);
// Align to read 'data'
__ sub(data, G1, data_ptr);
// Load first 8 bytes of 'data'
__ ldx(data_ptr, 0, O4);
__ sllx(O4, left_shift, O4);
__ ldx(data_ptr, 8, O5);
__ srlx(O5, right_shift, G4);
__ bset(G4, O4);
// Load second 8 bytes of 'data'
__ sllx(O5, left_shift, O5);
__ ldx(data_ptr, 16, G4);
__ srlx(G4, right_shift, G4);
__ ba(L_main);
__ delayed()->bset(G4, O5);
// If 'data' is aligned, load normally
__ BIND(L_aligned);
__ ldx(data, 0, O4);
__ ldx(data, 8, O5);
__ BIND(L_main);
__ ldx(subkeyH, 0, O2);
__ ldx(subkeyH, 8, O3);
__ xor3(O0, O4, O0);
__ xor3(O1, O5, O1);
__ xmulxhi(O0, O3, G3);
__ xmulx(O0, O2, O5);
__ xmulxhi(O1, O2, G4);
__ xmulxhi(O1, O3, G5);
__ xmulx(O0, O3, G1);
__ xmulx(O1, O3, G2);
__ xmulx(O1, O2, O3);
__ xmulxhi(O0, O2, O4);
__ mov(0xE1, O0);
__ sllx(O0, 56, O0);
__ xor3(O5, G3, O5);
__ xor3(O5, G4, O5);
__ xor3(G5, G1, G1);
__ xor3(G1, O3, G1);
__ srlx(G2, 63, O1);
__ srlx(G1, 63, G3);
__ sllx(G2, 63, O3);
__ sllx(G2, 58, O2);
__ xor3(O3, O2, O2);
__ sllx(G1, 1, G1);
__ or3(G1, O1, G1);
__ xor3(G1, O2, G1);
__ sllx(G2, 1, G2);
__ xmulxhi(G1, O0, O1);
__ xmulx(G1, O0, O2);
__ xmulxhi(G2, O0, O3);
__ xmulx(G2, O0, G1);
__ xor3(O4, O1, O4);
__ xor3(O5, O2, O5);
__ xor3(O5, O3, O5);
__ sllx(O4, 1, O2);
__ srlx(O5, 63, O3);
__ or3(O2, O3, O0);
__ sllx(O5, 1, O1);
__ srlx(G1, 63, O2);
__ or3(O1, O2, O1);
__ xor3(O1, G3, O1);
__ deccc(len);
__ br(Assembler::notZero, true, Assembler::pt, L_ghash_loop);
__ delayed()->add(data, 16, data);
__ stx(O0, I0, 0);
__ stx(O1, I0, 8);
__ ret();
__ delayed()->restore();
return start;
}
void generate_initial() {
// Generates all stubs and initializes the entry points
@ -4859,6 +4983,10 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
}
// generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
}
// generate SHA1/SHA256/SHA512 intrinsics code
if (UseSHA1Intrinsics) {

View File

@ -300,6 +300,17 @@ void VM_Version::initialize() {
}
}
// GHASH/GCM intrinsics
if (has_vis3() && (UseVIS > 2)) {
if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
UseGHASHIntrinsics = true;
}
} else if (UseGHASHIntrinsics) {
if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
warning("GHASH intrinsics require VIS3 insructions support. Intriniscs will be disabled");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
// SHA1, SHA256, and SHA512 instructions were added to SPARC T-series at different times
if (has_sha1() || has_sha256() || has_sha512()) {
if (UseVIS > 0) { // SHA intrinsics use VIS1 instructions

View File

@ -1347,7 +1347,7 @@ void Assembler::andl(Register dst, Register src) {
void Assembler::andnl(Register dst, Register src1, Register src2) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode(dst, src1, src2, false);
int encode = vex_prefix_0F38_and_encode_legacy(dst, src1, src2, false);
emit_int8((unsigned char)0xF2);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -1355,7 +1355,7 @@ void Assembler::andnl(Register dst, Register src1, Register src2) {
void Assembler::andnl(Register dst, Register src1, Address src2) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38(dst, src1, src2, false);
vex_prefix_0F38_legacy(dst, src1, src2, false);
emit_int8((unsigned char)0xF2);
emit_operand(dst, src2);
}
@ -1382,7 +1382,7 @@ void Assembler::bswapl(Register reg) { // bswap
void Assembler::blsil(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode(rbx, dst, src, false);
int encode = vex_prefix_0F38_and_encode_legacy(rbx, dst, src, false);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -1390,14 +1390,14 @@ void Assembler::blsil(Register dst, Register src) {
void Assembler::blsil(Register dst, Address src) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38(rbx, dst, src, false);
vex_prefix_0F38_legacy(rbx, dst, src, false);
emit_int8((unsigned char)0xF3);
emit_operand(rbx, src);
}
void Assembler::blsmskl(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode(rdx, dst, src, false);
int encode = vex_prefix_0F38_and_encode_legacy(rdx, dst, src, false);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -1412,7 +1412,7 @@ void Assembler::blsmskl(Register dst, Address src) {
void Assembler::blsrl(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode(rcx, dst, src, false);
int encode = vex_prefix_0F38_and_encode_legacy(rcx, dst, src, false);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -1420,7 +1420,7 @@ void Assembler::blsrl(Register dst, Register src) {
void Assembler::blsrl(Register dst, Address src) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38(rcx, dst, src, false);
vex_prefix_0F38_legacy(rcx, dst, src, false);
emit_int8((unsigned char)0xF3);
emit_operand(rcx, src);
}
@ -3095,8 +3095,16 @@ void Assembler::pshuflw(XMMRegister dst, Address src, int mode) {
void Assembler::psrldq(XMMRegister dst, int shift) {
// Shift 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F,
false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
int encode = simd_prefix_and_encode(xmm3, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F, false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
emit_int8(0x73);
emit_int8((unsigned char)(0xC0 | encode));
emit_int8(shift);
}
void Assembler::pslldq(XMMRegister dst, int shift) {
// Shift left 128 bit value in xmm register by number of bytes.
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
int encode = simd_prefix_and_encode(xmm7, dst, dst, VEX_SIMD_66, true, VEX_OPCODE_0F, false, AVX_128bit, (VM_Version::supports_avx512bw() == false));
emit_int8(0x73);
emit_int8((unsigned char)(0xC0 | encode));
emit_int8(shift);
@ -3106,15 +3114,16 @@ void Assembler::ptest(XMMRegister dst, Address src) {
assert(VM_Version::supports_sse4_1(), "");
assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
InstructionMark im(this);
simd_prefix(dst, src, VEX_SIMD_66, false, VEX_OPCODE_0F_38);
simd_prefix(dst, xnoreg, src, VEX_SIMD_66, false,
VEX_OPCODE_0F_38, false, AVX_128bit, true);
emit_int8(0x17);
emit_operand(dst, src);
}
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
false, VEX_OPCODE_0F_38);
int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, false,
VEX_OPCODE_0F_38, false, AVX_128bit, true);
emit_int8(0x17);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -3126,7 +3135,7 @@ void Assembler::vptest(XMMRegister dst, Address src) {
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len, true, false);
emit_int8(0x17);
emit_operand(dst, src);
}
@ -3135,7 +3144,7 @@ void Assembler::vptest(XMMRegister dst, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
int vector_len = AVX_256bit;
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
vector_len, VEX_OPCODE_0F_38);
vector_len, VEX_OPCODE_0F_38, true, false);
emit_int8(0x17);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -3146,12 +3155,12 @@ void Assembler::punpcklbw(XMMRegister dst, Address src) {
if (VM_Version::supports_evex()) {
tuple_type = EVEX_FVM;
}
emit_simd_arith(0x60, dst, src, VEX_SIMD_66);
emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false));
}
void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
NOT_LP64(assert(VM_Version::supports_sse2(), ""));
emit_simd_arith(0x60, dst, src, VEX_SIMD_66);
emit_simd_arith(0x60, dst, src, VEX_SIMD_66, false, (VM_Version::supports_avx512vlbw() == false));
}
void Assembler::punpckldq(XMMRegister dst, Address src) {
@ -4979,7 +4988,51 @@ void Assembler::vpbroadcastd(XMMRegister dst, XMMRegister src) {
emit_int8((unsigned char)(0xC0 | encode));
}
// duplicate 4-bytes integer data from src into 8 locations in dest
// duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL
void Assembler::evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
vector_len, VEX_OPCODE_0F_38, false);
emit_int8(0x78);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastb(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_8bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
emit_int8(0x78);
emit_operand(dst, src);
}
// duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL
void Assembler::evpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
vector_len, VEX_OPCODE_0F_38, false);
emit_int8(0x79);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastw(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_16bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
emit_int8(0x79);
emit_operand(dst, src);
}
// duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
void Assembler::evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
@ -4988,6 +5041,121 @@ void Assembler::evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len)
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastd(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_32bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
emit_int8(0x58);
emit_operand(dst, src);
}
// duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
void Assembler::evpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, true, vector_len, false, false);
emit_int8(0x59);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastq(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_64bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len);
emit_int8(0x59);
emit_operand(dst, src);
}
// duplicate single precision fp from src into 4|8|16 locations in dest : requires AVX512VL
void Assembler::evpbroadcastss(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, false, vector_len, false, false);
emit_int8(0x18);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastss(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_32bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector_len);
emit_int8(0x18);
emit_operand(dst, src);
}
// duplicate double precision fp from src into 2|4|8 locations in dest : requires AVX512VL
void Assembler::evpbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, true, vector_len, false, false);
emit_int8(0x19);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::evpbroadcastsd(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_evex(), "");
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_64bit;
InstructionMark im(this);
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, true, vector_len);
emit_int8(0x19);
emit_operand(dst, src);
}
// duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL
void Assembler::evpbroadcastb(XMMRegister dst, Register src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, false, vector_len, false, false);
emit_int8(0x7A);
emit_int8((unsigned char)(0xC0 | encode));
}
// duplicate 2-byte integer data from src into 8|16||32 locations in dest : requires AVX512BW and AVX512VL
void Assembler::evpbroadcastw(XMMRegister dst, Register src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, false, vector_len, false, false);
emit_int8(0x7B);
emit_int8((unsigned char)(0xC0 | encode));
}
// duplicate 4-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
void Assembler::evpbroadcastd(XMMRegister dst, Register src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, false, vector_len, false, false);
emit_int8(0x7C);
emit_int8((unsigned char)(0xC0 | encode));
}
// duplicate 8-byte integer data from src into 4|8|16 locations in dest : requires AVX512VL
void Assembler::evpbroadcastq(XMMRegister dst, Register src, int vector_len) {
assert(VM_Version::supports_evex(), "");
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66,
VEX_OPCODE_0F_38, true, vector_len, false, false);
emit_int8(0x7C);
emit_int8((unsigned char)(0xC0 | encode));
}
// Carry-Less Multiplication Quadword
void Assembler::pclmulqdq(XMMRegister dst, XMMRegister src, int mask) {
assert(VM_Version::supports_clmul(), "");
@ -5598,7 +5766,7 @@ void Assembler::evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool vex_w, bool
void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix pre,
VexOpcode opc, bool vex_w, int vector_len, bool legacy_mode, bool no_mask_reg) {
bool vex_r = (xreg_enc >= 8);
bool vex_r = ((xreg_enc & 8) == 8) ? 1 : 0;
bool vex_b = adr.base_needs_rex();
bool vex_x = adr.index_needs_rex();
avx_vector_len = vector_len;
@ -5626,8 +5794,8 @@ void Assembler::vex_prefix(Address adr, int nds_enc, int xreg_enc, VexSimdPrefix
int Assembler::vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc, VexSimdPrefix pre, VexOpcode opc,
bool vex_w, int vector_len, bool legacy_mode, bool no_mask_reg ) {
bool vex_r = (dst_enc >= 8);
bool vex_b = (src_enc >= 8);
bool vex_r = ((dst_enc & 8) == 8) ? 1 : 0;
bool vex_b = ((src_enc & 8) == 8) ? 1 : 0;
bool vex_x = false;
avx_vector_len = vector_len;
@ -6272,19 +6440,15 @@ void Assembler::andq(Register dst, Register src) {
void Assembler::andnq(Register dst, Register src1, Register src2) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode_q(dst, src1, src2);
int encode = vex_prefix_0F38_and_encode_q_legacy(dst, src1, src2);
emit_int8((unsigned char)0xF2);
emit_int8((unsigned char)(0xC0 | encode));
}
void Assembler::andnq(Register dst, Register src1, Address src2) {
if (VM_Version::supports_evex()) {
tuple_type = EVEX_T1S;
input_size_in_bits = EVEX_64bit;
}
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38_q(dst, src1, src2);
vex_prefix_0F38_q_legacy(dst, src1, src2);
emit_int8((unsigned char)0xF2);
emit_operand(dst, src2);
}
@ -6311,7 +6475,7 @@ void Assembler::bswapq(Register reg) {
void Assembler::blsiq(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode_q(rbx, dst, src);
int encode = vex_prefix_0F38_and_encode_q_legacy(rbx, dst, src);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -6319,14 +6483,14 @@ void Assembler::blsiq(Register dst, Register src) {
void Assembler::blsiq(Register dst, Address src) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38_q(rbx, dst, src);
vex_prefix_0F38_q_legacy(rbx, dst, src);
emit_int8((unsigned char)0xF3);
emit_operand(rbx, src);
}
void Assembler::blsmskq(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode_q(rdx, dst, src);
int encode = vex_prefix_0F38_and_encode_q_legacy(rdx, dst, src);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -6334,14 +6498,14 @@ void Assembler::blsmskq(Register dst, Register src) {
void Assembler::blsmskq(Register dst, Address src) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38_q(rdx, dst, src);
vex_prefix_0F38_q_legacy(rdx, dst, src);
emit_int8((unsigned char)0xF3);
emit_operand(rdx, src);
}
void Assembler::blsrq(Register dst, Register src) {
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
int encode = vex_prefix_0F38_and_encode_q(rcx, dst, src);
int encode = vex_prefix_0F38_and_encode_q_legacy(rcx, dst, src);
emit_int8((unsigned char)0xF3);
emit_int8((unsigned char)(0xC0 | encode));
}
@ -6349,7 +6513,7 @@ void Assembler::blsrq(Register dst, Register src) {
void Assembler::blsrq(Register dst, Address src) {
InstructionMark im(this);
assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
vex_prefix_0F38_q(rcx, dst, src);
vex_prefix_0F38_q_legacy(rcx, dst, src);
emit_int8((unsigned char)0xF3);
emit_operand(rcx, src);
}

View File

@ -661,6 +661,14 @@ private:
vector_len, no_mask_reg);
}
void vex_prefix_0F38_legacy(Register dst, Register nds, Address src, bool no_mask_reg = false) {
bool vex_w = false;
int vector_len = AVX_128bit;
vex_prefix(src, nds->encoding(), dst->encoding(),
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
vector_len, true, no_mask_reg);
}
void vex_prefix_0F38_q(Register dst, Register nds, Address src, bool no_mask_reg = false) {
bool vex_w = true;
int vector_len = AVX_128bit;
@ -668,6 +676,15 @@ private:
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
vector_len, no_mask_reg);
}
void vex_prefix_0F38_q_legacy(Register dst, Register nds, Address src, bool no_mask_reg = false) {
bool vex_w = true;
int vector_len = AVX_128bit;
vex_prefix(src, nds->encoding(), dst->encoding(),
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
vector_len, true, no_mask_reg);
}
int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
VexSimdPrefix pre, VexOpcode opc,
bool vex_w, int vector_len,
@ -680,6 +697,15 @@ private:
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
false, no_mask_reg);
}
int vex_prefix_0F38_and_encode_legacy(Register dst, Register nds, Register src, bool no_mask_reg = false) {
bool vex_w = false;
int vector_len = AVX_128bit;
return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
true, no_mask_reg);
}
int vex_prefix_0F38_and_encode_q(Register dst, Register nds, Register src, bool no_mask_reg = false) {
bool vex_w = true;
int vector_len = AVX_128bit;
@ -687,6 +713,15 @@ private:
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
false, no_mask_reg);
}
int vex_prefix_0F38_and_encode_q_legacy(Register dst, Register nds, Register src, bool no_mask_reg = false) {
bool vex_w = true;
int vector_len = AVX_128bit;
return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
true, no_mask_reg);
}
int vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
VexSimdPrefix pre, int vector_len = AVX_128bit,
VexOpcode opc = VEX_OPCODE_0F, bool legacy_mode = false,
@ -1666,6 +1701,8 @@ private:
// Shift Right by bytes Logical DoubleQuadword Immediate
void psrldq(XMMRegister dst, int shift);
// Shift Left by bytes Logical DoubleQuadword Immediate
void pslldq(XMMRegister dst, int shift);
// Logical Compare 128bit
void ptest(XMMRegister dst, XMMRegister src);
@ -2024,8 +2061,25 @@ private:
// duplicate 4-bytes integer data from src into 8 locations in dest
void vpbroadcastd(XMMRegister dst, XMMRegister src);
// duplicate 4-bytes integer data from src into vector_len locations in dest
// duplicate n-bytes integer data from src into vector_len locations in dest
void evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastb(XMMRegister dst, Address src, int vector_len);
void evpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastw(XMMRegister dst, Address src, int vector_len);
void evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastd(XMMRegister dst, Address src, int vector_len);
void evpbroadcastq(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastq(XMMRegister dst, Address src, int vector_len);
void evpbroadcastss(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastss(XMMRegister dst, Address src, int vector_len);
void evpbroadcastsd(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastsd(XMMRegister dst, Address src, int vector_len);
void evpbroadcastb(XMMRegister dst, Register src, int vector_len);
void evpbroadcastw(XMMRegister dst, Register src, int vector_len);
void evpbroadcastd(XMMRegister dst, Register src, int vector_len);
void evpbroadcastq(XMMRegister dst, Register src, int vector_len);
// Carry-Less Multiplication Quadword
void pclmulqdq(XMMRegister dst, XMMRegister src, int mask);

View File

@ -58,4 +58,6 @@ void Compile::pd_compiler2_init() {
OptoReg::invalidate(i);
}
}
SuperWordLoopUnrollAnalysis = true;
}

View File

@ -524,17 +524,6 @@ frame frame::sender(RegisterMap* map) const {
return frame(sender_sp(), link(), sender_pc());
}
bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) {
assert(is_interpreted_frame(), "must be interpreter frame");
Method* method = interpreter_frame_method();
// When unpacking an optimized frame the frame pointer is
// adjusted with:
int diff = (method->max_locals() - method->size_of_parameters()) *
Interpreter::stackElementWords;
return _fp == (fp - diff);
}
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
// QQQ
#ifdef CC_INTERP

View File

@ -84,7 +84,7 @@ define_pd_global(uintx, TypeProfileLevel, 111);
define_pd_global(bool, PreserveFramePointer, false);
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
develop(bool, IEEEPrecision, true, \
"Enables IEEE precision (for INTEL only)") \

View File

@ -4260,31 +4260,24 @@ void MacroAssembler::g1_write_barrier_post(Register store_addr,
//////////////////////////////////////////////////////////////////////////////////
void MacroAssembler::store_check(Register obj) {
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
store_check_part_1(obj);
store_check_part_2(obj);
}
void MacroAssembler::store_check(Register obj, Address dst) {
store_check(obj);
}
void MacroAssembler::store_check(Register obj) {
// Does a store check for the oop in register obj. The content of
// register obj is destroyed afterwards.
// split the store check operation so that other instructions can be scheduled inbetween
void MacroAssembler::store_check_part_1(Register obj) {
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
shrptr(obj, CardTableModRefBS::card_shift);
}
void MacroAssembler::store_check_part_2(Register obj) {
BarrierSet* bs = Universe::heap()->barrier_set();
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
shrptr(obj, CardTableModRefBS::card_shift);
Address card_addr;
// The calculation for byte_map_base is as follows:
// byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
// So this essentially converts an address to a displacement and it will
@ -4292,8 +4285,7 @@ void MacroAssembler::store_check_part_2(Register obj) {
// large for a 32bit displacement.
intptr_t disp = (intptr_t) ct->byte_map_base;
if (is_simm32(disp)) {
Address cardtable(noreg, obj, Address::times_1, disp);
movb(cardtable, 0);
card_addr = Address(noreg, obj, Address::times_1, disp);
} else {
// By doing it as an ExternalAddress 'disp' could be converted to a rip-relative
// displacement and done in a single instruction given favorable mapping and a
@ -4301,7 +4293,21 @@ void MacroAssembler::store_check_part_2(Register obj) {
// entry and that entry is not properly handled by the relocation code.
AddressLiteral cardtable((address)ct->byte_map_base, relocInfo::none);
Address index(noreg, obj, Address::times_1);
movb(as_Address(ArrayAddress(cardtable, index)), 0);
card_addr = as_Address(ArrayAddress(cardtable, index));
}
int dirty = CardTableModRefBS::dirty_card_val();
if (UseCondCardMark) {
Label L_already_dirty;
if (UseConcMarkSweepGC) {
membar(Assembler::StoreLoad);
}
cmpb(card_addr, dirty);
jcc(Assembler::equal, L_already_dirty);
movb(card_addr, dirty);
bind(L_already_dirty);
} else {
movb(card_addr, dirty);
}
}

View File

@ -315,10 +315,6 @@ class MacroAssembler: public Assembler {
#endif // INCLUDE_ALL_GCS
// split store_check(Register obj) to enhance instruction interleaving
void store_check_part_1(Register obj);
void store_check_part_2(Register obj);
// C 'boolean' to Java boolean: x == 0 ? 0 : 1
void c2bool(Register x);

View File

@ -365,22 +365,22 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
if (UseAVX > 2) {
map->set_callee_saved(STACK_OFFSET(xmm16H_off), xmm16->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm17H_off), xmm17->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm18H_off), xmm18->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm19H_off), xmm19->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm20H_off), xmm20->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm21H_off), xmm21->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm22H_off), xmm22->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm23H_off), xmm23->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm24H_off), xmm24->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm25H_off), xmm25->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm26H_off), xmm26->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm27H_off), xmm27->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm28H_off), xmm28->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm29H_off), xmm29->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm30H_off), xmm30->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm31H_off), xmm31->as_VMReg());
map->set_callee_saved(STACK_OFFSET(xmm16H_off), xmm16->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm17H_off), xmm17->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm18H_off), xmm18->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm19H_off), xmm19->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm20H_off), xmm20->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm21H_off), xmm21->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm22H_off), xmm22->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm23H_off), xmm23->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm24H_off), xmm24->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm25H_off), xmm25->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm26H_off), xmm26->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm27H_off), xmm27->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm28H_off), xmm28->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm29H_off), xmm29->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm30H_off), xmm30->as_VMReg()->next());
map->set_callee_saved(STACK_OFFSET(xmm31H_off), xmm31->as_VMReg()->next());
}
}
@ -466,7 +466,7 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
__ vinsertf64x4h(xmm29, Address(rsp, 928));
__ vinsertf64x4h(xmm30, Address(rsp, 960));
__ vinsertf64x4h(xmm31, Address(rsp, 992));
__ subptr(rsp, 1024);
__ addptr(rsp, 1024);
}
}
#else

View File

@ -2727,6 +2727,167 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// byte swap x86 long
address generate_ghash_long_swap_mask() {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask");
address start = __ pc();
__ emit_data(0x0b0a0908, relocInfo::none, 0);
__ emit_data(0x0f0e0d0c, relocInfo::none, 0);
__ emit_data(0x03020100, relocInfo::none, 0);
__ emit_data(0x07060504, relocInfo::none, 0);
return start;
}
// byte swap x86 byte array
address generate_ghash_byte_swap_mask() {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask");
address start = __ pc();
__ emit_data(0x0c0d0e0f, relocInfo::none, 0);
__ emit_data(0x08090a0b, relocInfo::none, 0);
__ emit_data(0x04050607, relocInfo::none, 0);
__ emit_data(0x00010203, relocInfo::none, 0);
return start;
}
/* Single and multi-block ghash operations */
address generate_ghash_processBlocks() {
assert(UseGHASHIntrinsics, "need GHASH intrinsics and CLMUL support");
__ align(CodeEntryAlignment);
Label L_ghash_loop, L_exit;
StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
address start = __ pc();
const Register state = rdi;
const Register subkeyH = rsi;
const Register data = rdx;
const Register blocks = rcx;
const Address state_param(rbp, 8+0);
const Address subkeyH_param(rbp, 8+4);
const Address data_param(rbp, 8+8);
const Address blocks_param(rbp, 8+12);
const XMMRegister xmm_temp0 = xmm0;
const XMMRegister xmm_temp1 = xmm1;
const XMMRegister xmm_temp2 = xmm2;
const XMMRegister xmm_temp3 = xmm3;
const XMMRegister xmm_temp4 = xmm4;
const XMMRegister xmm_temp5 = xmm5;
const XMMRegister xmm_temp6 = xmm6;
const XMMRegister xmm_temp7 = xmm7;
__ enter();
__ movptr(state, state_param);
__ movptr(subkeyH, subkeyH_param);
__ movptr(data, data_param);
__ movptr(blocks, blocks_param);
__ movdqu(xmm_temp0, Address(state, 0));
__ pshufb(xmm_temp0, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
__ movdqu(xmm_temp1, Address(subkeyH, 0));
__ pshufb(xmm_temp1, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
__ BIND(L_ghash_loop);
__ movdqu(xmm_temp2, Address(data, 0));
__ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr()));
__ pxor(xmm_temp0, xmm_temp2);
//
// Multiply with the hash key
//
__ movdqu(xmm_temp3, xmm_temp0);
__ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0
__ movdqu(xmm_temp4, xmm_temp0);
__ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1
__ movdqu(xmm_temp5, xmm_temp0);
__ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0
__ movdqu(xmm_temp6, xmm_temp0);
__ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1
__ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0
__ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5
__ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right
__ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left
__ pxor(xmm_temp3, xmm_temp5);
__ pxor(xmm_temp6, xmm_temp4); // Register pair <xmm6:xmm3> holds the result
// of the carry-less multiplication of
// xmm0 by xmm1.
// We shift the result of the multiplication by one bit position
// to the left to cope for the fact that the bits are reversed.
__ movdqu(xmm_temp7, xmm_temp3);
__ movdqu(xmm_temp4, xmm_temp6);
__ pslld (xmm_temp3, 1);
__ pslld(xmm_temp6, 1);
__ psrld(xmm_temp7, 31);
__ psrld(xmm_temp4, 31);
__ movdqu(xmm_temp5, xmm_temp7);
__ pslldq(xmm_temp4, 4);
__ pslldq(xmm_temp7, 4);
__ psrldq(xmm_temp5, 12);
__ por(xmm_temp3, xmm_temp7);
__ por(xmm_temp6, xmm_temp4);
__ por(xmm_temp6, xmm_temp5);
//
// First phase of the reduction
//
// Move xmm3 into xmm4, xmm5, xmm7 in order to perform the shifts
// independently.
__ movdqu(xmm_temp7, xmm_temp3);
__ movdqu(xmm_temp4, xmm_temp3);
__ movdqu(xmm_temp5, xmm_temp3);
__ pslld(xmm_temp7, 31); // packed right shift shifting << 31
__ pslld(xmm_temp4, 30); // packed right shift shifting << 30
__ pslld(xmm_temp5, 25); // packed right shift shifting << 25
__ pxor(xmm_temp7, xmm_temp4); // xor the shifted versions
__ pxor(xmm_temp7, xmm_temp5);
__ movdqu(xmm_temp4, xmm_temp7);
__ pslldq(xmm_temp7, 12);
__ psrldq(xmm_temp4, 4);
__ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete
//
// Second phase of the reduction
//
// Make 3 copies of xmm3 in xmm2, xmm5, xmm7 for doing these
// shift operations.
__ movdqu(xmm_temp2, xmm_temp3);
__ movdqu(xmm_temp7, xmm_temp3);
__ movdqu(xmm_temp5, xmm_temp3);
__ psrld(xmm_temp2, 1); // packed left shifting >> 1
__ psrld(xmm_temp7, 2); // packed left shifting >> 2
__ psrld(xmm_temp5, 7); // packed left shifting >> 7
__ pxor(xmm_temp2, xmm_temp7); // xor the shifted versions
__ pxor(xmm_temp2, xmm_temp5);
__ pxor(xmm_temp2, xmm_temp4);
__ pxor(xmm_temp3, xmm_temp2);
__ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6
__ decrement(blocks);
__ jcc(Assembler::zero, L_exit);
__ movdqu(xmm_temp0, xmm_temp6);
__ addptr(data, 16);
__ jmp(L_ghash_loop);
__ BIND(L_exit);
// Byte swap 16-byte result
__ pshufb(xmm_temp6, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
__ movdqu(Address(state, 0), xmm_temp6); // store the result
__ leave();
__ ret(0);
return start;
}
/**
* Arguments:
*
@ -3026,6 +3187,13 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
}
// Generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask();
StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
}
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,

View File

@ -382,7 +382,12 @@ class StubGenerator: public StubCodeGenerator {
// restore regs belonging to calling function
#ifdef _WIN64
for (int i = 15; i >= 6; i--) {
int xmm_ub = 15;
if (UseAVX > 2) {
xmm_ub = 31;
}
// emit the restores for xmm regs
for (int i = 6; i <= xmm_ub; i++) {
__ movdqu(as_XMMRegister(i), xmm_save(i));
}
#endif
@ -3681,6 +3686,175 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
// byte swap x86 long
address generate_ghash_long_swap_mask() {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "ghash_long_swap_mask");
address start = __ pc();
__ emit_data64(0x0f0e0d0c0b0a0908, relocInfo::none );
__ emit_data64(0x0706050403020100, relocInfo::none );
return start;
}
// byte swap x86 byte array
address generate_ghash_byte_swap_mask() {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "ghash_byte_swap_mask");
address start = __ pc();
__ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none );
__ emit_data64(0x0001020304050607, relocInfo::none );
return start;
}
/* Single and multi-block ghash operations */
address generate_ghash_processBlocks() {
__ align(CodeEntryAlignment);
Label L_ghash_loop, L_exit;
StubCodeMark mark(this, "StubRoutines", "ghash_processBlocks");
address start = __ pc();
const Register state = c_rarg0;
const Register subkeyH = c_rarg1;
const Register data = c_rarg2;
const Register blocks = c_rarg3;
#ifdef _WIN64
const int XMM_REG_LAST = 10;
#endif
const XMMRegister xmm_temp0 = xmm0;
const XMMRegister xmm_temp1 = xmm1;
const XMMRegister xmm_temp2 = xmm2;
const XMMRegister xmm_temp3 = xmm3;
const XMMRegister xmm_temp4 = xmm4;
const XMMRegister xmm_temp5 = xmm5;
const XMMRegister xmm_temp6 = xmm6;
const XMMRegister xmm_temp7 = xmm7;
const XMMRegister xmm_temp8 = xmm8;
const XMMRegister xmm_temp9 = xmm9;
const XMMRegister xmm_temp10 = xmm10;
__ enter();
#ifdef _WIN64
// save the xmm registers which must be preserved 6-10
__ subptr(rsp, -rsp_after_call_off * wordSize);
for (int i = 6; i <= XMM_REG_LAST; i++) {
__ movdqu(xmm_save(i), as_XMMRegister(i));
}
#endif
__ movdqu(xmm_temp10, ExternalAddress(StubRoutines::x86::ghash_long_swap_mask_addr()));
__ movdqu(xmm_temp0, Address(state, 0));
__ pshufb(xmm_temp0, xmm_temp10);
__ BIND(L_ghash_loop);
__ movdqu(xmm_temp2, Address(data, 0));
__ pshufb(xmm_temp2, ExternalAddress(StubRoutines::x86::ghash_byte_swap_mask_addr()));
__ movdqu(xmm_temp1, Address(subkeyH, 0));
__ pshufb(xmm_temp1, xmm_temp10);
__ pxor(xmm_temp0, xmm_temp2);
//
// Multiply with the hash key
//
__ movdqu(xmm_temp3, xmm_temp0);
__ pclmulqdq(xmm_temp3, xmm_temp1, 0); // xmm3 holds a0*b0
__ movdqu(xmm_temp4, xmm_temp0);
__ pclmulqdq(xmm_temp4, xmm_temp1, 16); // xmm4 holds a0*b1
__ movdqu(xmm_temp5, xmm_temp0);
__ pclmulqdq(xmm_temp5, xmm_temp1, 1); // xmm5 holds a1*b0
__ movdqu(xmm_temp6, xmm_temp0);
__ pclmulqdq(xmm_temp6, xmm_temp1, 17); // xmm6 holds a1*b1
__ pxor(xmm_temp4, xmm_temp5); // xmm4 holds a0*b1 + a1*b0
__ movdqu(xmm_temp5, xmm_temp4); // move the contents of xmm4 to xmm5
__ psrldq(xmm_temp4, 8); // shift by xmm4 64 bits to the right
__ pslldq(xmm_temp5, 8); // shift by xmm5 64 bits to the left
__ pxor(xmm_temp3, xmm_temp5);
__ pxor(xmm_temp6, xmm_temp4); // Register pair <xmm6:xmm3> holds the result
// of the carry-less multiplication of
// xmm0 by xmm1.
// We shift the result of the multiplication by one bit position
// to the left to cope for the fact that the bits are reversed.
__ movdqu(xmm_temp7, xmm_temp3);
__ movdqu(xmm_temp8, xmm_temp6);
__ pslld(xmm_temp3, 1);
__ pslld(xmm_temp6, 1);
__ psrld(xmm_temp7, 31);
__ psrld(xmm_temp8, 31);
__ movdqu(xmm_temp9, xmm_temp7);
__ pslldq(xmm_temp8, 4);
__ pslldq(xmm_temp7, 4);
__ psrldq(xmm_temp9, 12);
__ por(xmm_temp3, xmm_temp7);
__ por(xmm_temp6, xmm_temp8);
__ por(xmm_temp6, xmm_temp9);
//
// First phase of the reduction
//
// Move xmm3 into xmm7, xmm8, xmm9 in order to perform the shifts
// independently.
__ movdqu(xmm_temp7, xmm_temp3);
__ movdqu(xmm_temp8, xmm_temp3);
__ movdqu(xmm_temp9, xmm_temp3);
__ pslld(xmm_temp7, 31); // packed right shift shifting << 31
__ pslld(xmm_temp8, 30); // packed right shift shifting << 30
__ pslld(xmm_temp9, 25); // packed right shift shifting << 25
__ pxor(xmm_temp7, xmm_temp8); // xor the shifted versions
__ pxor(xmm_temp7, xmm_temp9);
__ movdqu(xmm_temp8, xmm_temp7);
__ pslldq(xmm_temp7, 12);
__ psrldq(xmm_temp8, 4);
__ pxor(xmm_temp3, xmm_temp7); // first phase of the reduction complete
//
// Second phase of the reduction
//
// Make 3 copies of xmm3 in xmm2, xmm4, xmm5 for doing these
// shift operations.
__ movdqu(xmm_temp2, xmm_temp3);
__ movdqu(xmm_temp4, xmm_temp3);
__ movdqu(xmm_temp5, xmm_temp3);
__ psrld(xmm_temp2, 1); // packed left shifting >> 1
__ psrld(xmm_temp4, 2); // packed left shifting >> 2
__ psrld(xmm_temp5, 7); // packed left shifting >> 7
__ pxor(xmm_temp2, xmm_temp4); // xor the shifted versions
__ pxor(xmm_temp2, xmm_temp5);
__ pxor(xmm_temp2, xmm_temp8);
__ pxor(xmm_temp3, xmm_temp2);
__ pxor(xmm_temp6, xmm_temp3); // the result is in xmm6
__ decrement(blocks);
__ jcc(Assembler::zero, L_exit);
__ movdqu(xmm_temp0, xmm_temp6);
__ addptr(data, 16);
__ jmp(L_ghash_loop);
__ BIND(L_exit);
__ pshufb(xmm_temp6, xmm_temp10); // Byte swap 16-byte result
__ movdqu(Address(state, 0), xmm_temp6); // store the result
#ifdef _WIN64
// restore xmm regs belonging to calling function
for (int i = 6; i <= XMM_REG_LAST; i++) {
__ movdqu(as_XMMRegister(i), xmm_save(i));
}
#endif
__ leave();
__ ret(0);
return start;
}
/**
* Arguments:
*
@ -4120,6 +4294,13 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
}
// Generate GHASH intrinsics code
if (UseGHASHIntrinsics) {
StubRoutines::x86::_ghash_long_swap_mask_addr = generate_ghash_long_swap_mask();
StubRoutines::x86::_ghash_byte_swap_mask_addr = generate_ghash_byte_swap_mask();
StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
}
// Safefetch stubs.
generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry,
&StubRoutines::_safefetch32_fault_pc,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,8 @@
address StubRoutines::x86::_verify_mxcsr_entry = NULL;
address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
address StubRoutines::x86::_ghash_long_swap_mask_addr = NULL;
address StubRoutines::x86::_ghash_byte_swap_mask_addr = NULL;
uint64_t StubRoutines::x86::_crc_by128_masks[] =
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,10 +36,15 @@
// masks and table for CRC32
static uint64_t _crc_by128_masks[];
static juint _crc_table[];
// swap mask for ghash
static address _ghash_long_swap_mask_addr;
static address _ghash_byte_swap_mask_addr;
public:
static address verify_mxcsr_entry() { return _verify_mxcsr_entry; }
static address key_shuffle_mask_addr() { return _key_shuffle_mask_addr; }
static address crc_by128_masks_addr() { return (address)_crc_by128_masks; }
static address ghash_long_swap_mask_addr() { return _ghash_long_swap_mask_addr; }
static address ghash_byte_swap_mask_addr() { return _ghash_byte_swap_mask_addr; }
#endif // CPU_X86_VM_STUBROUTINES_X86_32_HPP

View File

@ -33,7 +33,7 @@ static bool returns_to_call_stub(address return_pc) { return return_pc == _
enum platform_dependent_constants {
code_size1 = 19000, // simply increase if too small (assembler will crash if too small)
code_size2 = 23000 // simply increase if too small (assembler will crash if too small)
code_size2 = 24000 // simply increase if too small (assembler will crash if too small)
};
class x86 {

View File

@ -677,6 +677,17 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
// GHASH/GCM intrinsics
if (UseCLMUL && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
UseGHASHIntrinsics = true;
}
} else if (UseGHASHIntrinsics) {
if (!FLAG_IS_DEFAULT(UseGHASHIntrinsics))
warning("GHASH intrinsic requires CLMUL and SSE2 instructions on this CPU");
FLAG_SET_DEFAULT(UseGHASHIntrinsics, false);
}
if (UseSHA) {
warning("SHA instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseSHA, false);

View File

@ -702,6 +702,7 @@ public:
static bool supports_avx512cd() { return (_cpuFeatures & CPU_AVX512CD) != 0; }
static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; }
static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; }
static bool supports_avx512vlbw() { return (supports_avx512bw() && supports_avx512vl()); }
// Intel features
static bool is_intel_family_core() { return is_intel() &&
extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,8 @@ define_pd_global(uintx, TypeProfileLevel, 0);
define_pd_global(bool, PreserveFramePointer, false);
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(bool, UseFastEmptyMethods, true, \
"Use fast method entry code for empty methods") \
\

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2013 SAP AG. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -38,8 +38,8 @@ class AIXDecoder: public AbstractDecoder {
virtual bool demangle(const char* symbol, char* buf, int buflen) { return false; } // demangled by getFuncName
virtual bool decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
return (::getFuncName((codeptr_t)addr, buf, buflen, offset, 0, 0, 0) == 0);
virtual bool decode(address addr, char* buf, int buflen, int* offset, const char* modulepath, bool demangle) {
return (::getFuncName((codeptr_t)addr, buf, buflen, offset, 0, 0, 0, demangle) == 0);
}
virtual bool decode(address addr, char *buf, int buflen, int* offset, const void *base) {
ShouldNotReachHere();

View File

@ -29,7 +29,7 @@
//
// Defines Aix specific flags. They are not available on other platforms.
//
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
/* Use 64K pages for virtual memory (shmat). */ \
product(bool, Use64KPages, true, \

View File

@ -1439,7 +1439,8 @@ static address resolve_function_descriptor_to_code_pointer(address p) {
}
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
int buflen, int *offset,
bool demangle) {
if (offset) {
*offset = -1;
}
@ -1454,7 +1455,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
}
// Go through Decoder::decode to call getFuncName which reads the name from the traceback table.
return Decoder::decode(addr, buf, buflen, offset);
return Decoder::decode(addr, buf, buflen, offset, demangle);
}
static int getModuleName(codeptr_t pc, // [in] program counter
@ -1653,7 +1654,7 @@ void os::print_memory_info(outputStream* st) {
}
}
void os::pd_print_cpu_info(outputStream* st) {
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
// cpu
st->print("CPU:");
st->print("total %d", os::processor_count());
@ -3761,10 +3762,6 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
return fetcher.result();
}
// Not neede on Aix.
// int os::Aix::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) {
// }
////////////////////////////////////////////////////////////////////////////////
// debug support

View File

@ -114,7 +114,8 @@ extern "C" int getFuncName(
int* p_displacement, // [out] optional: displacement (-1 if not available)
const struct tbtable** p_tb, // [out] optional: ptr to traceback table to get further
// information (NULL if not available)
char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
char* p_errmsg, size_t errmsglen,// [out] optional: user provided buffer for error messages
bool demangle // [in] whether to demangle the name
) {
struct tbtable* tb = 0;
unsigned int searchcount = 0;
@ -216,15 +217,17 @@ extern "C" int getFuncName(
p_name[0] = '\0';
// If it is a C++ name, try and demangle it using the Demangle interface (see demangle.h).
char* rest;
Name* const name = Demangle(buf, rest);
if (name) {
const char* const demangled_name = name->Text();
if (demangled_name) {
strncpy(p_name, demangled_name, namelen-1);
p_name[namelen-1] = '\0';
if (demangle) {
char* rest;
Name* const name = Demangle(buf, rest);
if (name) {
const char* const demangled_name = name->Text();
if (demangled_name) {
strncpy(p_name, demangled_name, namelen-1);
p_name[namelen-1] = '\0';
}
delete name;
}
delete name;
}
// Fallback: if demangling did not work, just provide the unmangled name.
@ -325,7 +328,7 @@ int dladdr(void* addr, Dl_info* info) {
int displacement = 0;
if (getFuncName((codeptr_t) p, funcname, sizeof(funcname), &displacement,
NULL, NULL, 0) == 0) {
NULL, NULL, 0, true /* demangle */) == 0) {
if (funcname[0] != '\0') {
const char* const interned = dladdr_fixed_strings.intern(funcname);
info->dli_sname = interned;

View File

@ -87,7 +87,8 @@ int getFuncName(
char* p_name, size_t namelen, // [out] optional: user provided buffer for the function name
int* p_displacement, // [out] optional: displacement
const struct tbtable** p_tb, // [out] optional: ptr to traceback table to get further information
char* p_errmsg, size_t errmsglen // [out] optional: user provided buffer for error messages
char* p_errmsg, size_t errmsglen,// [out] optional: user provided buffer for error messages
bool demangle = true // [in] whether to demangle the name
);
// -------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,7 @@ class MachODecoder : public AbstractDecoder {
virtual bool decode(address pc, char* buf, int buflen, int* offset,
const void* base);
virtual bool decode(address pc, char* buf, int buflen, int* offset,
const char* module_path = NULL) {
const char* module_path, bool demangle) {
ShouldNotReachHere();
return false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,19 +28,20 @@
//
// Defines Bsd specific flags. They are not available on other platforms.
//
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
product(bool, UseOprofile, false, \
"enable support for Oprofile profiler") \
\
product(bool, UseBsdPosixThreadCPUClocks, true, \
"enable fast Bsd Posix clocks where available") \
/* NB: The default value of UseBsdPosixThreadCPUClocks may be \
overridden in Arguments::parse_each_vm_init_arg. */ \
\
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \
\
product(bool, UseSHM, false, \
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
product(bool, UseOprofile, false, \
"enable support for Oprofile profiler") \
\
/* NB: The default value of UseBsdPosixThreadCPUClocks may be */ \
/* overridden in Arguments::parse_each_vm_init_arg. */ \
product(bool, UseBsdPosixThreadCPUClocks, true, \
"enable fast Bsd Posix clocks where available") \
\
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \
\
product(bool, UseSHM, false, \
"Use SYSV shared memory for large pages")
//

View File

@ -637,11 +637,6 @@ void os::Bsd::hotspot_sigmask(Thread* thread) {
//////////////////////////////////////////////////////////////////////////////
// create new thread
// check if it's safe to start a new thread
static bool _thread_safety_check(Thread* thread) {
return true;
}
#ifdef __APPLE__
// library handle for calling objc_registerThreadWithCollector()
// without static linking to the libobjc library
@ -681,15 +676,6 @@ static void *java_start(Thread *thread) {
OSThread* osthread = thread->osthread();
Monitor* sync = osthread->startThread_lock();
// non floating stack BsdThreads needs extra check, see above
if (!_thread_safety_check(thread)) {
// notify parent thread
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
osthread->set_state(ZOMBIE);
sync->notify_all();
return NULL;
}
osthread->set_thread_id(os::Bsd::gettid());
#ifdef __APPLE__
@ -1339,7 +1325,8 @@ bool os::address_is_in_vm(address addr) {
#define MACH_MAXSYMLEN 256
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
int buflen, int *offset,
bool demangle) {
// buf is not optional, but offset is optional
assert(buf != NULL, "sanity check");
@ -1349,7 +1336,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
if (dladdr((void*)addr, &dlinfo) != 0) {
// see if we have a matching symbol
if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {
jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
@ -1358,15 +1345,16 @@ bool os::dll_address_to_function_name(address addr, char *buf,
// no matching symbol so try for just file info
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
buf, buflen, offset, dlinfo.dli_fname)) {
buf, buflen, offset, dlinfo.dli_fname, demangle)) {
return true;
}
}
// Handle non-dynamic manually:
if (dlinfo.dli_fbase != NULL &&
Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) {
if (!Decoder::demangle(localbuf, buf, buflen)) {
Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset,
dlinfo.dli_fbase)) {
if (!(demangle && Decoder::demangle(localbuf, buf, buflen))) {
jio_snprintf(buf, buflen, "%s", localbuf);
}
return true;
@ -1706,7 +1694,7 @@ void os::print_os_info(outputStream* st) {
os::Posix::print_load_average(st);
}
void os::pd_print_cpu_info(outputStream* st) {
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
// Nothing to do for now.
}
@ -2276,8 +2264,6 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) {
return os::uncommit_memory(addr, size);
}
static address _highest_vm_reserved_address = NULL;
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
// at 'requested_addr'. If there are existing memory mappings at the same
// location, however, they will be overwritten. If 'fixed' is false,
@ -2300,23 +2286,9 @@ static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
flags, -1, 0);
if (addr != MAP_FAILED) {
// anon_mmap() should only get called during VM initialization,
// don't need lock (actually we can skip locking even it can be called
// from multiple threads, because _highest_vm_reserved_address is just a
// hint about the upper limit of non-stack memory regions.)
if ((address)addr + bytes > _highest_vm_reserved_address) {
_highest_vm_reserved_address = (address)addr + bytes;
}
}
return addr == MAP_FAILED ? NULL : addr;
}
// Don't update _highest_vm_reserved_address, because there might be memory
// regions above addr + size. If so, releasing a memory region only creates
// a hole in the address space, it doesn't help prevent heap-stack collision.
//
static int anon_munmap(char * addr, size_t size) {
return ::munmap(addr, size) == 0;
}
@ -2490,15 +2462,7 @@ char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
// Repeatedly allocate blocks until the block is allocated at the
// right spot. Give up after max_tries. Note that reserve_memory() will
// automatically update _highest_vm_reserved_address if the call is
// successful. The variable tracks the highest memory address every reserved
// by JVM. It is used to detect heap-stack collision if running with
// fixed-stack BsdThreads. Because here we may attempt to reserve more
// space than needed, it could confuse the collision detecting code. To
// solve the problem, save current _highest_vm_reserved_address and
// calculate the correct value before return.
address old_highest = _highest_vm_reserved_address;
// right spot.
// Bsd mmap allows caller to pass an address as hint; give it a try first,
// if kernel honors the hint then we can return immediately.
@ -2552,10 +2516,8 @@ char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
}
if (i < max_tries) {
_highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
return requested_addr;
} else {
_highest_vm_reserved_address = old_highest;
return NULL;
}
}
@ -3715,12 +3677,6 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
return fetcher.result();
}
int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond,
pthread_mutex_t *_mutex,
const struct timespec *_abstime) {
return pthread_cond_timedwait(_cond, _mutex, _abstime);
}
////////////////////////////////////////////////////////////////////////////////
// debug support
@ -4286,7 +4242,7 @@ int os::PlatformEvent::park(jlong millis) {
// In that case, we should propagate the notify to another waiter.
while (_Event < 0) {
status = os::Bsd::safe_cond_timedwait(_cond, _mutex, &abst);
status = pthread_cond_timedwait(_cond, _mutex, &abst);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy(_cond);
pthread_cond_init(_cond, NULL);
@ -4492,7 +4448,7 @@ void Parker::park(bool isAbsolute, jlong time) {
if (time == 0) {
status = pthread_cond_wait(_cond, _mutex);
} else {
status = os::Bsd::safe_cond_timedwait(_cond, _mutex, &absTime);
status = pthread_cond_timedwait(_cond, _mutex, &absTime);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy(_cond);
pthread_cond_init(_cond, NULL);

View File

@ -30,9 +30,6 @@
// Information about the protection of the page at address '0' on this os.
static bool zero_page_read_protected() { return true; }
// pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1
typedef int (*pthread_getattr_func_type)(pthread_t, pthread_attr_t *);
#ifdef __APPLE__
// Mac OS X doesn't support clock_gettime. Stub out the type, it is
// unused
@ -145,9 +142,6 @@ class Bsd {
// none present
// BsdThreads work-around for 6292965
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
private:
typedef int (*sched_getcpu_func_t)(void);
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,14 +28,15 @@
//
// Defines Linux specific flags. They are not available on other platforms.
//
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
product(bool, UseOprofile, false, \
"enable support for Oprofile profiler") \
\
/* NB: The default value of UseLinuxPosixThreadCPUClocks may be */ \
/* overridden in Arguments::parse_each_vm_init_arg. */ \
product(bool, UseLinuxPosixThreadCPUClocks, true, \
"enable fast Linux Posix clocks where available") \
/* NB: The default value of UseLinuxPosixThreadCPUClocks may be \
overridden in Arguments::parse_each_vm_init_arg. */ \
\
product(bool, UseHugeTLBFS, false, \
"Use MAP_HUGETLB for large pages") \

View File

@ -135,8 +135,6 @@ Mutex* os::Linux::_createThread_lock = NULL;
pthread_t os::Linux::_main_thread;
int os::Linux::_page_size = -1;
const int os::Linux::_vm_default_page_size = (8 * K);
bool os::Linux::_is_floating_stack = false;
bool os::Linux::_is_NPTL = false;
bool os::Linux::_supports_fast_thread_cpu_time = false;
const char * os::Linux::_glibc_version = NULL;
const char * os::Linux::_libpthread_version = NULL;
@ -150,8 +148,6 @@ static int clock_tics_per_sec = 100;
static sigset_t check_signal_done;
static bool check_signals = true;
static pid_t _initial_pid = 0;
// Signal number used to suspend/resume a thread
// do not use any signal number less than SIGSEGV, see 4355769
@ -223,18 +219,10 @@ static char cpu_arch[] = HOTSPOT_LIB_ARCH;
//
// Returns the kernel thread id of the currently running thread. Kernel
// thread id is used to access /proc.
//
// (Note that getpid() on LinuxThreads returns kernel thread id too; but
// on NPTL, it returns the same pid for all threads, as required by POSIX.)
//
pid_t os::Linux::gettid() {
int rslt = syscall(SYS_gettid);
if (rslt == -1) {
// old kernel, no NPTL support
return getpid();
} else {
return (pid_t)rslt;
}
assert(rslt != -1, "must be."); // old linuxthreads implementation?
return (pid_t)rslt;
}
// Most versions of linux have a bug where the number of processors are
@ -508,68 +496,48 @@ void os::Linux::hotspot_sigmask(Thread* thread) {
// detecting pthread library
void os::Linux::libpthread_init() {
// Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
// and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
// generic name for earlier versions.
// Define macros here so we can build HotSpot on old systems.
#ifndef _CS_GNU_LIBC_VERSION
#define _CS_GNU_LIBC_VERSION 2
#endif
#ifndef _CS_GNU_LIBPTHREAD_VERSION
#define _CS_GNU_LIBPTHREAD_VERSION 3
// Save glibc and pthread version strings.
#if !defined(_CS_GNU_LIBC_VERSION) || \
!defined(_CS_GNU_LIBPTHREAD_VERSION)
#error "glibc too old (< 2.3.2)"
#endif
size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
if (n > 0) {
char *str = (char *)malloc(n, mtInternal);
confstr(_CS_GNU_LIBC_VERSION, str, n);
os::Linux::set_glibc_version(str);
} else {
// _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
static char _gnu_libc_version[32];
jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
"glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
os::Linux::set_glibc_version(_gnu_libc_version);
}
assert(n > 0, "cannot retrieve glibc version");
char *str = (char *)malloc(n, mtInternal);
confstr(_CS_GNU_LIBC_VERSION, str, n);
os::Linux::set_glibc_version(str);
n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
if (n > 0) {
char *str = (char *)malloc(n, mtInternal);
confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
// Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
// us "NPTL-0.29" even we are running with LinuxThreads. Check if this
// is the case. LinuxThreads has a hard limit on max number of threads.
// So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
// On the other hand, NPTL does not have such a limit, sysconf()
// will return -1 and errno is not changed. Check if it is really NPTL.
if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
strstr(str, "NPTL") &&
sysconf(_SC_THREAD_THREADS_MAX) > 0) {
free(str);
os::Linux::set_libpthread_version("linuxthreads");
} else {
os::Linux::set_libpthread_version(str);
}
} else {
// glibc before 2.3.2 only has LinuxThreads.
os::Linux::set_libpthread_version("linuxthreads");
}
if (strstr(libpthread_version(), "NPTL")) {
os::Linux::set_is_NPTL();
} else {
os::Linux::set_is_LinuxThreads();
}
// LinuxThreads have two flavors: floating-stack mode, which allows variable
// stack size; and fixed-stack mode. NPTL is always floating-stack.
if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
os::Linux::set_is_floating_stack();
}
assert(n > 0, "cannot retrieve pthread version");
str = (char *)malloc(n, mtInternal);
confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
os::Linux::set_libpthread_version(str);
}
/////////////////////////////////////////////////////////////////////////////
// thread stack
// thread stack expansion
// os::Linux::manually_expand_stack() takes care of expanding the thread
// stack. Note that this is normally not needed: pthread stacks allocate
// thread stack using mmap() without MAP_NORESERVE, so the stack is already
// committed. Therefore it is not necessary to expand the stack manually.
//
// Manually expanding the stack was historically needed on LinuxThreads
// thread stacks, which were allocated with mmap(MAP_GROWSDOWN). Nowadays
// it is kept to deal with very rare corner cases:
//
// For one, user may run the VM on an own implementation of threads
// whose stacks are - like the old LinuxThreads - implemented using
// mmap(MAP_GROWSDOWN).
//
// Also, this coding may be needed if the VM is running on the primordial
// thread. Normally we avoid running on the primordial thread; however,
// user may still invoke the VM on the primordial thread.
//
// The following historical comment describes the details about running
// on a thread stack allocated with mmap(MAP_GROWSDOWN):
// Force Linux kernel to expand current thread stack. If "bottom" is close
// to the stack guard, caller should block all signals.
@ -593,10 +561,7 @@ void os::Linux::libpthread_init() {
// stack overflow detection.
//
// Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
// not use this flag. However, the stack of initial thread is not created
// by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
// unlikely) that user code can create a thread with MAP_GROWSDOWN stack
// and then attach the thread to JVM.
// not use MAP_GROWSDOWN.
//
// To get around the problem and allow stack banging on Linux, we need to
// manually expand thread stack after receiving the SIGSEGV.
@ -671,45 +636,6 @@ bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
//////////////////////////////////////////////////////////////////////////////
// create new thread
static address highest_vm_reserved_address();
// check if it's safe to start a new thread
static bool _thread_safety_check(Thread* thread) {
if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
// Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
// Heap is mmap'ed at lower end of memory space. Thread stacks are
// allocated (MAP_FIXED) from high address space. Every thread stack
// occupies a fixed size slot (usually 2Mbytes, but user can change
// it to other values if they rebuild LinuxThreads).
//
// Problem with MAP_FIXED is that mmap() can still succeed even part of
// the memory region has already been mmap'ed. That means if we have too
// many threads and/or very large heap, eventually thread stack will
// collide with heap.
//
// Here we try to prevent heap/stack collision by comparing current
// stack bottom with the highest address that has been mmap'ed by JVM
// plus a safety margin for memory maps created by native code.
//
// This feature can be disabled by setting ThreadSafetyMargin to 0
//
if (ThreadSafetyMargin > 0) {
address stack_bottom = os::current_stack_base() - os::current_stack_size();
// not safe if our stack extends below the safety margin
return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
} else {
return true;
}
} else {
// Floating stack LinuxThreads or NPTL:
// Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
// there's not enough space left, pthread_create() will fail. If we come
// here, that means enough space has been reserved for stack.
return true;
}
}
// Thread start routine for all newly created threads
static void *java_start(Thread *thread) {
// Try to randomize the cache line index of hot stack frames.
@ -726,15 +652,6 @@ static void *java_start(Thread *thread) {
OSThread* osthread = thread->osthread();
Monitor* sync = osthread->startThread_lock();
// non floating stack LinuxThreads needs extra check, see above
if (!_thread_safety_check(thread)) {
// notify parent thread
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
osthread->set_state(ZOMBIE);
sync->notify_all();
return NULL;
}
// thread_id is kernel thread id (similar to Solaris LWP id)
osthread->set_thread_id(os::Linux::gettid());
@ -833,12 +750,6 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
ThreadState state;
{
// Serialize thread creation if we are running with fixed stack LinuxThreads
bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
if (lock) {
os::Linux::createThread_lock()->lock_without_safepoint_check();
}
pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
@ -851,7 +762,6 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
// Need to clean up stuff we've allocated so far
thread->set_osthread(NULL);
delete osthread;
if (lock) os::Linux::createThread_lock()->unlock();
return false;
}
@ -866,10 +776,6 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
sync_with_child->wait(Mutex::_no_safepoint_check_flag);
}
}
if (lock) {
os::Linux::createThread_lock()->unlock();
}
}
// Aborted due to thread limit being reached
@ -1497,7 +1403,6 @@ void os::abort(bool dump_core, void* siginfo, void* context) {
// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
// _exit() on LinuxThreads only kills current thread
::abort();
}
@ -1520,24 +1425,7 @@ size_t os::lasterror(char *buf, size_t len) {
intx os::current_thread_id() { return (intx)pthread_self(); }
int os::current_process_id() {
// Under the old linux thread library, linux gives each thread
// its own process id. Because of this each thread will return
// a different pid if this method were to return the result
// of getpid(2). Linux provides no api that returns the pid
// of the launcher thread for the vm. This implementation
// returns a unique pid, the pid of the launcher thread
// that starts the vm 'process'.
// Under the NPTL, getpid() returns the same pid as the
// launcher thread rather than a unique pid per thread.
// Use gettid() if you want the old pre NPTL behaviour.
// if you are looking for the result of a call to getpid() that
// returns a unique pid for the calling thread, then look at the
// OSThread::thread_id() method in osThread_linux.hpp file
return (int)(_initial_pid ? _initial_pid : getpid());
return ::getpid();
}
// DLL functions
@ -1623,7 +1511,8 @@ bool os::address_is_in_vm(address addr) {
}
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
int buflen, int *offset,
bool demangle) {
// buf is not optional, but offset is optional
assert(buf != NULL, "sanity check");
@ -1632,7 +1521,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
if (dladdr((void*)addr, &dlinfo) != 0) {
// see if we have a matching symbol
if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {
jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
@ -1641,7 +1530,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
// no matching symbol so try for just file info
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
buf, buflen, offset, dlinfo.dli_fname)) {
buf, buflen, offset, dlinfo.dli_fname, demangle)) {
return true;
}
}
@ -2183,9 +2072,6 @@ void os::Linux::print_libversion_info(outputStream* st) {
st->print("libc:");
st->print("%s ", os::Linux::glibc_version());
st->print("%s ", os::Linux::libpthread_version());
if (os::Linux::is_LinuxThreads()) {
st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
}
st->cr();
}
@ -2215,12 +2101,52 @@ void os::print_memory_info(outputStream* st) {
st->cr();
}
void os::pd_print_cpu_info(outputStream* st) {
st->print("\n/proc/cpuinfo:\n");
if (!_print_ascii_file("/proc/cpuinfo", st)) {
st->print(" <Not Available>");
// Print the first "model name" line and the first "flags" line
// that we find and nothing more. We assume "model name" comes
// before "flags" so if we find a second "model name", then the
// "flags" field is considered missing.
static bool print_model_name_and_flags(outputStream* st, char* buf, size_t buflen) {
#if defined(IA32) || defined(AMD64)
// Other platforms have less repetitive cpuinfo files
FILE *fp = fopen("/proc/cpuinfo", "r");
if (fp) {
while (!feof(fp)) {
if (fgets(buf, buflen, fp)) {
// Assume model name comes before flags
bool model_name_printed = false;
if (strstr(buf, "model name") != NULL) {
if (!model_name_printed) {
st->print_raw("\nCPU Model and flags from /proc/cpuinfo:\n");
st->print_raw(buf);
model_name_printed = true;
} else {
// model name printed but not flags? Odd, just return
fclose(fp);
return true;
}
}
// print the flags line too
if (strstr(buf, "flags") != NULL) {
st->print_raw(buf);
fclose(fp);
return true;
}
}
}
fclose(fp);
}
#endif // x86 platforms
return false;
}
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
// Only print the model name if the platform provides this as a summary
if (!print_model_name_and_flags(st, buf, buflen)) {
st->print("\n/proc/cpuinfo:\n");
if (!_print_ascii_file("/proc/cpuinfo", st)) {
st->print_cr(" <Not Available>");
}
}
st->cr();
}
void os::print_siginfo(outputStream* st, void* siginfo) {
@ -3044,8 +2970,6 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) {
return os::uncommit_memory(addr, size);
}
static address _highest_vm_reserved_address = NULL;
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
// at 'requested_addr'. If there are existing memory mappings at the same
// location, however, they will be overwritten. If 'fixed' is false,
@ -3068,23 +2992,9 @@ static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
flags, -1, 0);
if (addr != MAP_FAILED) {
// anon_mmap() should only get called during VM initialization,
// don't need lock (actually we can skip locking even it can be called
// from multiple threads, because _highest_vm_reserved_address is just a
// hint about the upper limit of non-stack memory regions.)
if ((address)addr + bytes > _highest_vm_reserved_address) {
_highest_vm_reserved_address = (address)addr + bytes;
}
}
return addr == MAP_FAILED ? NULL : addr;
}
// Don't update _highest_vm_reserved_address, because there might be memory
// regions above addr + size. If so, releasing a memory region only creates
// a hole in the address space, it doesn't help prevent heap-stack collision.
//
static int anon_munmap(char * addr, size_t size) {
return ::munmap(addr, size) == 0;
}
@ -3098,10 +3008,6 @@ bool os::pd_release_memory(char* addr, size_t size) {
return anon_munmap(addr, size);
}
static address highest_vm_reserved_address() {
return _highest_vm_reserved_address;
}
static bool linux_mprotect(char* addr, size_t size, int prot) {
// Linux wants the mprotect address argument to be page aligned.
char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
@ -3718,15 +3624,7 @@ char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
// Repeatedly allocate blocks until the block is allocated at the
// right spot. Give up after max_tries. Note that reserve_memory() will
// automatically update _highest_vm_reserved_address if the call is
// successful. The variable tracks the highest memory address every reserved
// by JVM. It is used to detect heap-stack collision if running with
// fixed-stack LinuxThreads. Because here we may attempt to reserve more
// space than needed, it could confuse the collision detecting code. To
// solve the problem, save current _highest_vm_reserved_address and
// calculate the correct value before return.
address old_highest = _highest_vm_reserved_address;
// right spot.
// Linux mmap allows caller to pass an address as hint; give it a try first,
// if kernel honors the hint then we can return immediately.
@ -3780,10 +3678,8 @@ char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
}
if (i < max_tries) {
_highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
return requested_addr;
} else {
_highest_vm_reserved_address = old_highest;
return NULL;
}
}
@ -4627,16 +4523,6 @@ void os::init(void) {
char dummy; // used to get a guess on initial stack address
// first_hrtime = gethrtime();
// With LinuxThreads the JavaMain thread pid (primordial thread)
// is different than the pid of the java launcher thread.
// So, on Linux, the launcher thread pid is passed to the VM
// via the sun.java.launcher.pid property.
// Use this property instead of getpid() if it was correctly passed.
// See bug 6351349.
pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
_initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
clock_tics_per_sec = sysconf(_SC_CLK_TCK);
init_random(1234567);
@ -4769,9 +4655,8 @@ jint os::init_2(void) {
Linux::libpthread_init();
if (PrintMiscellaneous && (Verbose || WizardMode)) {
tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
Linux::glibc_version(), Linux::libpthread_version(),
Linux::is_floating_stack() ? "floating stack" : "fixed stack");
tty->print_cr("[HotSpot is running with %s, %s]\n",
Linux::glibc_version(), Linux::libpthread_version());
}
if (UseNUMA) {
@ -4946,22 +4831,6 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
return fetcher.result();
}
int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond,
pthread_mutex_t *_mutex,
const struct timespec *_abstime) {
if (is_NPTL()) {
return pthread_cond_timedwait(_cond, _mutex, _abstime);
} else {
// 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
// word back to default 64bit precision if condvar is signaled. Java
// wants 53bit precision. Save and restore current value.
int fpu = get_fpu_control_word();
int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
set_fpu_control_word(fpu);
return status;
}
}
////////////////////////////////////////////////////////////////////////////////
// debug support
@ -5585,7 +5454,7 @@ int os::PlatformEvent::park(jlong millis) {
// In that case, we should propagate the notify to another waiter.
while (_Event < 0) {
status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
status = pthread_cond_timedwait(_cond, _mutex, &abst);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy(_cond);
pthread_cond_init(_cond, os::Linux::condAttr());
@ -5813,7 +5682,7 @@ void Parker::park(bool isAbsolute, jlong time) {
status = pthread_cond_wait(&_cond[_cur_index], _mutex);
} else {
_cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
status = os::Linux::safe_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);
status = pthread_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);
if (status != 0 && WorkAroundNPTLTimedWaitHang) {
pthread_cond_destroy(&_cond[_cur_index]);
pthread_cond_init(&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,9 +27,6 @@
// Linux_OS defines the interface to Linux operating systems
// pthread_getattr_np comes with LinuxThreads-0.9-7 on RedHat 7.1
typedef int (*pthread_getattr_func_type)(pthread_t, pthread_attr_t *);
// Information about the protection of the page at address '0' on this os.
static bool zero_page_read_protected() { return true; }
@ -63,8 +60,6 @@ class Linux {
static const char *_glibc_version;
static const char *_libpthread_version;
static bool _is_floating_stack;
static bool _is_NPTL;
static bool _supports_fast_thread_cpu_time;
static GrowableArray<int>* _cpu_to_node;
@ -90,10 +85,6 @@ class Linux {
static bool supports_variable_stack_size();
static void set_is_NPTL() { _is_NPTL = true; }
static void set_is_LinuxThreads() { _is_NPTL = false; }
static void set_is_floating_stack() { _is_floating_stack = true; }
static void rebuild_cpu_to_node_map();
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
@ -178,14 +169,6 @@ class Linux {
static const char *glibc_version() { return _glibc_version; }
static const char *libpthread_version() { return _libpthread_version; }
// NPTL or LinuxThreads?
static bool is_LinuxThreads() { return !_is_NPTL; }
static bool is_NPTL() { return _is_NPTL; }
// NPTL is always floating stack. LinuxThreads could be using floating
// stack or fixed stack.
static bool is_floating_stack() { return _is_floating_stack; }
static void libpthread_init();
static bool libnuma_init();
static void* libnuma_dlsym(void* handle, const char* name);
@ -234,9 +217,6 @@ class Linux {
// none present
// LinuxThreads work-around for 6292965
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
private:
typedef int (*sched_getcpu_func_t)(void);
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,7 @@
//
// Defines Solaris specific flags. They are not available on other platforms.
//
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
product(bool, UseExtendedFileIO, true, \
"Enable workaround for limitations of stdio FILE structure")

View File

@ -1627,7 +1627,8 @@ typedef int (*dladdr1_func_type)(void *, Dl_info *, void **, int);
static dladdr1_func_type dladdr1_func = NULL;
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int * offset) {
int buflen, int * offset,
bool demangle) {
// buf is not optional, but offset is optional
assert(buf != NULL, "sanity check");
@ -1655,7 +1656,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
if (dlinfo.dli_saddr != NULL &&
(char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
if (dlinfo.dli_sname != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {
jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
@ -1665,7 +1666,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
// no matching symbol so try for just file info
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
buf, buflen, offset, dlinfo.dli_fname)) {
buf, buflen, offset, dlinfo.dli_fname, demangle)) {
return true;
}
}
@ -1679,7 +1680,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
if (dladdr((void *)addr, &dlinfo) != 0) {
// see if we have a matching symbol
if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {
jio_snprintf(buf, buflen, dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
@ -1688,7 +1689,7 @@ bool os::dll_address_to_function_name(address addr, char *buf,
// no matching symbol so try for just file info
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
buf, buflen, offset, dlinfo.dli_fname)) {
buf, buflen, offset, dlinfo.dli_fname, demangle)) {
return true;
}
}
@ -1996,7 +1997,7 @@ static bool check_addr0(outputStream* st) {
return status;
}
void os::pd_print_cpu_info(outputStream* st) {
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
// Nothing to do for now.
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -162,7 +162,7 @@ void WindowsDecoder::initialize() {
// current function and comparing the result
address addr = (address)Decoder::demangle;
char buf[MAX_PATH];
if (decode(addr, buf, sizeof(buf), NULL)) {
if (decode(addr, buf, sizeof(buf), NULL, NULL, true /* demangle */)) {
_can_decode_in_vm = !strcmp(buf, "Decoder::demangle");
}
}
@ -187,7 +187,7 @@ bool WindowsDecoder::can_decode_C_frame_in_vm() const {
}
bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath) {
bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath, bool demangle_name) {
if (_pfnSymGetSymFromAddr64 != NULL) {
PIMAGEHLP_SYMBOL64 pSymbol;
char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
@ -197,7 +197,7 @@ bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, co
DWORD64 displacement;
if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
if (buf != NULL) {
if (demangle(pSymbol->Name, buf, buflen)) {
if (!(demangle_name && demangle(pSymbol->Name, buf, buflen))) {
jio_snprintf(buf, buflen, "%s", pSymbol->Name);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,7 @@ public:
bool can_decode_C_frame_in_vm() const;
bool demangle(const char* symbol, char *buf, int buflen);
bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath, bool demangle);
bool decode(address addr, char *buf, int buflen, int* offset, const void* base) {
ShouldNotReachHere();
return false;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,7 @@
//
// Defines Windows specific flags. They are not available on other platforms.
//
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, \
diagnostic, notproduct) \
#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
product(bool, UseUTCFileTimestamp, true, \
"Adjust the timestamp returned from stat() to be UTC")

View File

@ -1369,11 +1369,12 @@ bool os::dll_address_to_library_name(address addr, char* buf,
}
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
int buflen, int *offset,
bool demangle) {
// buf is not optional, but offset is optional
assert(buf != NULL, "sanity check");
if (Decoder::decode(addr, buf, buflen, offset)) {
if (Decoder::decode(addr, buf, buflen, offset, demangle)) {
return true;
}
if (offset != NULL) *offset = -1;
@ -1732,7 +1733,7 @@ void os::win32::print_windows_version(outputStream* st) {
st->cr();
}
void os::pd_print_cpu_info(outputStream* st) {
void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
// Nothing to do for now.
}

View File

@ -10,7 +10,7 @@
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file hat
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -619,54 +619,15 @@ bool os::is_allocatable(size_t bytes) {
#ifdef AMD64
size_t os::Linux::min_stack_allowed = 64 * K;
// amd64: pthread on amd64 is always in floating stack mode
bool os::Linux::supports_variable_stack_size() { return true; }
#else
size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
#ifdef __GNUC__
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
#endif
// Test if pthread library can support variable thread stack size. LinuxThreads
// in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
// in floating stack mode and NPTL support variable stack size.
bool os::Linux::supports_variable_stack_size() {
if (os::Linux::is_NPTL()) {
// NPTL, yes
return true;
} else {
// Note: We can't control default stack size when creating a thread.
// If we use non-default stack size (pthread_attr_setstacksize), both
// floating stack and non-floating stack LinuxThreads will return the
// same value. This makes it impossible to implement this function by
// detecting thread stack size directly.
//
// An alternative approach is to check %gs. Fixed-stack LinuxThreads
// do not use %gs, so its value is 0. Floating-stack LinuxThreads use
// %gs (either as LDT selector or GDT selector, depending on kernel)
// to access thread specific data.
//
// Note that %gs is a reserved glibc register since early 2001, so
// applications are not allowed to change its value (Ulrich Drepper from
// Redhat confirmed that all known offenders have been modified to use
// either %fs or TSD). In the worst case scenario, when VM is embedded in
// a native application that plays with %gs, we might see non-zero %gs
// even LinuxThreads is running in fixed stack mode. As the result, we'll
// return true and skip _thread_safety_check(), so we may not be able to
// detect stack-heap collisions. But otherwise it's harmless.
//
#ifdef __GNUC__
return (GET_GS() != 0);
#else
return false;
#endif
}
}
#endif // AMD64
// Test if pthread library can support variable thread stack size.
bool os::Linux::supports_variable_stack_size() {
return true;
}
// return default stack size for thr_type
size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
// default stack size (compiler thread needs larger stack)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,8 +40,7 @@
// actual memory pages are committed on demand.
//
// If an application creates and destroys a lot of threads, usually the
// stack space freed by a thread will soon get reused by new thread
// (this is especially true in NPTL or LinuxThreads in fixed-stack mode).
// stack space freed by a thread will soon get reused by new thread.
// No memory page in _sp_map is wasted.
//
// However, it's still possible that we might end up populating &

View File

@ -363,9 +363,6 @@ class CompilerInterfaceVC10 extends CompilerInterface {
// Set /On option
addAttr(rv, "Optimization", opt);
// Set /FR option.
addAttr(rv, "BrowseInformation", "true");
addAttr(rv, "BrowseInformationFile", "$(IntDir)");
// Set /MD option.
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
// Set /Oy- option

View File

@ -1619,6 +1619,9 @@ void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc*
LIR_Opr dirty = LIR_OprFact::intConst(CardTableModRefBS::dirty_card_val());
if (UseCondCardMark) {
LIR_Opr cur_value = new_register(T_INT);
if (UseConcMarkSweepGC) {
__ membar_storeload();
}
__ move(card_addr, cur_value);
LabelObj* L_already_dirty = new LabelObj();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,4 +25,4 @@
#include "precompiled.hpp"
#include "c1/c1_globals.hpp"
C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG, IGNORE_RANGE, IGNORE_CONSTRAINT)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -60,7 +60,7 @@
//
// Defines all global flags used by the client compiler.
//
#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
\
/* Printing */ \
notproduct(bool, PrintC1Statistics, false, \
@ -148,6 +148,7 @@
\
product(intx, ValueMapInitialSize, 11, \
"Initial size of a value map") \
range(1, NOT_LP64(1*K) LP64_ONLY(32*K)) \
\
product(intx, ValueMapMaxLoopSize, 8, \
"maximum size of a loop optimized by global value numbering") \
@ -191,6 +192,7 @@
\
develop(intx, NestedInliningSizeRatio, 90, \
"Percentage of prev. allowed inline size in recursive inlining") \
range(0, 100) \
\
notproduct(bool, PrintIRWithLIR, false, \
"Print IR instructions with generated LIR") \
@ -338,10 +340,15 @@
diagnostic(bool, C1PatchInvokeDynamic, true, \
"Patch invokedynamic appendix not known at compile time") \
\
// Read default values for c1 globals
C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
C1_FLAGS(DECLARE_DEVELOPER_FLAG, \
DECLARE_PD_DEVELOPER_FLAG, \
DECLARE_PRODUCT_FLAG, \
DECLARE_PD_PRODUCT_FLAG, \
DECLARE_DIAGNOSTIC_FLAG, \
DECLARE_NOTPRODUCT_FLAG, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
#endif // SHARE_VM_C1_C1_GLOBALS_HPP

Some files were not shown because too many files have changed in this diff Show More