This commit is contained in:
J. Duke 2017-07-05 21:26:50 +02:00
commit f1f6a48424
436 changed files with 13904 additions and 6318 deletions

View File

@ -351,3 +351,4 @@ be58b02c11f90b88c67e4d0e2cb5e4cf2d9b3c57 jdk-9+105
54575d8783b3a39a2d710c28cda675d44261f9d9 jdk-9+106 54575d8783b3a39a2d710c28cda675d44261f9d9 jdk-9+106
4d65eba233a8730f913734a6804910b842d2cb54 jdk-9+107 4d65eba233a8730f913734a6804910b842d2cb54 jdk-9+107
c7be2a78c31b3b6132f2f5e9e4b3d3bb1c20245c jdk-9+108 c7be2a78c31b3b6132f2f5e9e4b3d3bb1c20245c jdk-9+108
1787bdaabb2b6f4193406e25a50cb0419ea8e8f3 jdk-9+109

View File

@ -4005,7 +4005,7 @@ apt_help() {
devkit) devkit)
PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;; PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;;
openjdk) openjdk)
PKGHANDLER_COMMAND="sudo apt-get install openjdk-7-jdk" ;; PKGHANDLER_COMMAND="sudo apt-get install openjdk-8-jdk" ;;
alsa) alsa)
PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;; PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
cups) cups)
@ -4026,7 +4026,7 @@ yum_help() {
devkit) devkit)
PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;; PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;;
openjdk) openjdk)
PKGHANDLER_COMMAND="sudo yum install java-1.7.0-openjdk" ;; PKGHANDLER_COMMAND="sudo yum install java-1.8.0-openjdk-devel" ;;
alsa) alsa)
PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;; PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
cups) cups)
@ -4862,7 +4862,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1456136781 DATE_WHEN_GENERATED=1457684806
############################################################################### ###############################################################################
# #
@ -15118,6 +15118,10 @@ $as_echo "$COMPILE_TYPE" >&6; }
REQUIRED_OS_NAME=Darwin REQUIRED_OS_NAME=Darwin
REQUIRED_OS_VERSION=11.2 REQUIRED_OS_VERSION=11.2
fi fi
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
REQUIRED_OS_NAME=AIX
REQUIRED_OS_VERSION=7.1
fi

View File

@ -106,7 +106,7 @@ apt_help() {
devkit) devkit)
PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;; PKGHANDLER_COMMAND="sudo apt-get install build-essential" ;;
openjdk) openjdk)
PKGHANDLER_COMMAND="sudo apt-get install openjdk-7-jdk" ;; PKGHANDLER_COMMAND="sudo apt-get install openjdk-8-jdk" ;;
alsa) alsa)
PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;; PKGHANDLER_COMMAND="sudo apt-get install libasound2-dev" ;;
cups) cups)
@ -127,7 +127,7 @@ yum_help() {
devkit) devkit)
PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;; PKGHANDLER_COMMAND="sudo yum groupinstall \"Development Tools\"" ;;
openjdk) openjdk)
PKGHANDLER_COMMAND="sudo yum install java-1.7.0-openjdk" ;; PKGHANDLER_COMMAND="sudo yum install java-1.8.0-openjdk-devel" ;;
alsa) alsa)
PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;; PKGHANDLER_COMMAND="sudo yum install alsa-lib-devel" ;;
cups) cups)

View File

@ -406,6 +406,10 @@ AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES],
REQUIRED_OS_NAME=Darwin REQUIRED_OS_NAME=Darwin
REQUIRED_OS_VERSION=11.2 REQUIRED_OS_VERSION=11.2
fi fi
if test "x$OPENJDK_TARGET_OS" = "xaix"; then
REQUIRED_OS_NAME=AIX
REQUIRED_OS_VERSION=7.1
fi
AC_SUBST(REQUIRED_OS_NAME) AC_SUBST(REQUIRED_OS_NAME)
AC_SUBST(REQUIRED_OS_VERSION) AC_SUBST(REQUIRED_OS_VERSION)

View File

@ -185,7 +185,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "x86_64" ];
./lib/amd64/libjava.so ./lib/amd64/libjava.so
./lib/amd64/libjawt.so ./lib/amd64/libjawt.so
./lib/amd64/libjdwp.so ./lib/amd64/libjdwp.so
./lib/amd64/libjfr.so
./lib/amd64/libjpeg.so ./lib/amd64/libjpeg.so
./lib/amd64/libjsdt.so ./lib/amd64/libjsdt.so
./lib/amd64/libjsound.so ./lib/amd64/libjsound.so
@ -321,7 +320,6 @@ if [ "$OPENJDK_TARGET_OS" = "solaris" ] && [ "$OPENJDK_TARGET_CPU" = "sparcv9" ]
./lib/sparcv9/libjava.so ./lib/sparcv9/libjava.so
./lib/sparcv9/libjawt.so ./lib/sparcv9/libjawt.so
./lib/sparcv9/libjdwp.so ./lib/sparcv9/libjdwp.so
./lib/sparcv9/libjfr.so
./lib/sparcv9/libjpeg.so ./lib/sparcv9/libjpeg.so
./lib/sparcv9/libjsdt.so ./lib/sparcv9/libjsdt.so
./lib/sparcv9/libjsound.so ./lib/sparcv9/libjsound.so

View File

@ -1293,12 +1293,8 @@ jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/win
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c
jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h jdk/src/jdk.crypto.pkcs11/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent/package.html : jdk/src/macosx/classes/com/apple/concurrent/package.html jdk/src/java.desktop/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m
jdk/src/jdk.deploy.osx/macosx/classes/com/apple/concurrent : jdk/src/macosx/classes/com/apple/concurrent jdk/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m : jdk/src/macosx/native/apple/security/KeystoreImpl.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m : jdk/src/macosx/native/com/apple/concurrent/Dispatch.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/JavaAppLauncher.m : jdk/src/macosx/native/apple/launcher/JavaAppLauncher.m
jdk/src/jdk.deploy.osx/macosx/native/libosx/KeystoreImpl.m : jdk/src/macosx/native/apple/security/KeystoreImpl.m
jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof : jdk/src/share/classes/com/sun/demo/jvmti/hprof jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof : jdk/src/share/classes/com/sun/demo/jvmti/hprof
jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver : jdk/src/share/classes/com/sun/net/httpserver jdk/src/jdk.httpserver/share/classes/com/sun/net/httpserver : jdk/src/share/classes/com/sun/net/httpserver
jdk/src/jdk.httpserver/share/classes/sun/net/httpserver : jdk/src/share/classes/sun/net/httpserver jdk/src/jdk.httpserver/share/classes/sun/net/httpserver : jdk/src/share/classes/sun/net/httpserver

View File

@ -511,3 +511,4 @@ c5f55130b1b69510d9a6f4a3105b58e21cd7ffe1 jdk-9+103
7232de4c17c37f60aecec4f3191090bd3d41d334 jdk-9+106 7232de4c17c37f60aecec4f3191090bd3d41d334 jdk-9+106
c5146d4da417f76edfc43097d2e2ced042a65b4e jdk-9+107 c5146d4da417f76edfc43097d2e2ced042a65b4e jdk-9+107
934f6793f5f7dca44f69b4559d525fa64b31840d jdk-9+108 934f6793f5f7dca44f69b4559d525fa64b31840d jdk-9+108
7e7e50ac4faf19899fc811569e32cfa478759ebb jdk-9+109

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \ TraceGeneratedNames += \
traceRequestables.hpp \ traceRequestables.hpp \
traceEventControl.hpp traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%) TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -100,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \ TraceGeneratedNames += \
traceRequestables.hpp \ traceRequestables.hpp \
traceEventControl.hpp traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif endif
@ -101,9 +96,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -57,11 +57,6 @@ ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \ TraceGeneratedNames += \
traceRequestables.hpp \ traceRequestables.hpp \
traceEventControl.hpp traceEventControl.hpp
ifneq ($(INCLUDE_TRACE), false)
TraceGeneratedNames += traceProducer.cpp
endif
endif endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%) TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -100,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)

View File

@ -39,7 +39,7 @@ OPT_CFLAGS/c1_LinearScan.o = -xO2
# of OPT_CFLAGS. Restore it here. # of OPT_CFLAGS. Restore it here.
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
OPT_CFLAGS/generateOptoStub.o += -g0 -xs OPT_CFLAGS/generateOptoStub.o += -g0 -xs
OPT_CFLAGS/LinearScan.o += -g0 -xs OPT_CFLAGS/c1_LinearScan.o += -g0 -xs
endif endif
else else

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -56,8 +56,7 @@ TraceGeneratedNames = \
ifeq ($(HAS_ALT_SRC), true) ifeq ($(HAS_ALT_SRC), true)
TraceGeneratedNames += \ TraceGeneratedNames += \
traceRequestables.hpp \ traceRequestables.hpp \
traceEventControl.hpp \ traceEventControl.hpp
traceProducer.cpp
endif endif
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%) TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
@ -96,9 +95,6 @@ else
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
$(GENERATE_CODE)
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
$(GENERATE_CODE) $(GENERATE_CODE)

View File

@ -48,6 +48,7 @@ BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
$(HOTSPOT_TOPDIR)/test/runtime/SameObject \ $(HOTSPOT_TOPDIR)/test/runtime/SameObject \
$(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \ $(HOTSPOT_TOPDIR)/test/compiler/floatingpoint/ \
$(HOTSPOT_TOPDIR)/test/compiler/calls \ $(HOTSPOT_TOPDIR)/test/compiler/calls \
$(HOTSPOT_TOPDIR)/test/compiler/native \
# #
# Add conditional directories here when needed. # Add conditional directories here when needed.

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -43,8 +43,7 @@ TraceGeneratedNames = \
!if EXISTS($(TraceAltSrcDir)) !if EXISTS($(TraceAltSrcDir))
TraceGeneratedNames = $(TraceGeneratedNames) \ TraceGeneratedNames = $(TraceGeneratedNames) \
traceRequestables.hpp \ traceRequestables.hpp \
traceEventControl.hpp \ traceEventControl.hpp
traceProducer.cpp
!endif !endif
@ -58,8 +57,7 @@ TraceGeneratedFiles = \
!if EXISTS($(TraceAltSrcDir)) !if EXISTS($(TraceAltSrcDir))
TraceGeneratedFiles = $(TraceGeneratedFiles) \ TraceGeneratedFiles = $(TraceGeneratedFiles) \
$(TraceOutDir)/traceRequestables.hpp \ $(TraceOutDir)/traceRequestables.hpp \
$(TraceOutDir)/traceEventControl.hpp \ $(TraceOutDir)/traceEventControl.hpp
$(TraceOutDir)/traceProducer.cpp
!endif !endif
XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
@ -98,10 +96,6 @@ $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)
@echo Generating AltSrc $@ @echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
@echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
@echo Generating AltSrc $@ @echo Generating AltSrc $@
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp

File diff suppressed because it is too large Load Diff

View File

@ -74,7 +74,7 @@ void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, T
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) { void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
address pc = _instructions->start() + pc_offset; address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc); NativeInstruction* inst = nativeInstruction_at(pc);
if (inst->is_adr_aligned()) { if (inst->is_adr_aligned() || inst->is_ldr_literal()) {
address dest = _constants->start() + data_offset; address dest = _constants->start() + data_offset;
_instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS)); _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS));
TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset); TRACE_jvmci_3("relocating at " PTR_FORMAT " (+%d) with destination at %d", p2i(pc), pc_offset, data_offset);

View File

@ -4481,225 +4481,126 @@ void MacroAssembler::string_compare(Register str1, Register str2,
BLOCK_COMMENT("} string_compare"); BLOCK_COMMENT("} string_compare");
} }
// Compare Strings or char/byte arrays.
void MacroAssembler::string_equals(Register str1, Register str2, // is_string is true iff this is a string comparison.
Register cnt, Register result,
Register tmp1) {
Label SAME_CHARS, DONE, SHORT_LOOP, SHORT_STRING,
NEXT_WORD;
const Register tmp2 = rscratch1; // For Strings we're passed the address of the first characters in a1
assert_different_registers(str1, str2, cnt, result, tmp1, tmp2, rscratch2); // and a2 and the length in cnt1.
BLOCK_COMMENT("string_equals {"); // For byte and char arrays we're passed the arrays themselves and we
// have to extract length fields and do null checks here.
// Start by assuming that the strings are not equal. // elem_size is the element size in bytes: either 1 or 2.
mov(result, zr);
// A very short string // There are two implementations. For arrays >= 8 bytes, all
cmpw(cnt, 4); // comparisons (including the final one, which may overlap) are
br(Assembler::LT, SHORT_STRING); // performed 8 bytes at a time. For arrays < 8 bytes, we compare a
// halfword, then a short, and then a byte.
// Check if the strings start at the same location. void MacroAssembler::arrays_equals(Register a1, Register a2,
cmp(str1, str2); Register result, Register cnt1,
br(Assembler::EQ, SAME_CHARS); int elem_size, bool is_string)
{
Label SAME, DONE, SHORT, NEXT_WORD, ONE;
Register tmp1 = rscratch1;
Register tmp2 = rscratch2;
Register cnt2 = tmp2; // cnt2 only used in array length compare
int elem_per_word = wordSize/elem_size;
int log_elem_size = exact_log2(elem_size);
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset
= arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
// Compare longwords assert(elem_size == 1 || elem_size == 2, "must be char or byte");
{ assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
subw(cnt, cnt, 4); // The last longword is a special case
// Move both string pointers to the last longword of their BLOCK_COMMENT(is_string ? "string_equals {" : "array_equals {");
// strings, negate the remaining count, and convert it to bytes.
lea(str1, Address(str1, cnt, Address::uxtw(1)));
lea(str2, Address(str2, cnt, Address::uxtw(1)));
sub(cnt, zr, cnt, LSL, 1);
// Loop, loading longwords and comparing them into rscratch2. mov(result, false);
bind(NEXT_WORD);
ldr(tmp1, Address(str1, cnt));
ldr(tmp2, Address(str2, cnt));
adds(cnt, cnt, wordSize);
eor(rscratch2, tmp1, tmp2);
cbnz(rscratch2, DONE);
br(Assembler::LT, NEXT_WORD);
// Last longword. In the case where length == 4 we compare the if (!is_string) {
// same longword twice, but that's still faster than another // if (a==a2)
// conditional branch. // return true;
eor(rscratch1, a1, a2);
cbz(rscratch1, SAME);
// if (a==null || a2==null)
// return false;
cbz(a1, DONE);
cbz(a2, DONE);
// if (a1.length != a2.length)
// return false;
ldrw(cnt1, Address(a1, length_offset));
ldrw(cnt2, Address(a2, length_offset));
eorw(tmp1, cnt1, cnt2);
cbnzw(tmp1, DONE);
ldr(tmp1, Address(str1)); lea(a1, Address(a1, base_offset));
ldr(tmp2, Address(str2)); lea(a2, Address(a2, base_offset));
eor(rscratch2, tmp1, tmp2);
cbz(rscratch2, SAME_CHARS);
b(DONE);
} }
bind(SHORT_STRING); // Check for short strings, i.e. smaller than wordSize.
// Is the length zero? subs(cnt1, cnt1, elem_per_word);
cbz(cnt, SAME_CHARS); br(Assembler::LT, SHORT);
// Main 8 byte comparison loop.
bind(SHORT_LOOP); bind(NEXT_WORD); {
load_unsigned_short(tmp1, Address(post(str1, 2))); ldr(tmp1, Address(post(a1, wordSize)));
load_unsigned_short(tmp2, Address(post(str2, 2))); ldr(tmp2, Address(post(a2, wordSize)));
subw(tmp1, tmp1, tmp2); subs(cnt1, cnt1, elem_per_word);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DONE);
} br(GT, NEXT_WORD);
// Last longword. In the case where length == 4 we compare the
// same longword twice, but that's still faster than another
// conditional branch.
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
// length == 4.
if (log_elem_size > 0)
lsl(cnt1, cnt1, log_elem_size);
ldr(tmp1, Address(a1, cnt1));
ldr(tmp2, Address(a2, cnt1));
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DONE); cbnz(tmp1, DONE);
sub(cnt, cnt, 1); b(SAME);
cbnz(cnt, SHORT_LOOP);
// Strings are equal. bind(SHORT);
bind(SAME_CHARS); Label TAIL03, TAIL01;
tbz(cnt1, 2 - log_elem_size, TAIL03); // 0-7 bytes left.
{
ldrw(tmp1, Address(post(a1, 4)));
ldrw(tmp2, Address(post(a2, 4)));
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
bind(TAIL03);
tbz(cnt1, 1 - log_elem_size, TAIL01); // 0-3 bytes left.
{
ldrh(tmp1, Address(post(a1, 2)));
ldrh(tmp2, Address(post(a2, 2)));
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
bind(TAIL01);
if (elem_size == 1) { // Only needed when comparing byte arrays.
tbz(cnt1, 0, SAME); // 0-1 bytes left.
{
ldrb(tmp1, a1);
ldrb(tmp2, a2);
eorw(tmp1, tmp1, tmp2);
cbnzw(tmp1, DONE);
}
}
// Arrays are equal.
bind(SAME);
mov(result, true); mov(result, true);
// That's it // That's it.
bind(DONE); bind(DONE);
BLOCK_COMMENT(is_string ? "} string_equals" : "} array_equals");
BLOCK_COMMENT("} string_equals");
} }
void MacroAssembler::byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
{
Register cnt1 = rscratch1;
Register cnt2 = rscratch2;
Register tmp2 = rscratch2;
Label SAME, DIFFER, NEXT, TAIL07, TAIL03, TAIL01;
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_BYTE);
BLOCK_COMMENT("byte_arrays_equals {");
// different until proven equal
mov(result, false);
// same array?
cmp(ary1, ary2);
br(Assembler::EQ, SAME);
// ne if either null
cbz(ary1, DIFFER);
cbz(ary2, DIFFER);
// lengths ne?
ldrw(cnt1, Address(ary1, length_offset));
ldrw(cnt2, Address(ary2, length_offset));
cmp(cnt1, cnt2);
br(Assembler::NE, DIFFER);
lea(ary1, Address(ary1, base_offset));
lea(ary2, Address(ary2, base_offset));
subs(cnt1, cnt1, 8);
br(LT, TAIL07);
BIND(NEXT);
ldr(tmp1, Address(post(ary1, 8)));
ldr(tmp2, Address(post(ary2, 8)));
subs(cnt1, cnt1, 8);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DIFFER);
br(GE, NEXT);
BIND(TAIL07); // 0-7 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b100);
br(EQ, TAIL03);
ldrw(tmp1, Address(post(ary1, 4)));
ldrw(tmp2, Address(post(ary2, 4)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL03); // 0-3 bytes left, cnt1 = #bytes left - 4
tst(cnt1, 0b10);
br(EQ, TAIL01);
ldrh(tmp1, Address(post(ary1, 2)));
ldrh(tmp2, Address(post(ary2, 2)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL01); // 0-1 byte left
tst(cnt1, 0b01);
br(EQ, SAME);
ldrb(tmp1, ary1);
ldrb(tmp2, ary2);
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(SAME);
mov(result, true);
BIND(DIFFER); // result already set
BLOCK_COMMENT("} byte_arrays_equals");
}
// Compare char[] arrays aligned to 4 bytes
void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1)
{
Register cnt1 = rscratch1;
Register cnt2 = rscratch2;
Register tmp2 = rscratch2;
Label SAME, DIFFER, NEXT, TAIL03, TAIL01;
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
BLOCK_COMMENT("char_arrays_equals {");
// different until proven equal
mov(result, false);
// same array?
cmp(ary1, ary2);
br(Assembler::EQ, SAME);
// ne if either null
cbz(ary1, DIFFER);
cbz(ary2, DIFFER);
// lengths ne?
ldrw(cnt1, Address(ary1, length_offset));
ldrw(cnt2, Address(ary2, length_offset));
cmp(cnt1, cnt2);
br(Assembler::NE, DIFFER);
lea(ary1, Address(ary1, base_offset));
lea(ary2, Address(ary2, base_offset));
subs(cnt1, cnt1, 4);
br(LT, TAIL03);
BIND(NEXT);
ldr(tmp1, Address(post(ary1, 8)));
ldr(tmp2, Address(post(ary2, 8)));
subs(cnt1, cnt1, 4);
eor(tmp1, tmp1, tmp2);
cbnz(tmp1, DIFFER);
br(GE, NEXT);
BIND(TAIL03); // 0-3 chars left, cnt1 = #chars left - 4
tst(cnt1, 0b10);
br(EQ, TAIL01);
ldrw(tmp1, Address(post(ary1, 4)));
ldrw(tmp2, Address(post(ary2, 4)));
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(TAIL01); // 0-1 chars left
tst(cnt1, 0b01);
br(EQ, SAME);
ldrh(tmp1, ary1);
ldrh(tmp2, ary2);
cmp(tmp1, tmp2);
br(NE, DIFFER);
BIND(SAME);
mov(result, true);
BIND(DIFFER); // result already set
BLOCK_COMMENT("} char_arrays_equals");
}
// encode char[] to byte[] in ISO_8859_1 // encode char[] to byte[] in ISO_8859_1
void MacroAssembler::encode_iso_array(Register src, Register dst, void MacroAssembler::encode_iso_array(Register src, Register dst,
Register len, Register result, Register len, Register result,

View File

@ -1186,13 +1186,11 @@ public:
void string_compare(Register str1, Register str2, void string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result, Register cnt1, Register cnt2, Register result,
Register tmp1); Register tmp1);
void string_equals(Register str1, Register str2,
Register cnt, Register result, void arrays_equals(Register a1, Register a2,
Register tmp1); Register result, Register cnt1,
void char_arrays_equals(Register ary1, Register ary2, int elem_size, bool is_string);
Register result, Register tmp1);
void byte_arrays_equals(Register ary1, Register ary2,
Register result, Register tmp1);
void encode_iso_array(Register src, Register dst, void encode_iso_array(Register src, Register dst,
Register len, Register result, Register len, Register result,
FloatRegister Vtmp1, FloatRegister Vtmp2, FloatRegister Vtmp1, FloatRegister Vtmp2,

View File

@ -105,13 +105,20 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
inline friend NativeInstruction* nativeInstruction_at(address address); inline friend NativeInstruction* nativeInstruction_at(address address);
static bool is_adrp_at(address instr); static bool is_adrp_at(address instr);
static bool is_ldr_literal_at(address instr); static bool is_ldr_literal_at(address instr);
bool is_ldr_literal() {
return is_ldr_literal_at(addr_at(0));
}
static bool is_ldrw_to_zr(address instr); static bool is_ldrw_to_zr(address instr);
static bool is_call_at(address instr) { static bool is_call_at(address instr) {
const uint32_t insn = (*(uint32_t*)instr); const uint32_t insn = (*(uint32_t*)instr);
return (insn >> 26) == 0b100101; return (insn >> 26) == 0b100101;
} }
bool is_call() { bool is_call() {
return is_call_at(addr_at(0)); return is_call_at(addr_at(0));
} }

View File

@ -163,30 +163,20 @@ class StubGenerator: public StubCodeGenerator {
sp_after_call_off = -26, sp_after_call_off = -26,
d15_off = -26, d15_off = -26,
d14_off = -25,
d13_off = -24, d13_off = -24,
d12_off = -23,
d11_off = -22, d11_off = -22,
d10_off = -21,
d9_off = -20, d9_off = -20,
d8_off = -19,
r28_off = -18, r28_off = -18,
r27_off = -17,
r26_off = -16, r26_off = -16,
r25_off = -15,
r24_off = -14, r24_off = -14,
r23_off = -13,
r22_off = -12, r22_off = -12,
r21_off = -11,
r20_off = -10, r20_off = -10,
r19_off = -9,
call_wrapper_off = -8, call_wrapper_off = -8,
result_off = -7, result_off = -7,
result_type_off = -6, result_type_off = -6,
method_off = -5, method_off = -5,
entry_point_off = -4, entry_point_off = -4,
parameters_off = -3,
parameter_size_off = -2, parameter_size_off = -2,
thread_off = -1, thread_off = -1,
fp_f = 0, fp_f = 0,
@ -208,30 +198,20 @@ class StubGenerator: public StubCodeGenerator {
const Address result_type (rfp, result_type_off * wordSize); const Address result_type (rfp, result_type_off * wordSize);
const Address method (rfp, method_off * wordSize); const Address method (rfp, method_off * wordSize);
const Address entry_point (rfp, entry_point_off * wordSize); const Address entry_point (rfp, entry_point_off * wordSize);
const Address parameters (rfp, parameters_off * wordSize);
const Address parameter_size(rfp, parameter_size_off * wordSize); const Address parameter_size(rfp, parameter_size_off * wordSize);
const Address thread (rfp, thread_off * wordSize); const Address thread (rfp, thread_off * wordSize);
const Address d15_save (rfp, d15_off * wordSize); const Address d15_save (rfp, d15_off * wordSize);
const Address d14_save (rfp, d14_off * wordSize);
const Address d13_save (rfp, d13_off * wordSize); const Address d13_save (rfp, d13_off * wordSize);
const Address d12_save (rfp, d12_off * wordSize);
const Address d11_save (rfp, d11_off * wordSize); const Address d11_save (rfp, d11_off * wordSize);
const Address d10_save (rfp, d10_off * wordSize);
const Address d9_save (rfp, d9_off * wordSize); const Address d9_save (rfp, d9_off * wordSize);
const Address d8_save (rfp, d8_off * wordSize);
const Address r28_save (rfp, r28_off * wordSize); const Address r28_save (rfp, r28_off * wordSize);
const Address r27_save (rfp, r27_off * wordSize);
const Address r26_save (rfp, r26_off * wordSize); const Address r26_save (rfp, r26_off * wordSize);
const Address r25_save (rfp, r25_off * wordSize);
const Address r24_save (rfp, r24_off * wordSize); const Address r24_save (rfp, r24_off * wordSize);
const Address r23_save (rfp, r23_off * wordSize);
const Address r22_save (rfp, r22_off * wordSize); const Address r22_save (rfp, r22_off * wordSize);
const Address r21_save (rfp, r21_off * wordSize);
const Address r20_save (rfp, r20_off * wordSize); const Address r20_save (rfp, r20_off * wordSize);
const Address r19_save (rfp, r19_off * wordSize);
// stub code // stub code
@ -254,31 +234,20 @@ class StubGenerator: public StubCodeGenerator {
// rthread because we want to sanity check rthread later // rthread because we want to sanity check rthread later
__ str(c_rarg7, thread); __ str(c_rarg7, thread);
__ strw(c_rarg6, parameter_size); __ strw(c_rarg6, parameter_size);
__ str(c_rarg5, parameters); __ stp(c_rarg4, c_rarg5, entry_point);
__ str(c_rarg4, entry_point); __ stp(c_rarg2, c_rarg3, result_type);
__ str(c_rarg3, method); __ stp(c_rarg0, c_rarg1, call_wrapper);
__ str(c_rarg2, result_type);
__ str(c_rarg1, result);
__ str(c_rarg0, call_wrapper);
__ str(r19, r19_save);
__ str(r20, r20_save);
__ str(r21, r21_save);
__ str(r22, r22_save);
__ str(r23, r23_save);
__ str(r24, r24_save);
__ str(r25, r25_save);
__ str(r26, r26_save);
__ str(r27, r27_save);
__ str(r28, r28_save);
__ strd(v8, d8_save); __ stp(r20, r19, r20_save);
__ strd(v9, d9_save); __ stp(r22, r21, r22_save);
__ strd(v10, d10_save); __ stp(r24, r23, r24_save);
__ strd(v11, d11_save); __ stp(r26, r25, r26_save);
__ strd(v12, d12_save); __ stp(r28, r27, r28_save);
__ strd(v13, d13_save);
__ strd(v14, d14_save); __ stpd(v9, v8, d9_save);
__ strd(v15, d15_save); __ stpd(v11, v10, d11_save);
__ stpd(v13, v12, d13_save);
__ stpd(v15, v14, d15_save);
// install Java thread in global register now we have saved // install Java thread in global register now we have saved
// whatever value it held // whatever value it held
@ -385,33 +354,22 @@ class StubGenerator: public StubCodeGenerator {
#endif #endif
// restore callee-save registers // restore callee-save registers
__ ldrd(v15, d15_save); __ ldpd(v15, v14, d15_save);
__ ldrd(v14, d14_save); __ ldpd(v13, v12, d13_save);
__ ldrd(v13, d13_save); __ ldpd(v11, v10, d11_save);
__ ldrd(v12, d12_save); __ ldpd(v9, v8, d9_save);
__ ldrd(v11, d11_save);
__ ldrd(v10, d10_save);
__ ldrd(v9, d9_save);
__ ldrd(v8, d8_save);
__ ldr(r28, r28_save); __ ldp(r28, r27, r28_save);
__ ldr(r27, r27_save); __ ldp(r26, r25, r26_save);
__ ldr(r26, r26_save); __ ldp(r24, r23, r24_save);
__ ldr(r25, r25_save); __ ldp(r22, r21, r22_save);
__ ldr(r24, r24_save); __ ldp(r20, r19, r20_save);
__ ldr(r23, r23_save);
__ ldr(r22, r22_save); __ ldp(c_rarg0, c_rarg1, call_wrapper);
__ ldr(r21, r21_save);
__ ldr(r20, r20_save);
__ ldr(r19, r19_save);
__ ldr(c_rarg0, call_wrapper);
__ ldr(c_rarg1, result);
__ ldrw(c_rarg2, result_type); __ ldrw(c_rarg2, result_type);
__ ldr(c_rarg3, method); __ ldr(c_rarg3, method);
__ ldr(c_rarg4, entry_point); __ ldp(c_rarg4, c_rarg5, entry_point);
__ ldr(c_rarg5, parameters); __ ldp(c_rarg6, c_rarg7, parameter_size);
__ ldr(c_rarg6, parameter_size);
__ ldr(c_rarg7, thread);
#ifndef PRODUCT #ifndef PRODUCT
// tell the simulator we are about to end Java execution // tell the simulator we are about to end Java execution
@ -666,7 +624,7 @@ class StubGenerator: public StubCodeGenerator {
// count - element count // count - element count
// tmp - scratch register // tmp - scratch register
// //
// Destroy no registers! // Destroy no registers except rscratch1 and rscratch2
// //
void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) { void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
BarrierSet* bs = Universe::heap()->barrier_set(); BarrierSet* bs = Universe::heap()->barrier_set();
@ -674,12 +632,13 @@ class StubGenerator: public StubCodeGenerator {
case BarrierSet::G1SATBCTLogging: case BarrierSet::G1SATBCTLogging:
// With G1, don't generate the call if we statically know that the target in uninitialized // With G1, don't generate the call if we statically know that the target in uninitialized
if (!dest_uninitialized) { if (!dest_uninitialized) {
__ push(RegSet::range(r0, r29), sp); // integer registers except lr & sp __ push_call_clobbered_registers();
if (count == c_rarg0) { if (count == c_rarg0) {
if (addr == c_rarg1) { if (addr == c_rarg1) {
// exactly backwards!! // exactly backwards!!
__ stp(c_rarg0, c_rarg1, __ pre(sp, -2 * wordSize)); __ mov(rscratch1, c_rarg0);
__ ldp(c_rarg1, c_rarg0, __ post(sp, -2 * wordSize)); __ mov(c_rarg0, c_rarg1);
__ mov(c_rarg1, rscratch1);
} else { } else {
__ mov(c_rarg1, count); __ mov(c_rarg1, count);
__ mov(c_rarg0, addr); __ mov(c_rarg0, addr);
@ -689,7 +648,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg1, count); __ mov(c_rarg1, count);
} }
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2); __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ pop(RegSet::range(r0, r29), sp); // integer registers except lr & sp } __ pop_call_clobbered_registers();
break; break;
case BarrierSet::CardTableForRS: case BarrierSet::CardTableForRS:
case BarrierSet::CardTableExtension: case BarrierSet::CardTableExtension:
@ -719,7 +678,7 @@ class StubGenerator: public StubCodeGenerator {
case BarrierSet::G1SATBCTLogging: case BarrierSet::G1SATBCTLogging:
{ {
__ push(RegSet::range(r0, r29), sp); // integer registers except lr & sp __ push_call_clobbered_registers();
// must compute element count unless barrier set interface is changed (other platforms supply count) // must compute element count unless barrier set interface is changed (other platforms supply count)
assert_different_registers(start, end, scratch); assert_different_registers(start, end, scratch);
__ lea(scratch, Address(end, BytesPerHeapOop)); __ lea(scratch, Address(end, BytesPerHeapOop));
@ -728,7 +687,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg0, start); __ mov(c_rarg0, start);
__ mov(c_rarg1, scratch); __ mov(c_rarg1, scratch);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2); __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ pop(RegSet::range(r0, r29), sp); // integer registers except lr & sp } __ pop_call_clobbered_registers();
} }
break; break;
case BarrierSet::CardTableForRS: case BarrierSet::CardTableForRS:
@ -1394,10 +1353,10 @@ class StubGenerator: public StubCodeGenerator {
// no-overlap entry point used by generate_conjoint_long_oop_copy(). // no-overlap entry point used by generate_conjoint_long_oop_copy().
// //
address generate_disjoint_oop_copy(bool aligned, address *entry, address generate_disjoint_oop_copy(bool aligned, address *entry,
const char *name, bool dest_uninitialized = false) { const char *name, bool dest_uninitialized) {
const bool is_oop = true; const bool is_oop = true;
const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong);
return generate_disjoint_copy(size, aligned, is_oop, entry, name); return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized);
} }
// Arguments: // Arguments:
@ -1412,10 +1371,11 @@ class StubGenerator: public StubCodeGenerator {
// //
address generate_conjoint_oop_copy(bool aligned, address generate_conjoint_oop_copy(bool aligned,
address nooverlap_target, address *entry, address nooverlap_target, address *entry,
const char *name, bool dest_uninitialized = false) { const char *name, bool dest_uninitialized) {
const bool is_oop = true; const bool is_oop = true;
const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong);
return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, name); return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry,
name, dest_uninitialized);
} }
@ -1522,6 +1482,8 @@ class StubGenerator: public StubCodeGenerator {
} }
#endif //ASSERT #endif //ASSERT
gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
// save the original count // save the original count
__ mov(count_save, count); __ mov(count_save, count);
@ -1988,9 +1950,11 @@ class StubGenerator: public StubCodeGenerator {
bool aligned = !UseCompressedOops; bool aligned = !UseCompressedOops;
StubRoutines::_arrayof_oop_disjoint_arraycopy StubRoutines::_arrayof_oop_disjoint_arraycopy
= generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy"); = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy",
/*dest_uninitialized*/false);
StubRoutines::_arrayof_oop_arraycopy StubRoutines::_arrayof_oop_arraycopy
= generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy"); = generate_conjoint_oop_copy(aligned, entry, &entry_oop_arraycopy, "arrayof_oop_arraycopy",
/*dest_uninitialized*/false);
// Aligned versions without pre-barriers // Aligned versions without pre-barriers
StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit
= generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit", = generate_disjoint_oop_copy(aligned, &entry, "arrayof_oop_disjoint_arraycopy_uninit",

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,8 +74,7 @@ define_pd_global(size_t, CMSYoungGenPerWorker, 16*M); // Default max size of CM
define_pd_global(uintx, TypeProfileLevel, 111); define_pd_global(uintx, TypeProfileLevel, 111);
// No performance work done here yet. define_pd_global(bool, CompactStrings, true);
define_pd_global(bool, CompactStrings, false);
// Platform dependent flag handling: flags only defined on this platform. // Platform dependent flag handling: flags only defined on this platform.
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \ #define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \

View File

@ -45,6 +45,9 @@
#include "gc/g1/g1SATBCardTableModRefBS.hpp" #include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
#ifdef COMPILER2
#include "opto/intrinsicnode.hpp"
#endif
#ifdef PRODUCT #ifdef PRODUCT
#define BLOCK_COMMENT(str) // nothing #define BLOCK_COMMENT(str) // nothing
@ -3168,6 +3171,553 @@ void MacroAssembler::clear_memory_doubleword(Register base_ptr, Register cnt_dwo
/////////////////////////////////////////// String intrinsics //////////////////////////////////////////// /////////////////////////////////////////// String intrinsics ////////////////////////////////////////////
#ifdef COMPILER2
// Intrinsics for CompactStrings
// Compress char[] to byte[] by compressing 16 bytes at once.
void MacroAssembler::string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure) {
const Register tmp0 = R0;
assert_different_registers(src, dst, cnt, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
Label Lloop, Lslow;
// Check if cnt >= 8 (= 16 bytes)
lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF00FF00FF
srwi_(tmp2, cnt, 3);
beq(CCR0, Lslow);
ori(tmp1, tmp1, 0xFF);
rldimi(tmp1, tmp1, 32, 0);
mtctr(tmp2);
// 2x unrolled loop
bind(Lloop);
ld(tmp2, 0, src); // _0_1_2_3 (Big Endian)
ld(tmp4, 8, src); // _4_5_6_7
orr(tmp0, tmp2, tmp4);
rldicl(tmp3, tmp2, 6*8, 64-24); // _____1_2
rldimi(tmp2, tmp2, 2*8, 2*8); // _0_2_3_3
rldicl(tmp5, tmp4, 6*8, 64-24); // _____5_6
rldimi(tmp4, tmp4, 2*8, 2*8); // _4_6_7_7
andc_(tmp0, tmp0, tmp1);
bne(CCR0, Lfailure); // Not latin1.
addi(src, src, 16);
rlwimi(tmp3, tmp2, 0*8, 24, 31);// _____1_3
srdi(tmp2, tmp2, 3*8); // ____0_2_
rlwimi(tmp5, tmp4, 0*8, 24, 31);// _____5_7
srdi(tmp4, tmp4, 3*8); // ____4_6_
orr(tmp2, tmp2, tmp3); // ____0123
orr(tmp4, tmp4, tmp5); // ____4567
stw(tmp2, 0, dst);
stw(tmp4, 4, dst);
addi(dst, dst, 8);
bdnz(Lloop);
bind(Lslow); // Fallback to slow version
}
// Compress char[] to byte[]. cnt must be positive int.
void MacroAssembler::string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure) {
Label Lloop;
mtctr(cnt);
bind(Lloop);
lhz(tmp, 0, src);
cmplwi(CCR0, tmp, 0xff);
bgt(CCR0, Lfailure); // Not latin1.
addi(src, src, 2);
stb(tmp, 0, dst);
addi(dst, dst, 1);
bdnz(Lloop);
}
// Inflate byte[] to char[] by inflating 16 bytes at once.
void MacroAssembler::string_inflate_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5) {
const Register tmp0 = R0;
assert_different_registers(src, dst, cnt, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
Label Lloop, Lslow;
// Check if cnt >= 8
srwi_(tmp2, cnt, 3);
beq(CCR0, Lslow);
lis(tmp1, 0xFF); // tmp1 = 0x00FF00FF
ori(tmp1, tmp1, 0xFF);
mtctr(tmp2);
// 2x unrolled loop
bind(Lloop);
lwz(tmp2, 0, src); // ____0123 (Big Endian)
lwz(tmp4, 4, src); // ____4567
addi(src, src, 8);
rldicl(tmp3, tmp2, 7*8, 64-8); // _______2
rlwimi(tmp2, tmp2, 3*8, 16, 23);// ____0113
rldicl(tmp5, tmp4, 7*8, 64-8); // _______6
rlwimi(tmp4, tmp4, 3*8, 16, 23);// ____4557
andc(tmp0, tmp2, tmp1); // ____0_1_
rlwimi(tmp2, tmp3, 2*8, 0, 23); // _____2_3
andc(tmp3, tmp4, tmp1); // ____4_5_
rlwimi(tmp4, tmp5, 2*8, 0, 23); // _____6_7
rldimi(tmp2, tmp0, 3*8, 0*8); // _0_1_2_3
rldimi(tmp4, tmp3, 3*8, 0*8); // _4_5_6_7
std(tmp2, 0, dst);
std(tmp4, 8, dst);
addi(dst, dst, 16);
bdnz(Lloop);
bind(Lslow); // Fallback to slow version
}
// Inflate byte[] to char[]. cnt must be positive int.
void MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp) {
Label Lloop;
mtctr(cnt);
bind(Lloop);
lbz(tmp, 0, src);
addi(src, src, 1);
sth(tmp, 0, dst);
addi(dst, dst, 2);
bdnz(Lloop);
}
void MacroAssembler::string_compare(Register str1, Register str2,
Register cnt1, Register cnt2,
Register tmp1, Register result, int ae) {
const Register tmp0 = R0,
diff = tmp1;
assert_different_registers(str1, str2, cnt1, cnt2, tmp0, tmp1, result);
Label Ldone, Lslow, Lloop, Lreturn_diff;
// Note: Making use of the fact that compareTo(a, b) == -compareTo(b, a)
// we interchange str1 and str2 in the UL case and negate the result.
// Like this, str1 is always latin1 encoded, except for the UU case.
// In addition, we need 0 (or sign which is 0) extend.
if (ae == StrIntrinsicNode::UU) {
srwi(cnt1, cnt1, 1);
} else {
clrldi(cnt1, cnt1, 32);
}
if (ae != StrIntrinsicNode::LL) {
srwi(cnt2, cnt2, 1);
} else {
clrldi(cnt2, cnt2, 32);
}
// See if the lengths are different, and calculate min in cnt1.
// Save diff in case we need it for a tie-breaker.
subf_(diff, cnt2, cnt1); // diff = cnt1 - cnt2
// if (diff > 0) { cnt1 = cnt2; }
if (VM_Version::has_isel()) {
isel(cnt1, CCR0, Assembler::greater, /*invert*/ false, cnt2);
} else {
Label Lskip;
blt(CCR0, Lskip);
mr(cnt1, cnt2);
bind(Lskip);
}
// Rename registers
Register chr1 = result;
Register chr2 = tmp0;
// Compare multiple characters in fast loop (only implemented for same encoding).
int stride1 = 8, stride2 = 8;
if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
int log2_chars_per_iter = (ae == StrIntrinsicNode::LL) ? 3 : 2;
Label Lfastloop, Lskipfast;
srwi_(tmp0, cnt1, log2_chars_per_iter);
beq(CCR0, Lskipfast);
rldicl(cnt2, cnt1, 0, 64 - log2_chars_per_iter); // Remaining characters.
li(cnt1, 1 << log2_chars_per_iter); // Initialize for failure case: Rescan characters from current iteration.
mtctr(tmp0);
bind(Lfastloop);
ld(chr1, 0, str1);
ld(chr2, 0, str2);
cmpd(CCR0, chr1, chr2);
bne(CCR0, Lslow);
addi(str1, str1, stride1);
addi(str2, str2, stride2);
bdnz(Lfastloop);
mr(cnt1, cnt2); // Remaining characters.
bind(Lskipfast);
}
// Loop which searches the first difference character by character.
cmpwi(CCR0, cnt1, 0);
beq(CCR0, Lreturn_diff);
bind(Lslow);
mtctr(cnt1);
switch (ae) {
case StrIntrinsicNode::LL: stride1 = 1; stride2 = 1; break;
case StrIntrinsicNode::UL: // fallthru (see comment above)
case StrIntrinsicNode::LU: stride1 = 1; stride2 = 2; break;
case StrIntrinsicNode::UU: stride1 = 2; stride2 = 2; break;
default: ShouldNotReachHere(); break;
}
bind(Lloop);
if (stride1 == 1) { lbz(chr1, 0, str1); } else { lhz(chr1, 0, str1); }
if (stride2 == 1) { lbz(chr2, 0, str2); } else { lhz(chr2, 0, str2); }
subf_(result, chr2, chr1); // result = chr1 - chr2
bne(CCR0, Ldone);
addi(str1, str1, stride1);
addi(str2, str2, stride2);
bdnz(Lloop);
// If strings are equal up to min length, return the length difference.
bind(Lreturn_diff);
mr(result, diff);
// Otherwise, return the difference between the first mismatched chars.
bind(Ldone);
if (ae == StrIntrinsicNode::UL) {
neg(result, result); // Negate result (see note above).
}
}
void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary2,
Register limit, Register tmp1, Register result, bool is_byte) {
const Register tmp0 = R0;
assert_different_registers(ary1, ary2, limit, tmp0, tmp1, result);
Label Ldone, Lskiploop, Lloop, Lfastloop, Lskipfast;
bool limit_needs_shift = false;
if (is_array_equ) {
const int length_offset = arrayOopDesc::length_offset_in_bytes();
const int base_offset = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR);
// Return true if the same array.
cmpd(CCR0, ary1, ary2);
beq(CCR0, Lskiploop);
// Return false if one of them is NULL.
cmpdi(CCR0, ary1, 0);
cmpdi(CCR1, ary2, 0);
li(result, 0);
cror(CCR0, Assembler::equal, CCR1, Assembler::equal);
beq(CCR0, Ldone);
// Load the lengths of arrays.
lwz(limit, length_offset, ary1);
lwz(tmp0, length_offset, ary2);
// Return false if the two arrays are not equal length.
cmpw(CCR0, limit, tmp0);
bne(CCR0, Ldone);
// Load array addresses.
addi(ary1, ary1, base_offset);
addi(ary2, ary2, base_offset);
} else {
limit_needs_shift = !is_byte;
li(result, 0); // Assume not equal.
}
// Rename registers
Register chr1 = tmp0;
Register chr2 = tmp1;
// Compare 8 bytes per iteration in fast loop.
const int log2_chars_per_iter = is_byte ? 3 : 2;
srwi_(tmp0, limit, log2_chars_per_iter + (limit_needs_shift ? 1 : 0));
beq(CCR0, Lskipfast);
mtctr(tmp0);
bind(Lfastloop);
ld(chr1, 0, ary1);
ld(chr2, 0, ary2);
addi(ary1, ary1, 8);
addi(ary2, ary2, 8);
cmpd(CCR0, chr1, chr2);
bne(CCR0, Ldone);
bdnz(Lfastloop);
bind(Lskipfast);
rldicl_(limit, limit, limit_needs_shift ? 64 - 1 : 0, 64 - log2_chars_per_iter); // Remaining characters.
beq(CCR0, Lskiploop);
mtctr(limit);
// Character by character.
bind(Lloop);
if (is_byte) {
lbz(chr1, 0, ary1);
lbz(chr2, 0, ary2);
addi(ary1, ary1, 1);
addi(ary2, ary2, 1);
} else {
lhz(chr1, 0, ary1);
lhz(chr2, 0, ary2);
addi(ary1, ary1, 2);
addi(ary2, ary2, 2);
}
cmpw(CCR0, chr1, chr2);
bne(CCR0, Ldone);
bdnz(Lloop);
bind(Lskiploop);
li(result, 1); // All characters are equal.
bind(Ldone);
}
void MacroAssembler::string_indexof(Register result, Register haystack, Register haycnt,
Register needle, ciTypeArray* needle_values, Register needlecnt, int needlecntval,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, int ae) {
// Ensure 0<needlecnt<=haycnt in ideal graph as prerequisite!
Label L_TooShort, L_Found, L_NotFound, L_End;
Register last_addr = haycnt, // Kill haycnt at the beginning.
addr = tmp1,
n_start = tmp2,
ch1 = tmp3,
ch2 = R0;
assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
const int h_csize = (ae == StrIntrinsicNode::LL) ? 1 : 2;
const int n_csize = (ae == StrIntrinsicNode::UU) ? 2 : 1;
// **************************************************************************************************
// Prepare for main loop: optimized for needle count >=2, bail out otherwise.
// **************************************************************************************************
// Compute last haystack addr to use if no match gets found.
clrldi(haycnt, haycnt, 32); // Ensure positive int is valid as 64 bit value.
addi(addr, haystack, -h_csize); // Accesses use pre-increment.
if (needlecntval == 0) { // variable needlecnt
cmpwi(CCR6, needlecnt, 2);
clrldi(needlecnt, needlecnt, 32); // Ensure positive int is valid as 64 bit value.
blt(CCR6, L_TooShort); // Variable needlecnt: handle short needle separately.
}
if (n_csize == 2) { lwz(n_start, 0, needle); } else { lhz(n_start, 0, needle); } // Load first 2 characters of needle.
if (needlecntval == 0) { // variable needlecnt
subf(ch1, needlecnt, haycnt); // Last character index to compare is haycnt-needlecnt.
addi(needlecnt, needlecnt, -2); // Rest of needle.
} else { // constant needlecnt
guarantee(needlecntval != 1, "IndexOf with single-character needle must be handled separately");
assert((needlecntval & 0x7fff) == needlecntval, "wrong immediate");
addi(ch1, haycnt, -needlecntval); // Last character index to compare is haycnt-needlecnt.
if (needlecntval > 3) { li(needlecnt, needlecntval - 2); } // Rest of needle.
}
if (h_csize == 2) { slwi(ch1, ch1, 1); } // Scale to number of bytes.
if (ae ==StrIntrinsicNode::UL) {
srwi(tmp4, n_start, 1*8); // ___0
rlwimi(n_start, tmp4, 2*8, 0, 23); // _0_1
}
add(last_addr, haystack, ch1); // Point to last address to compare (haystack+2*(haycnt-needlecnt)).
// Main Loop (now we have at least 2 characters).
Label L_OuterLoop, L_InnerLoop, L_FinalCheck, L_Comp1, L_Comp2;
bind(L_OuterLoop); // Search for 1st 2 characters.
Register addr_diff = tmp4;
subf(addr_diff, addr, last_addr); // Difference between already checked address and last address to check.
addi(addr, addr, h_csize); // This is the new address we want to use for comparing.
srdi_(ch2, addr_diff, h_csize);
beq(CCR0, L_FinalCheck); // 2 characters left?
mtctr(ch2); // num of characters / 2
bind(L_InnerLoop); // Main work horse (2x unrolled search loop)
if (h_csize == 2) { // Load 2 characters of haystack (ignore alignment).
lwz(ch1, 0, addr);
lwz(ch2, 2, addr);
} else {
lhz(ch1, 0, addr);
lhz(ch2, 1, addr);
}
cmpw(CCR0, ch1, n_start); // Compare 2 characters (1 would be sufficient but try to reduce branches to CompLoop).
cmpw(CCR1, ch2, n_start);
beq(CCR0, L_Comp1); // Did we find the needle start?
beq(CCR1, L_Comp2);
addi(addr, addr, 2 * h_csize);
bdnz(L_InnerLoop);
bind(L_FinalCheck);
andi_(addr_diff, addr_diff, h_csize); // Remaining characters not covered by InnerLoop: (num of characters) & 1.
beq(CCR0, L_NotFound);
if (h_csize == 2) { lwz(ch1, 0, addr); } else { lhz(ch1, 0, addr); } // One position left at which we have to compare.
cmpw(CCR1, ch1, n_start);
beq(CCR1, L_Comp1);
bind(L_NotFound);
li(result, -1); // not found
b(L_End);
// **************************************************************************************************
// Special Case: unfortunately, the variable needle case can be called with needlecnt<2
// **************************************************************************************************
if (needlecntval == 0) { // We have to handle these cases separately.
Label L_OneCharLoop;
bind(L_TooShort);
mtctr(haycnt);
if (n_csize == 2) { lhz(n_start, 0, needle); } else { lbz(n_start, 0, needle); } // First character of needle
bind(L_OneCharLoop);
if (h_csize == 2) { lhzu(ch1, 2, addr); } else { lbzu(ch1, 1, addr); }
cmpw(CCR1, ch1, n_start);
beq(CCR1, L_Found); // Did we find the one character needle?
bdnz(L_OneCharLoop);
li(result, -1); // Not found.
b(L_End);
}
// **************************************************************************************************
// Regular Case Part II: compare rest of needle (first 2 characters have been compared already)
// **************************************************************************************************
// Compare the rest
bind(L_Comp2);
addi(addr, addr, h_csize); // First comparison has failed, 2nd one hit.
bind(L_Comp1); // Addr points to possible needle start.
if (needlecntval != 2) { // Const needlecnt==2?
if (needlecntval != 3) {
if (needlecntval == 0) { beq(CCR6, L_Found); } // Variable needlecnt==2?
Register n_ind = tmp4,
h_ind = n_ind;
li(n_ind, 2 * n_csize); // First 2 characters are already compared, use index 2.
mtctr(needlecnt); // Decremented by 2, still > 0.
Label L_CompLoop;
bind(L_CompLoop);
if (ae ==StrIntrinsicNode::UL) {
h_ind = ch1;
sldi(h_ind, n_ind, 1);
}
if (n_csize == 2) { lhzx(ch2, needle, n_ind); } else { lbzx(ch2, needle, n_ind); }
if (h_csize == 2) { lhzx(ch1, addr, h_ind); } else { lbzx(ch1, addr, h_ind); }
cmpw(CCR1, ch1, ch2);
bne(CCR1, L_OuterLoop);
addi(n_ind, n_ind, n_csize);
bdnz(L_CompLoop);
} else { // No loop required if there's only one needle character left.
if (n_csize == 2) { lhz(ch2, 2 * 2, needle); } else { lbz(ch2, 2 * 1, needle); }
if (h_csize == 2) { lhz(ch1, 2 * 2, addr); } else { lbz(ch1, 2 * 1, addr); }
cmpw(CCR1, ch1, ch2);
bne(CCR1, L_OuterLoop);
}
}
// Return index ...
bind(L_Found);
subf(result, haystack, addr); // relative to haystack, ...
if (h_csize == 2) { srdi(result, result, 1); } // in characters.
bind(L_End);
} // string_indexof
void MacroAssembler::string_indexof_char(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar, Register tmp1, Register tmp2, bool is_byte) {
assert_different_registers(haystack, haycnt, needle, tmp1, tmp2);
Label L_InnerLoop, L_FinalCheck, L_Found1, L_Found2, L_NotFound, L_End;
Register addr = tmp1,
ch1 = tmp2,
ch2 = R0;
const int h_csize = is_byte ? 1 : 2;
//4:
srwi_(tmp2, haycnt, 1); // Shift right by exact_log2(UNROLL_FACTOR).
mr(addr, haystack);
beq(CCR0, L_FinalCheck);
mtctr(tmp2); // Move to count register.
//8:
bind(L_InnerLoop); // Main work horse (2x unrolled search loop).
if (!is_byte) {
lhz(ch1, 0, addr);
lhz(ch2, 2, addr);
} else {
lbz(ch1, 0, addr);
lbz(ch2, 1, addr);
}
(needle != R0) ? cmpw(CCR0, ch1, needle) : cmplwi(CCR0, ch1, (unsigned int)needleChar);
(needle != R0) ? cmpw(CCR1, ch2, needle) : cmplwi(CCR1, ch2, (unsigned int)needleChar);
beq(CCR0, L_Found1); // Did we find the needle?
beq(CCR1, L_Found2);
addi(addr, addr, 2 * h_csize);
bdnz(L_InnerLoop);
//16:
bind(L_FinalCheck);
andi_(R0, haycnt, 1);
beq(CCR0, L_NotFound);
if (!is_byte) { lhz(ch1, 0, addr); } else { lbz(ch1, 0, addr); } // One position left at which we have to compare.
(needle != R0) ? cmpw(CCR1, ch1, needle) : cmplwi(CCR1, ch1, (unsigned int)needleChar);
beq(CCR1, L_Found1);
//21:
bind(L_NotFound);
li(result, -1); // Not found.
b(L_End);
bind(L_Found2);
addi(addr, addr, h_csize);
//24:
bind(L_Found1); // Return index ...
subf(result, haystack, addr); // relative to haystack, ...
if (!is_byte) { srdi(result, result, 1); } // in characters.
bind(L_End);
} // string_indexof_char
void MacroAssembler::has_negatives(Register src, Register cnt, Register result,
Register tmp1, Register tmp2) {
const Register tmp0 = R0;
assert_different_registers(src, result, cnt, tmp0, tmp1, tmp2);
Label Lfastloop, Lslow, Lloop, Lnoneg, Ldone;
// Check if cnt >= 8 (= 16 bytes)
lis(tmp1, (int)(short)0x8080); // tmp1 = 0x8080808080808080
srwi_(tmp2, cnt, 4);
li(result, 1); // Assume there's a negative byte.
beq(CCR0, Lslow);
ori(tmp1, tmp1, 0x8080);
rldimi(tmp1, tmp1, 32, 0);
mtctr(tmp2);
// 2x unrolled loop
bind(Lfastloop);
ld(tmp2, 0, src);
ld(tmp0, 8, src);
orr(tmp0, tmp2, tmp0);
and_(tmp0, tmp0, tmp1);
bne(CCR0, Ldone); // Found negative byte.
addi(src, src, 16);
bdnz(Lfastloop);
bind(Lslow); // Fallback to slow version
rldicl_(tmp0, cnt, 0, 64-4);
beq(CCR0, Lnoneg);
mtctr(tmp0);
bind(Lloop);
lbz(tmp0, 0, src);
addi(src, src, 1);
andi_(tmp0, tmp0, 0x80);
bne(CCR0, Ldone); // Found negative byte.
bdnz(Lloop);
bind(Lnoneg);
li(result, 0);
bind(Ldone);
}
// Intrinsics for non-CompactStrings
// Search for a single jchar in an jchar[]. // Search for a single jchar in an jchar[].
// //
// Assumes that result differs from all other registers. // Assumes that result differs from all other registers.
@ -3613,6 +4163,8 @@ void MacroAssembler::char_arrays_equalsImm(Register str1_reg, Register str2_reg,
bind(Ldone_false); bind(Ldone_false);
} }
#endif // Compiler2
// Helpers for Intrinsic Emitters // Helpers for Intrinsic Emitters
// //
// Revert the byte order of a 32bit value in a register // Revert the byte order of a 32bit value in a register

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -679,6 +679,39 @@ class MacroAssembler: public Assembler {
void clear_memory_doubleword(Register base_ptr, Register cnt_dwords, Register tmp = R0); void clear_memory_doubleword(Register base_ptr, Register cnt_dwords, Register tmp = R0);
#ifdef COMPILER2
// Intrinsics for CompactStrings
// Compress char[] to byte[] by compressing 16 bytes at once.
void string_compress_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5,
Label& Lfailure);
// Compress char[] to byte[]. cnt must be positive int.
void string_compress(Register src, Register dst, Register cnt, Register tmp, Label& Lfailure);
// Inflate byte[] to char[] by inflating 16 bytes at once.
void string_inflate_16(Register src, Register dst, Register cnt,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, Register tmp5);
// Inflate byte[] to char[]. cnt must be positive int.
void string_inflate(Register src, Register dst, Register cnt, Register tmp);
void string_compare(Register str1, Register str2, Register cnt1, Register cnt2,
Register tmp1, Register result, int ae);
void array_equals(bool is_array_equ, Register ary1, Register ary2,
Register limit, Register tmp1, Register result, bool is_byte);
void string_indexof(Register result, Register haystack, Register haycnt,
Register needle, ciTypeArray* needle_values, Register needlecnt, int needlecntval,
Register tmp1, Register tmp2, Register tmp3, Register tmp4, int ae);
void string_indexof_char(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar, Register tmp1, Register tmp2, bool is_byte);
void has_negatives(Register src, Register cnt, Register result, Register tmp1, Register tmp2);
// Intrinsics for non-CompactStrings
// Needle of length 1. // Needle of length 1.
void string_indexof_1(Register result, Register haystack, Register haycnt, void string_indexof_1(Register result, Register haystack, Register haycnt,
Register needle, jchar needleChar, Register needle, jchar needleChar,
@ -694,6 +727,7 @@ class MacroAssembler: public Assembler {
Register tmp5_reg); Register tmp5_reg);
void char_arrays_equalsImm(Register str1_reg, Register str2_reg, int cntval, Register result_reg, void char_arrays_equalsImm(Register str1_reg, Register str2_reg, int cntval, Register result_reg,
Register tmp1_reg, Register tmp2_reg); Register tmp1_reg, Register tmp2_reg);
#endif
// Emitters for BigInteger.multiplyToLen intrinsic. // Emitters for BigInteger.multiplyToLen intrinsic.
inline void multiply64(Register dest_hi, Register dest_lo, inline void multiply64(Register dest_hi, Register dest_lo,

View File

@ -1,6 +1,6 @@
// //
// Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2012, 2015 SAP SE. All rights reserved. // Copyright (c) 2012, 2016 SAP SE. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// //
// This code is free software; you can redistribute it and/or modify it // This code is free software; you can redistribute it and/or modify it
@ -2024,13 +2024,13 @@ const bool Matcher::match_rule_supported(int opcode) {
return (UsePopCountInstruction && VM_Version::has_popcntw()); return (UsePopCountInstruction && VM_Version::has_popcntw());
case Op_StrComp: case Op_StrComp:
return SpecialStringCompareTo && !CompactStrings; return SpecialStringCompareTo;
case Op_StrEquals: case Op_StrEquals:
return SpecialStringEquals && !CompactStrings; return SpecialStringEquals;
case Op_StrIndexOf: case Op_StrIndexOf:
return SpecialStringIndexOf && !CompactStrings; return SpecialStringIndexOf;
case Op_StrIndexOfChar: case Op_StrIndexOfChar:
return SpecialStringIndexOf && !CompactStrings; return SpecialStringIndexOf;
} }
return true; // Per default match rules are supported. return true; // Per default match rules are supported.
@ -11022,6 +11022,584 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, reg
ins_pipe(pipe_class_default); ins_pipe(pipe_class_default);
%} %}
instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::LU);
%}
ins_pipe(pipe_class_default);
%}
instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ctr, KILL cr0, TEMP tmp);
ins_cost(300);
format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_compare($str2$$Register, $str1$$Register,
$cnt2$$Register, $cnt1$$Register,
$tmp$$Register,
$result$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_default);
%}
instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $tmp$$Register,
$result$$Register, true /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst result,
iRegIdst tmp, regCTR ctr, flagsRegCR0 cr0) %{
predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP_DEF result, USE_KILL str1, USE_KILL str2, USE_KILL cnt, TEMP tmp, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Equals char[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(false, $str1$$Register, $str2$$Register,
$cnt$$Register, $tmp$$Register,
$result$$Register, false /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (AryEq ary1 ary2));
effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(true, $ary1$$Register, $ary2$$Register,
$tmp1$$Register, $tmp2$$Register,
$result$$Register, true /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
iRegIdst tmp1, iRegIdst tmp2, regCTR ctr, flagsRegCR0 cr0, flagsRegCR0 cr1) %{
predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(TEMP_DEF result, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0, KILL cr1);
ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ array_equals(true, $ary1$$Register, $ary2$$Register,
$tmp1$$Register, $tmp2$$Register,
$result$$Register, false /* byte */);
%}
ins_pipe(pipe_class_default);
%}
instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr;
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
ins_cost(150);
format %{ "String IndexOf CSCL1 $haystack[0..$haycnt], $needleImm+$offsetImm[0..$needlecntImm]"
"-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
immPOper *needleOper = (immPOper *)$needleImm;
const TypeOopPtr *t = needleOper->type()->isa_oopptr();
ciTypeArray* needle_values = t->const_oop()->as_type_array(); // Pointer to live char *
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr;
#ifdef VM_LITTLE_ENDIAN
chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else
chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, true /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
rscratch2RegP needle, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL needle, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
guarantee(needle_values, "sanity");
jchar chr = (jchar)needle_values->element_value(0).as_byte();
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
R0, chr,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
iRegIsrc ch, iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1, regCTR ctr) %{
match(Set result (StrIndexOfChar (Binary haystack haycnt) ch));
effect(TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1, KILL ctr);
predicate(CompactStrings);
ins_cost(180);
format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof_char($result$$Register,
$haystack$$Register, $haycnt$$Register,
$ch$$Register, 0 /* this is not used if the character is already in a register */,
$tmp1$$Register, $tmp2$$Register, false /*is_byte*/);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
iRegPsrc needle, uimmI15 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2, iRegIdst tmp3, iRegIdst tmp4, iRegIdst tmp5,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecntImm)));
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
// Required for EA: check if it is still a type_array.
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
" -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Node *ndl = in(operand_index($needle)); // The node that defines needle.
ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, needle_values, $tmp5$$Register, $needlecntImm$$constant,
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_compare);
%}
instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRegPsrc needle, rscratch2RegI needlecnt,
iRegLdst tmp1, iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4,
flagsRegCR0 cr0, flagsRegCR1 cr1, flagsRegCR6 cr6, regCTR ctr) %{
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary needle needlecnt)));
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6, KILL ctr);
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
ins_cost(300);
format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
" -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ string_indexof($result$$Register,
$haystack$$Register, $haycnt$$Register,
$needle$$Register, NULL, $needlecnt$$Register, 0, // needlecnt not constant.
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_compare);
%}
// char[] to byte[] compression
instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set result (StrCompressedCopy src (Binary dst len)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Lskip, Ldone;
__ li($result$$Register, 0);
__ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone);
__ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Lskip);
__ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone);
__ bind(Lskip);
__ mr($result$$Register, $len$$Register);
__ bind(Ldone);
%}
ins_pipe(pipe_class_default);
%}
// byte[] to char[] inflation
instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set dummy (StrInflatedCopy src (Binary dst len)));
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Ldone;
__ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
__ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Ldone);
__ string_inflate($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register);
__ bind(Ldone);
%}
ins_pipe(pipe_class_default);
%}
// StringCoding.java intrinsics
instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst tmp1, iRegLdst tmp2,
regCTR ctr, flagsRegCR0 cr0)
%{
match(Set result (HasNegatives ary1 len));
effect(TEMP_DEF result, USE_KILL ary1, TEMP tmp1, TEMP tmp2, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
$tmp1$$Register, $tmp2$$Register);
%}
ins_pipe(pipe_class_default);
%}
// encode char[] to byte[] in ISO_8859_1
instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst result, iRegLdst tmp1,
iRegLdst tmp2, iRegLdst tmp3, iRegLdst tmp4, iRegLdst tmp5, regCTR ctr, flagsRegCR0 cr0) %{
match(Set result (EncodeISOArray src (Binary dst len)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
USE_KILL src, USE_KILL dst, KILL ctr, KILL cr0);
ins_cost(300);
format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
Label Lslow, Lfailure1, Lfailure2, Ldone;
__ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
$tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
__ rldicl_($result$$Register, $len$$Register, 0, 64-3); // Remaining characters.
__ beq(CCR0, Ldone);
__ bind(Lslow);
__ string_compress($src$$Register, $dst$$Register, $result$$Register, $tmp2$$Register, Lfailure2);
__ li($result$$Register, 0);
__ b(Ldone);
__ bind(Lfailure1);
__ mr($result$$Register, $len$$Register);
__ mfctr($tmp1$$Register);
__ rldimi_($result$$Register, $tmp1$$Register, 3, 0); // Remaining characters.
__ beq(CCR0, Ldone);
__ b(Lslow);
__ bind(Lfailure2);
__ mfctr($result$$Register); // Remaining characters.
__ bind(Ldone);
__ subf($result$$Register, $result$$Register, $len$$Register);
%}
ins_pipe(pipe_class_default);
%}
// String_IndexOf for needle of length 1. // String_IndexOf for needle of length 1.
// //
// Match needle into immediate operands: no loadConP node needed. Saves one // Match needle into immediate operands: no loadConP node needed. Saves one
@ -11060,11 +11638,11 @@ instruct string_indexOf_imm1_char(iRegIdst result, iRegPsrc haystack, iRegIsrc h
if (java_lang_String::has_coder_field()) { if (java_lang_String::has_coder_field()) {
// New compact strings byte array strings // New compact strings byte array strings
#ifdef VM_LITTLE_ENDIAN #ifdef VM_LITTLE_ENDIAN
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) | chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
(jchar)needle_values->element_value(0).as_byte(); ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else #else
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) | chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
(jchar)needle_values->element_value(1).as_byte(); ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif #endif
} else { } else {
// Old char array strings // Old char array strings
@ -11115,11 +11693,11 @@ instruct string_indexOf_imm1(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
if (java_lang_String::has_coder_field()) { if (java_lang_String::has_coder_field()) {
// New compact strings byte array strings // New compact strings byte array strings
#ifdef VM_LITTLE_ENDIAN #ifdef VM_LITTLE_ENDIAN
chr = (((jchar)needle_values->element_value(1).as_byte()) << 8) | chr = (((jchar)(unsigned char)needle_values->element_value(1).as_byte()) << 8) |
(jchar)needle_values->element_value(0).as_byte(); ((jchar)(unsigned char)needle_values->element_value(0).as_byte());
#else #else
chr = (((jchar)needle_values->element_value(0).as_byte()) << 8) | chr = (((jchar)(unsigned char)needle_values->element_value(0).as_byte()) << 8) |
(jchar)needle_values->element_value(1).as_byte(); ((jchar)(unsigned char)needle_values->element_value(1).as_byte());
#endif #endif
} else { } else {
// Old char array strings // Old char array strings
@ -11321,6 +11899,20 @@ instruct minI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
%} %}
%} %}
instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set dst (MinI src1 src2));
effect(KILL cr0);
predicate(VM_Version::has_isel());
ins_cost(DEFAULT_COST*2);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ cmpw(CCR0, $src1$$Register, $src2$$Register);
__ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{ instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
match(Set dst (MaxI src1 src2)); match(Set dst (MaxI src1 src2));
ins_cost(DEFAULT_COST*6); ins_cost(DEFAULT_COST*6);
@ -11341,6 +11933,20 @@ instruct maxI_reg_reg_Ex(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
%} %}
%} %}
instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set dst (MaxI src1 src2));
effect(KILL cr0);
predicate(VM_Version::has_isel());
ins_cost(DEFAULT_COST*2);
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
__ cmpw(CCR0, $src1$$Register, $src2$$Register);
__ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
%}
ins_pipe(pipe_class_default);
%}
//---------- Population Count Instructions ------------------------------------ //---------- Population Count Instructions ------------------------------------
// Popcnt for Power7. // Popcnt for Power7.

View File

@ -2609,9 +2609,7 @@ class StubGenerator: public StubCodeGenerator {
* R5_ARG3 - int length (of buffer) * R5_ARG3 - int length (of buffer)
* *
* scratch: * scratch:
* R6_ARG4 - crc table address * R2, R6-R12
* R7_ARG5 - tmp1
* R8_ARG6 - tmp2
* *
* Ouput: * Ouput:
* R3_RET - int crc result * R3_RET - int crc result
@ -2623,22 +2621,25 @@ class StubGenerator: public StubCodeGenerator {
address start = __ function_entry(); // Remember stub start address (is rtn value). address start = __ function_entry(); // Remember stub start address (is rtn value).
// arguments to kernel_crc32: // arguments to kernel_crc32:
Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call. const Register crc = R3_ARG1; // Current checksum, preset by caller or result from previous call.
Register data = R4_ARG2; // source byte array const Register data = R4_ARG2; // source byte array
Register dataLen = R5_ARG3; // #bytes to process const Register dataLen = R5_ARG3; // #bytes to process
Register table = R6_ARG4; // crc table address const Register table = R6_ARG4; // crc table address
Register t0 = R9; // work reg for kernel* emitters const Register t0 = R2;
Register t1 = R10; // work reg for kernel* emitters const Register t1 = R7;
Register t2 = R11; // work reg for kernel* emitters const Register t2 = R8;
Register t3 = R12; // work reg for kernel* emitters const Register t3 = R9;
const Register tc0 = R10;
const Register tc1 = R11;
const Register tc2 = R12;
BLOCK_COMMENT("Stub body {"); BLOCK_COMMENT("Stub body {");
assert_different_registers(crc, data, dataLen, table); assert_different_registers(crc, data, dataLen, table);
StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table); StubRoutines::ppc64::generate_load_crc_table_addr(_masm, table);
__ kernel_crc32_1byte(crc, data, dataLen, table, t0, t1, t2, t3); __ kernel_crc32_1word(crc, data, dataLen, table, t0, t1, t2, t3, tc0, tc1, tc2, table);
BLOCK_COMMENT("return"); BLOCK_COMMENT("return");
__ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET). __ mr_if_needed(R3_RET, crc); // Updated crc is function result. No copying required (R3_ARG1 == R3_RET).

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -53,7 +53,7 @@ void VM_Version::initialize() {
// If PowerArchitecturePPC64 hasn't been specified explicitly determine from features. // If PowerArchitecturePPC64 hasn't been specified explicitly determine from features.
if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) { if (FLAG_IS_DEFAULT(PowerArchitecturePPC64)) {
if (VM_Version::has_tcheck() && VM_Version::has_lqarx()) { if (VM_Version::has_lqarx()) {
FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8); FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 8);
} else if (VM_Version::has_popcntw()) { } else if (VM_Version::has_popcntw()) {
FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7); FLAG_SET_ERGO(uintx, PowerArchitecturePPC64, 7);
@ -68,8 +68,7 @@ void VM_Version::initialize() {
bool PowerArchitecturePPC64_ok = false; bool PowerArchitecturePPC64_ok = false;
switch (PowerArchitecturePPC64) { switch (PowerArchitecturePPC64) {
case 8: if (!VM_Version::has_tcheck() ) break; case 8: if (!VM_Version::has_lqarx() ) break;
if (!VM_Version::has_lqarx() ) break;
case 7: if (!VM_Version::has_popcntw()) break; case 7: if (!VM_Version::has_popcntw()) break;
case 6: if (!VM_Version::has_cmpb() ) break; case 6: if (!VM_Version::has_cmpb() ) break;
case 5: if (!VM_Version::has_popcntb()) break; case 5: if (!VM_Version::has_popcntb()) break;
@ -80,7 +79,7 @@ void VM_Version::initialize() {
UINTX_FORMAT " on this machine", PowerArchitecturePPC64); UINTX_FORMAT " on this machine", PowerArchitecturePPC64);
// Power 8: Configure Data Stream Control Register. // Power 8: Configure Data Stream Control Register.
if (PowerArchitecturePPC64 >= 8) { if (has_mfdscr()) {
config_dscr(); config_dscr();
} }
@ -112,7 +111,7 @@ void VM_Version::initialize() {
// Create and print feature-string. // Create and print feature-string.
char buf[(num_features+1) * 16]; // Max 16 chars per feature. char buf[(num_features+1) * 16]; // Max 16 chars per feature.
jio_snprintf(buf, sizeof(buf), jio_snprintf(buf, sizeof(buf),
"ppc64%s%s%s%s%s%s%s%s%s%s%s%s", "ppc64%s%s%s%s%s%s%s%s%s%s%s%s%s",
(has_fsqrt() ? " fsqrt" : ""), (has_fsqrt() ? " fsqrt" : ""),
(has_isel() ? " isel" : ""), (has_isel() ? " isel" : ""),
(has_lxarxeh() ? " lxarxeh" : ""), (has_lxarxeh() ? " lxarxeh" : ""),
@ -125,7 +124,8 @@ void VM_Version::initialize() {
(has_lqarx() ? " lqarx" : ""), (has_lqarx() ? " lqarx" : ""),
(has_vcipher() ? " vcipher" : ""), (has_vcipher() ? " vcipher" : ""),
(has_vpmsumb() ? " vpmsumb" : ""), (has_vpmsumb() ? " vpmsumb" : ""),
(has_tcheck() ? " tcheck" : "") (has_tcheck() ? " tcheck" : ""),
(has_mfdscr() ? " mfdscr" : "")
// Make sure number of %s matches num_features! // Make sure number of %s matches num_features!
); );
_features_string = os::strdup(buf); _features_string = os::strdup(buf);
@ -610,6 +610,7 @@ void VM_Version::determine_features() {
a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher a->vcipher(VR0, VR1, VR2); // code[10] -> vcipher
a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb a->vpmsumb(VR0, VR1, VR2); // code[11] -> vpmsumb
a->tcheck(0); // code[12] -> tcheck a->tcheck(0); // code[12] -> tcheck
a->mfdscr(R0); // code[13] -> mfdscr
a->blr(); a->blr();
// Emit function to set one cache line to zero. Emit function descriptor and get pointer to it. // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
@ -657,6 +658,7 @@ void VM_Version::determine_features() {
if (code[feature_cntr++]) features |= vcipher_m; if (code[feature_cntr++]) features |= vcipher_m;
if (code[feature_cntr++]) features |= vpmsumb_m; if (code[feature_cntr++]) features |= vpmsumb_m;
if (code[feature_cntr++]) features |= tcheck_m; if (code[feature_cntr++]) features |= tcheck_m;
if (code[feature_cntr++]) features |= mfdscr_m;
// Print the detection code. // Print the detection code.
if (PrintAssembly) { if (PrintAssembly) {
@ -670,8 +672,6 @@ void VM_Version::determine_features() {
// Power 8: Configure Data Stream Control Register. // Power 8: Configure Data Stream Control Register.
void VM_Version::config_dscr() { void VM_Version::config_dscr() {
assert(has_tcheck(), "Only execute on Power 8 or later!");
// 7 InstWords for each call (function descriptor + blr instruction). // 7 InstWords for each call (function descriptor + blr instruction).
const int code_size = (2+2*7)*BytesPerInstWord; const int code_size = (2+2*7)*BytesPerInstWord;

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -45,6 +45,7 @@ protected:
vcipher, vcipher,
vpmsumb, vpmsumb,
tcheck, tcheck,
mfdscr,
num_features // last entry to count features num_features // last entry to count features
}; };
enum Feature_Flag_Set { enum Feature_Flag_Set {
@ -62,6 +63,7 @@ protected:
vcipher_m = (1 << vcipher), vcipher_m = (1 << vcipher),
vpmsumb_m = (1 << vpmsumb), vpmsumb_m = (1 << vpmsumb),
tcheck_m = (1 << tcheck ), tcheck_m = (1 << tcheck ),
mfdscr_m = (1 << mfdscr ),
all_features_m = (unsigned long)-1 all_features_m = (unsigned long)-1
}; };
@ -94,6 +96,7 @@ public:
static bool has_vcipher() { return (_features & vcipher_m) != 0; } static bool has_vcipher() { return (_features & vcipher_m) != 0; }
static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; } static bool has_vpmsumb() { return (_features & vpmsumb_m) != 0; }
static bool has_tcheck() { return (_features & tcheck_m) != 0; } static bool has_tcheck() { return (_features & tcheck_m) != 0; }
static bool has_mfdscr() { return (_features & mfdscr_m) != 0; }
// Assembler testing // Assembler testing
static void allow_all(); static void allow_all();

View File

@ -1349,9 +1349,12 @@ static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
} }
} else if (dst.first()->is_stack()) { } else if (dst.first()->is_stack()) {
// reg to stack // reg to stack
__ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS); // Some compilers (gcc) expect a clean 32 bit value on function entry
__ signx(src.first()->as_Register(), L5);
__ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS);
} else { } else {
__ mov(src.first()->as_Register(), dst.first()->as_Register()); // Some compilers (gcc) expect a clean 32 bit value on function entry
__ signx(src.first()->as_Register(), dst.first()->as_Register());
} }
} }

View File

@ -948,28 +948,28 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, PhaseRegAlloc* ra, const MachNode* n,
} }
#endif #endif
uint instr; uint instr = (Assembler::ldst_op << 30)
instr = (Assembler::ldst_op << 30) | (dst_enc << 25)
| (dst_enc << 25) | (primary << 19)
| (primary << 19) | (src1_enc << 14);
| (src1_enc << 14);
uint index = src2_enc; uint index = src2_enc;
int disp = disp32; int disp = disp32;
if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) { if (src1_enc == R_SP_enc || src1_enc == R_FP_enc) {
disp += STACK_BIAS; disp += STACK_BIAS;
// Quick fix for JDK-8029668: check that stack offset fits, bailout if not // Check that stack offset fits, load into O7 if not
if (!Assembler::is_simm13(disp)) { if (!Assembler::is_simm13(disp)) {
ra->C->record_method_not_compilable("unable to handle large constant offsets"); MacroAssembler _masm(&cbuf);
return; __ set(disp, O7);
if (index != R_G0_enc) {
__ add(O7, reg_to_register_object(index), O7);
}
index = R_O7_enc;
disp = 0;
} }
} }
// We should have a compiler bailout here rather than a guarantee.
// Better yet would be some mechanism to handle variable-size matches correctly.
guarantee(Assembler::is_simm13(disp), "Do not match large constant offsets" );
if( disp == 0 ) { if( disp == 0 ) {
// use reg-reg form // use reg-reg form
// bit 13 is already zero // bit 13 is already zero
@ -983,7 +983,7 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, PhaseRegAlloc* ra, const MachNode* n,
cbuf.insts()->emit_int32(instr); cbuf.insts()->emit_int32(instr);
#ifdef ASSERT #ifdef ASSERT
{ if (VerifyOops) {
MacroAssembler _masm(&cbuf); MacroAssembler _masm(&cbuf);
if (is_verified_oop_base) { if (is_verified_oop_base) {
__ verify_oop(reg_to_register_object(src1_enc)); __ verify_oop(reg_to_register_object(src1_enc));
@ -1342,7 +1342,7 @@ int MachEpilogNode::safepoint_offset() const {
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
enum RC { rc_bad, rc_int, rc_float, rc_stack }; enum RC { rc_bad, rc_int, rc_float, rc_stack };
static enum RC rc_class( OptoReg::Name reg ) { static enum RC rc_class( OptoReg::Name reg ) {
if( !OptoReg::is_valid(reg) ) return rc_bad; if (!OptoReg::is_valid(reg)) return rc_bad;
if (OptoReg::is_stack(reg)) return rc_stack; if (OptoReg::is_stack(reg)) return rc_stack;
VMReg r = OptoReg::as_VMReg(reg); VMReg r = OptoReg::as_VMReg(reg);
if (r->is_Register()) return rc_int; if (r->is_Register()) return rc_int;
@ -1350,66 +1350,79 @@ static enum RC rc_class( OptoReg::Name reg ) {
return rc_float; return rc_float;
} }
static int impl_helper(const MachNode* mach, CodeBuffer* cbuf, PhaseRegAlloc* ra, bool do_size, bool is_load, int offset, int reg, int opcode, const char *op_str, int size, outputStream* st ) { #ifndef PRODUCT
ATTRIBUTE_PRINTF(2, 3)
static void print_helper(outputStream* st, const char* format, ...) {
if (st->position() > 0) {
st->cr();
st->sp();
}
va_list ap;
va_start(ap, format);
st->vprint(format, ap);
va_end(ap);
}
#endif // !PRODUCT
static void impl_helper(const MachNode* mach, CodeBuffer* cbuf, PhaseRegAlloc* ra, bool is_load, int offset, int reg, int opcode, const char *op_str, outputStream* st) {
if (cbuf) { if (cbuf) {
emit_form3_mem_reg(*cbuf, ra, mach, opcode, -1, R_SP_enc, offset, 0, Matcher::_regEncode[reg]); emit_form3_mem_reg(*cbuf, ra, mach, opcode, -1, R_SP_enc, offset, 0, Matcher::_regEncode[reg]);
} }
#ifndef PRODUCT #ifndef PRODUCT
else if (!do_size) { else {
if (size != 0) st->print("\n\t"); if (is_load) {
if (is_load) st->print("%s [R_SP + #%d],R_%s\t! spill",op_str,offset,OptoReg::regname(reg)); print_helper(st, "%s [R_SP + #%d],R_%s\t! spill", op_str, offset, OptoReg::regname(reg));
else st->print("%s R_%s,[R_SP + #%d]\t! spill",op_str,OptoReg::regname(reg),offset); } else {
print_helper(st, "%s R_%s,[R_SP + #%d]\t! spill", op_str, OptoReg::regname(reg), offset);
}
} }
#endif #endif
return size+4;
} }
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int op1, int op2, const char *op_str, int size, outputStream* st ) { static void impl_mov_helper(CodeBuffer *cbuf, int src, int dst, int op1, int op2, const char *op_str, outputStream* st) {
if( cbuf ) emit3( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src] ); if (cbuf) {
emit3(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst], op1, 0, op2, Matcher::_regEncode[src]);
}
#ifndef PRODUCT #ifndef PRODUCT
else if( !do_size ) { else {
if( size != 0 ) st->print("\n\t"); print_helper(st, "%s R_%s,R_%s\t! spill", op_str, OptoReg::regname(src), OptoReg::regname(dst));
st->print("%s R_%s,R_%s\t! spill",op_str,OptoReg::regname(src),OptoReg::regname(dst));
} }
#endif #endif
return size+4;
} }
uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, static void mach_spill_copy_implementation_helper(const MachNode* mach,
PhaseRegAlloc *ra_, CodeBuffer *cbuf,
bool do_size, PhaseRegAlloc *ra_,
outputStream* st ) const { outputStream* st) {
// Get registers to move // Get registers to move
OptoReg::Name src_second = ra_->get_reg_second(in(1)); OptoReg::Name src_second = ra_->get_reg_second(mach->in(1));
OptoReg::Name src_first = ra_->get_reg_first(in(1)); OptoReg::Name src_first = ra_->get_reg_first(mach->in(1));
OptoReg::Name dst_second = ra_->get_reg_second(this ); OptoReg::Name dst_second = ra_->get_reg_second(mach);
OptoReg::Name dst_first = ra_->get_reg_first(this ); OptoReg::Name dst_first = ra_->get_reg_first(mach);
enum RC src_second_rc = rc_class(src_second); enum RC src_second_rc = rc_class(src_second);
enum RC src_first_rc = rc_class(src_first); enum RC src_first_rc = rc_class(src_first);
enum RC dst_second_rc = rc_class(dst_second); enum RC dst_second_rc = rc_class(dst_second);
enum RC dst_first_rc = rc_class(dst_first); enum RC dst_first_rc = rc_class(dst_first);
assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" ); assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register");
// Generate spill code! if (src_first == dst_first && src_second == dst_second) {
int size = 0; return; // Self copy, no move
}
if( src_first == dst_first && src_second == dst_second )
return size; // Self copy, no move
// -------------------------------------- // --------------------------------------
// Check for mem-mem move. Load into unused float registers and fall into // Check for mem-mem move. Load into unused float registers and fall into
// the float-store case. // the float-store case.
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { if (src_first_rc == rc_stack && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first); int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load // Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second ) { if ((src_first&1) == 0 && src_first+1 == src_second) {
src_second = OptoReg::Name(R_F31_num); src_second = OptoReg::Name(R_F31_num);
src_second_rc = rc_float; src_second_rc = rc_float;
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::lddf_op3,"LDDF",size, st); impl_helper(mach, cbuf, ra_, true, offset, R_F30_num, Assembler::lddf_op3, "LDDF", st);
} else { } else {
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F30_num,Assembler::ldf_op3 ,"LDF ",size, st); impl_helper(mach, cbuf, ra_, true, offset, R_F30_num, Assembler::ldf_op3, "LDF ", st);
} }
src_first = OptoReg::Name(R_F30_num); src_first = OptoReg::Name(R_F30_num);
src_first_rc = rc_float; src_first_rc = rc_float;
@ -1417,7 +1430,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) {
int offset = ra_->reg2offset(src_second); int offset = ra_->reg2offset(src_second);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,R_F31_num,Assembler::ldf_op3,"LDF ",size, st); impl_helper(mach, cbuf, ra_, true, offset, R_F31_num, Assembler::ldf_op3, "LDF ", st);
src_second = OptoReg::Name(R_F31_num); src_second = OptoReg::Name(R_F31_num);
src_second_rc = rc_float; src_second_rc = rc_float;
} }
@ -1427,36 +1440,38 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) { if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS < 3) {
int offset = frame::register_save_words*wordSize; int offset = frame::register_save_words*wordSize;
if (cbuf) { if (cbuf) {
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16 ); emit3_simm13(*cbuf, Assembler::arith_op, R_SP_enc, Assembler::sub_op3, R_SP_enc, 16);
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
emit3_simm13( *cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16 ); emit3_simm13(*cbuf, Assembler::arith_op, R_SP_enc, Assembler::add_op3, R_SP_enc, 16);
} }
#ifndef PRODUCT #ifndef PRODUCT
else if (!do_size) { else {
if (size != 0) st->print("\n\t"); print_helper(st, "SUB R_SP,16,R_SP");
st->print( "SUB R_SP,16,R_SP\n"); impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
impl_helper(this,cbuf,ra_,do_size,true ,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); print_helper(st, "ADD R_SP,16,R_SP");
st->print("\tADD R_SP,16,R_SP\n");
} }
#endif #endif
size += 16;
} }
// Check for float->int copy on T4 // Check for float->int copy on T4
if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) { if (src_first_rc == rc_float && dst_first_rc == rc_int && UseVIS >= 3) {
// Further check for aligned-adjacent pair, so we can use a double move // Further check for aligned-adjacent pair, so we can use a double move
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mdtox_opf,"MOVDTOX",size, st); impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mdtox_opf, "MOVDTOX", st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mstouw_opf,"MOVSTOUW",size, st); return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mstouw_opf, "MOVSTOUW", st);
} }
// Check for int->float copy on T4 // Check for int->float copy on T4
if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) { if (src_first_rc == rc_int && dst_first_rc == rc_float && UseVIS >= 3) {
// Further check for aligned-adjacent pair, so we can use a double move // Further check for aligned-adjacent pair, so we can use a double move
if ((src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mxtod_opf,"MOVXTOD",size, st); impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mxtod_opf, "MOVXTOD", st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::mftoi_op3,Assembler::mwtos_opf,"MOVWTOS",size, st); return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::mftoi_op3, Assembler::mwtos_opf, "MOVWTOS", st);
} }
// -------------------------------------- // --------------------------------------
@ -1466,10 +1481,10 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// there. Misaligned sources only come from native-long-returns (handled // there. Misaligned sources only come from native-long-returns (handled
// special below). // special below).
#ifndef _LP64 #ifndef _LP64
if( src_first_rc == rc_int && // source is already big-endian if (src_first_rc == rc_int && // source is already big-endian
src_second_rc != rc_bad && // 64-bit move src_second_rc != rc_bad && // 64-bit move
((dst_first&1)!=0 || dst_second != dst_first+1) ) { // misaligned dst ((dst_first & 1) != 0 || dst_second != dst_first + 1)) { // misaligned dst
assert( (src_first&1)==0 && src_second == src_first+1, "source must be aligned" ); assert((src_first & 1) == 0 && src_second == src_first + 1, "source must be aligned");
// Do the big-endian flop. // Do the big-endian flop.
OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ; OptoReg::Name tmp = dst_first ; dst_first = dst_second ; dst_second = tmp ;
enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc; enum RC tmp_rc = dst_first_rc; dst_first_rc = dst_second_rc; dst_second_rc = tmp_rc;
@ -1478,30 +1493,28 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// -------------------------------------- // --------------------------------------
// Check for integer reg-reg copy // Check for integer reg-reg copy
if( src_first_rc == rc_int && dst_first_rc == rc_int ) { if (src_first_rc == rc_int && dst_first_rc == rc_int) {
#ifndef _LP64 #ifndef _LP64
if( src_first == R_O0_num && src_second == R_O1_num ) { // Check for the evil O0/O1 native long-return case if (src_first == R_O0_num && src_second == R_O1_num) { // Check for the evil O0/O1 native long-return case
// Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
// as stored in memory. On a big-endian machine like SPARC, this means that the _second // as stored in memory. On a big-endian machine like SPARC, this means that the _second
// operand contains the least significant word of the 64-bit value and vice versa. // operand contains the least significant word of the 64-bit value and vice versa.
OptoReg::Name tmp = OptoReg::Name(R_O7_num); OptoReg::Name tmp = OptoReg::Name(R_O7_num);
assert( (dst_first&1)==0 && dst_second == dst_first+1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" ); assert((dst_first & 1) == 0 && dst_second == dst_first + 1, "return a native O0/O1 long to an aligned-adjacent 64-bit reg" );
// Shift O0 left in-place, zero-extend O1, then OR them into the dst // Shift O0 left in-place, zero-extend O1, then OR them into the dst
if( cbuf ) { if ( cbuf ) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tmp], Assembler::sllx_op3, Matcher::_regEncode[src_first], 0x1020);
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[src_second], Assembler::srl_op3, Matcher::_regEncode[src_second], 0x0000);
emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second] ); emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler:: or_op3, Matcher::_regEncode[tmp], 0, Matcher::_regEncode[src_second]);
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else {
if( size != 0 ) st->print("\n\t"); print_helper(st, "SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp));
st->print("SLLX R_%s,32,R_%s\t! Move O0-first to O7-high\n\t", OptoReg::regname(src_first), OptoReg::regname(tmp)); print_helper(st, "SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second));
st->print("SRL R_%s, 0,R_%s\t! Zero-extend O1\n\t", OptoReg::regname(src_second), OptoReg::regname(src_second)); print_helper(st, "OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first));
st->print("OR R_%s,R_%s,R_%s\t! spill",OptoReg::regname(tmp), OptoReg::regname(src_second), OptoReg::regname(dst_first));
#endif #endif
} }
return size+12; return;
} } else if (dst_first == R_I0_num && dst_second == R_I1_num) {
else if( dst_first == R_I0_num && dst_second == R_I1_num ) {
// returning a long value in I0/I1 // returning a long value in I0/I1
// a SpillCopy must be able to target a return instruction's reg_class // a SpillCopy must be able to target a return instruction's reg_class
// Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value // Note: The _first and _second suffixes refer to the addresses of the the 2 halves of the 64-bit value
@ -1511,27 +1524,25 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
if (src_first == dst_first) { if (src_first == dst_first) {
tdest = OptoReg::Name(R_O7_num); tdest = OptoReg::Name(R_O7_num);
size += 4;
} }
if( cbuf ) { if (cbuf) {
assert( (src_first&1) == 0 && (src_first+1) == src_second, "return value was in an aligned-adjacent 64-bit reg"); assert((src_first & 1) == 0 && (src_first + 1) == src_second, "return value was in an aligned-adjacent 64-bit reg");
// Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1 // Shift value in upper 32-bits of src to lower 32-bits of I0; move lower 32-bits to I1
// ShrL_reg_imm6 // ShrL_reg_imm6
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[tdest], Assembler::srlx_op3, Matcher::_regEncode[src_second], 32 | 0x1000);
// ShrR_reg_imm6 src, 0, dst // ShrR_reg_imm6 src, 0, dst
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srl_op3, Matcher::_regEncode[src_first], 0x0000);
if (tdest != dst_first) { if (tdest != dst_first) {
emit3 ( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest] ); emit3 (*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_first], Assembler::or_op3, 0/*G0*/, 0/*op2*/, Matcher::_regEncode[tdest]);
} }
} }
#ifndef PRODUCT #ifndef PRODUCT
else if( !do_size ) { else {
if( size != 0 ) st->print("\n\t"); // %%%%% !!!!! print_helper(st, "SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest));
st->print("SRLX R_%s,32,R_%s\t! Extract MSW\n\t",OptoReg::regname(src_second),OptoReg::regname(tdest)); print_helper(st, "SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second));
st->print("SRL R_%s, 0,R_%s\t! Extract LSW\n\t",OptoReg::regname(src_first),OptoReg::regname(dst_second));
if (tdest != dst_first) { if (tdest != dst_first) {
st->print("MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first)); print_helper(st, "MOV R_%s,R_%s\t! spill\n\t", OptoReg::regname(tdest), OptoReg::regname(dst_first));
} }
} }
#endif // PRODUCT #endif // PRODUCT
@ -1539,65 +1550,77 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
} }
#endif // !_LP64 #endif // !_LP64
// Else normal reg-reg copy // Else normal reg-reg copy
assert( src_second != dst_first, "smashed second before evacuating it" ); assert(src_second != dst_first, "smashed second before evacuating it");
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::or_op3,0,"MOV ",size, st); impl_mov_helper(cbuf, src_first, dst_first, Assembler::or_op3, 0, "MOV ", st);
assert( (src_first&1) == 0 && (dst_first&1) == 0, "never move second-halves of int registers" ); assert((src_first & 1) == 0 && (dst_first & 1) == 0, "never move second-halves of int registers");
// This moves an aligned adjacent pair. // This moves an aligned adjacent pair.
// See if we are done. // See if we are done.
if( src_first+1 == src_second && dst_first+1 == dst_second ) if (src_first + 1 == src_second && dst_first + 1 == dst_second) {
return size; return;
}
} }
// Check for integer store // Check for integer store
if( src_first_rc == rc_int && dst_first_rc == rc_stack ) { if (src_first_rc == rc_int && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(dst_first); int offset = ra_->reg2offset(dst_first);
// Further check for aligned-adjacent pair, so we can use a double store // Further check for aligned-adjacent pair, so we can use a double store
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stx_op3,"STX ",size, st); impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stx_op3, "STX ", st);
size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stw_op3,"STW ",size, st); return;
}
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stw_op3, "STW ", st);
} }
// Check for integer load // Check for integer load
if( dst_first_rc == rc_int && src_first_rc == rc_stack ) { if (dst_first_rc == rc_int && src_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first); int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load // Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldx_op3 ,"LDX ",size, st); impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::ldx_op3, "LDX ", st);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lduw_op3,"LDUW",size, st); return;
}
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lduw_op3, "LDUW", st);
} }
// Check for float reg-reg copy // Check for float reg-reg copy
if( src_first_rc == rc_float && dst_first_rc == rc_float ) { if (src_first_rc == rc_float && dst_first_rc == rc_float) {
// Further check for aligned-adjacent pair, so we can use a double move // Further check for aligned-adjacent pair, so we can use a double move
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovd_opf,"FMOVD",size, st); impl_mov_helper(cbuf, src_first, dst_first, Assembler::fpop1_op3, Assembler::fmovd_opf, "FMOVD", st);
size = impl_mov_helper(cbuf,do_size,src_first,dst_first,Assembler::fpop1_op3,Assembler::fmovs_opf,"FMOVS",size, st); return;
}
impl_mov_helper(cbuf, src_first, dst_first, Assembler::fpop1_op3, Assembler::fmovs_opf, "FMOVS", st);
} }
// Check for float store // Check for float store
if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { if (src_first_rc == rc_float && dst_first_rc == rc_stack) {
int offset = ra_->reg2offset(dst_first); int offset = ra_->reg2offset(dst_first);
// Further check for aligned-adjacent pair, so we can use a double store // Further check for aligned-adjacent pair, so we can use a double store
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stdf_op3,"STDF",size, st); impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stdf_op3, "STDF", st);
size = impl_helper(this,cbuf,ra_,do_size,false,offset,src_first,Assembler::stf_op3 ,"STF ",size, st); return;
}
impl_helper(mach, cbuf, ra_, false, offset, src_first, Assembler::stf_op3, "STF ", st);
} }
// Check for float load // Check for float load
if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { if (dst_first_rc == rc_float && src_first_rc == rc_stack) {
int offset = ra_->reg2offset(src_first); int offset = ra_->reg2offset(src_first);
// Further check for aligned-adjacent pair, so we can use a double load // Further check for aligned-adjacent pair, so we can use a double load
if( (src_first&1)==0 && src_first+1 == src_second && (dst_first&1)==0 && dst_first+1 == dst_second ) if ((src_first & 1) == 0 && src_first + 1 == src_second && (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
return impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::lddf_op3,"LDDF",size, st); impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::lddf_op3, "LDDF", st);
size = impl_helper(this,cbuf,ra_,do_size,true,offset,dst_first,Assembler::ldf_op3 ,"LDF ",size, st); return;
}
impl_helper(mach, cbuf, ra_, true, offset, dst_first, Assembler::ldf_op3, "LDF ", st);
} }
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Check for hi bits still needing moving. Only happens for misaligned // Check for hi bits still needing moving. Only happens for misaligned
// arguments to native calls. // arguments to native calls.
if( src_second == dst_second ) if (src_second == dst_second) {
return size; // Self copy; no move return; // Self copy; no move
assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); }
assert(src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad");
#ifndef _LP64 #ifndef _LP64
// In the LP64 build, all registers can be moved as aligned/adjacent // In the LP64 build, all registers can be moved as aligned/adjacent
@ -1609,52 +1632,57 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf,
// 32-bits of a 64-bit register, but are needed in low bits of another // 32-bits of a 64-bit register, but are needed in low bits of another
// register (else it's a hi-bits-to-hi-bits copy which should have // register (else it's a hi-bits-to-hi-bits copy which should have
// happened already as part of a 64-bit move) // happened already as part of a 64-bit move)
if( src_second_rc == rc_int && dst_second_rc == rc_int ) { if (src_second_rc == rc_int && dst_second_rc == rc_int) {
assert( (src_second&1)==1, "its the evil O0/O1 native return case" ); assert((src_second & 1) == 1, "its the evil O0/O1 native return case");
assert( (dst_second&1)==0, "should have moved with 1 64-bit move" ); assert((dst_second & 1) == 0, "should have moved with 1 64-bit move");
// Shift src_second down to dst_second's low bits. // Shift src_second down to dst_second's low bits.
if( cbuf ) { if (cbuf) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[dst_second], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else {
if( size != 0 ) st->print("\n\t"); print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second - 1), OptoReg::regname(dst_second));
st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(dst_second));
#endif #endif
} }
return size+4; return;
} }
// Check for high word integer store. Must down-shift the hi bits // Check for high word integer store. Must down-shift the hi bits
// into a temp register, then fall into the case of storing int bits. // into a temp register, then fall into the case of storing int bits.
if( src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second&1)==1 ) { if (src_second_rc == rc_int && dst_second_rc == rc_stack && (src_second & 1) == 1) {
// Shift src_second down to dst_second's low bits. // Shift src_second down to dst_second's low bits.
if( cbuf ) { if (cbuf) {
emit3_simm13( *cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020 ); emit3_simm13(*cbuf, Assembler::arith_op, Matcher::_regEncode[R_O7_num], Assembler::srlx_op3, Matcher::_regEncode[src_second-1], 0x1020);
#ifndef PRODUCT #ifndef PRODUCT
} else if( !do_size ) { } else {
if( size != 0 ) st->print("\n\t"); print_helper(st, "SRLX R_%s,32,R_%s\t! spill: Move high bits down low", OptoReg::regname(src_second-1), OptoReg::regname(R_O7_num));
st->print("SRLX R_%s,32,R_%s\t! spill: Move high bits down low",OptoReg::regname(src_second-1),OptoReg::regname(R_O7_num));
#endif #endif
} }
size+=4;
src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num! src_second = OptoReg::Name(R_O7_num); // Not R_O7H_num!
} }
// Check for high word integer load // Check for high word integer load
if( dst_second_rc == rc_int && src_second_rc == rc_stack ) if (dst_second_rc == rc_int && src_second_rc == rc_stack)
return impl_helper(this,cbuf,ra_,do_size,true ,ra_->reg2offset(src_second),dst_second,Assembler::lduw_op3,"LDUW",size, st); return impl_helper(this, cbuf, ra_, true, ra_->reg2offset(src_second), dst_second, Assembler::lduw_op3, "LDUW", size, st);
// Check for high word integer store // Check for high word integer store
if( src_second_rc == rc_int && dst_second_rc == rc_stack ) if (src_second_rc == rc_int && dst_second_rc == rc_stack)
return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stw_op3 ,"STW ",size, st); return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stw_op3, "STW ", size, st);
// Check for high word float store // Check for high word float store
if( src_second_rc == rc_float && dst_second_rc == rc_stack ) if (src_second_rc == rc_float && dst_second_rc == rc_stack)
return impl_helper(this,cbuf,ra_,do_size,false,ra_->reg2offset(dst_second),src_second,Assembler::stf_op3 ,"STF ",size, st); return impl_helper(this, cbuf, ra_, false, ra_->reg2offset(dst_second), src_second, Assembler::stf_op3, "STF ", size, st);
#endif // !_LP64 #endif // !_LP64
Unimplemented(); Unimplemented();
}
uint MachSpillCopyNode::implementation(CodeBuffer *cbuf,
PhaseRegAlloc *ra_,
bool do_size,
outputStream* st) const {
assert(!do_size, "not supported");
mach_spill_copy_implementation_helper(this, cbuf, ra_, st);
return 0; return 0;
} }
@ -1669,19 +1697,19 @@ void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
} }
uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
return implementation( NULL, ra_, true, NULL ); return MachNode::size(ra_);
} }
//============================================================================= //=============================================================================
#ifndef PRODUCT #ifndef PRODUCT
void MachNopNode::format( PhaseRegAlloc *, outputStream *st ) const { void MachNopNode::format(PhaseRegAlloc *, outputStream *st) const {
st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count); st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
} }
#endif #endif
void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const { void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const {
MacroAssembler _masm(&cbuf); MacroAssembler _masm(&cbuf);
for(int i = 0; i < _count; i += 1) { for (int i = 0; i < _count; i += 1) {
__ nop(); __ nop();
} }
} }
@ -5197,7 +5225,6 @@ instruct stkI_to_regF(regF dst, stackSlotI src) %{
// No match rule to avoid chain rule match. // No match rule to avoid chain rule match.
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! stkI to regF" %} format %{ "LDF $src,$dst\t! stkI to regF" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
@ -5208,7 +5235,6 @@ instruct stkL_to_regD(regD dst, stackSlotL src) %{
// No match rule to avoid chain rule match. // No match rule to avoid chain rule match.
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! stkL to regD" %} format %{ "LDDF $src,$dst\t! stkL to regD" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
@ -5219,7 +5245,6 @@ instruct regF_to_stkI(stackSlotI dst, regF src) %{
// No match rule to avoid chain rule match. // No match rule to avoid chain rule match.
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t! regF to stkI" %} format %{ "STF $src,$dst\t! regF to stkI" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
@ -5230,7 +5255,6 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
// No match rule to avoid chain rule match. // No match rule to avoid chain rule match.
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t! regD to stkL" %} format %{ "STDF $src,$dst\t! regD to stkL" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
@ -5240,7 +5264,6 @@ instruct regD_to_stkL(stackSlotL dst, regD src) %{
instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{ instruct regI_to_stkLHi(stackSlotL dst, iRegI src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST*2); ins_cost(MEMORY_REF_COST*2);
size(8);
format %{ "STW $src,$dst.hi\t! long\n\t" format %{ "STW $src,$dst.hi\t! long\n\t"
"STW R_G0,$dst.lo" %} "STW R_G0,$dst.lo" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
@ -5252,7 +5275,6 @@ instruct regL_to_stkD(stackSlotD dst, iRegL src) %{
// No match rule to avoid chain rule match. // No match rule to avoid chain rule match.
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! regL to stkD" %} format %{ "STX $src,$dst\t! regL to stkD" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5266,7 +5288,6 @@ instruct stkI_to_regI( iRegI dst, stackSlotI src ) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t!stk" %} format %{ "LDUW $src,$dst\t!stk" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5278,7 +5299,6 @@ instruct regI_to_stkI( stackSlotI dst, iRegI src ) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t!stk" %} format %{ "STW $src,$dst\t!stk" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5290,7 +5310,6 @@ instruct stkL_to_regL( iRegL dst, stackSlotL src ) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! long" %} format %{ "LDX $src,$dst\t! long" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5302,7 +5321,6 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! long" %} format %{ "STX $src,$dst\t! long" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5314,7 +5332,6 @@ instruct regL_to_stkL(stackSlotL dst, iRegL src) %{
instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t!ptr" %} format %{ "LDX $src,$dst\t!ptr" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
@ -5325,7 +5342,6 @@ instruct stkP_to_regP( iRegP dst, stackSlotP src ) %{
instruct regP_to_stkP(stackSlotP dst, iRegP src) %{ instruct regP_to_stkP(stackSlotP dst, iRegP src) %{
match(Set dst src); match(Set dst src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t!ptr" %} format %{ "STX $src,$dst\t!ptr" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -5771,7 +5787,6 @@ instruct loadL_unaligned(iRegL dst, memory mem, o7RegI tmp) %{
match(Set dst (LoadL_unaligned mem)); match(Set dst (LoadL_unaligned mem));
effect(KILL tmp); effect(KILL tmp);
ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
size(16);
format %{ "LDUW $mem+4,R_O7\t! misaligned long\n" format %{ "LDUW $mem+4,R_O7\t! misaligned long\n"
"\tLDUW $mem ,$dst\n" "\tLDUW $mem ,$dst\n"
"\tSLLX #32, $dst, $dst\n" "\tSLLX #32, $dst, $dst\n"
@ -5786,7 +5801,6 @@ instruct loadRange(iRegI dst, memory mem) %{
match(Set dst (LoadRange mem)); match(Set dst (LoadRange mem));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $mem,$dst\t! range" %} format %{ "LDUW $mem,$dst\t! range" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -5797,7 +5811,6 @@ instruct loadRange(iRegI dst, memory mem) %{
instruct loadI_freg(regF dst, memory mem) %{ instruct loadI_freg(regF dst, memory mem) %{
match(Set dst (LoadI mem)); match(Set dst (LoadI mem));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst\t! for fitos/fitod" %} format %{ "LDF $mem,$dst\t! for fitos/fitod" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
@ -5876,7 +5889,6 @@ instruct loadD(regD dst, memory mem) %{
match(Set dst (LoadD mem)); match(Set dst (LoadD mem));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $mem,$dst" %} format %{ "LDDF $mem,$dst" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -5887,7 +5899,6 @@ instruct loadD(regD dst, memory mem) %{
instruct loadD_unaligned(regD_low dst, memory mem ) %{ instruct loadD_unaligned(regD_low dst, memory mem ) %{
match(Set dst (LoadD_unaligned mem)); match(Set dst (LoadD_unaligned mem));
ins_cost(MEMORY_REF_COST*2+DEFAULT_COST); ins_cost(MEMORY_REF_COST*2+DEFAULT_COST);
size(8);
format %{ "LDF $mem ,$dst.hi\t! misaligned double\n" format %{ "LDF $mem ,$dst.hi\t! misaligned double\n"
"\tLDF $mem+4,$dst.lo\t!" %} "\tLDF $mem+4,$dst.lo\t!" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
@ -5900,7 +5911,6 @@ instruct loadF(regF dst, memory mem) %{
match(Set dst (LoadF mem)); match(Set dst (LoadF mem));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $mem,$dst" %} format %{ "LDF $mem,$dst" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg( mem, dst ) ); ins_encode(simple_form3_mem_reg( mem, dst ) );
@ -6119,7 +6129,6 @@ instruct prefetchAlloc( memory mem ) %{
predicate(AllocatePrefetchInstr == 0); predicate(AllocatePrefetchInstr == 0);
match( PrefetchAllocation mem ); match( PrefetchAllocation mem );
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "PREFETCH $mem,2\t! Prefetch allocation" %} format %{ "PREFETCH $mem,2\t! Prefetch allocation" %}
opcode(Assembler::prefetch_op3); opcode(Assembler::prefetch_op3);
@ -6175,7 +6184,6 @@ instruct storeB(memory mem, iRegI src) %{
match(Set mem (StoreB mem src)); match(Set mem (StoreB mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %} format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3); opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6186,7 +6194,6 @@ instruct storeB0(memory mem, immI0 src) %{
match(Set mem (StoreB mem src)); match(Set mem (StoreB mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! byte" %} format %{ "STB $src,$mem\t! byte" %}
opcode(Assembler::stb_op3); opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6197,7 +6204,6 @@ instruct storeCM0(memory mem, immI0 src) %{
match(Set mem (StoreCM mem src)); match(Set mem (StoreCM mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STB $src,$mem\t! CMS card-mark byte 0" %} format %{ "STB $src,$mem\t! CMS card-mark byte 0" %}
opcode(Assembler::stb_op3); opcode(Assembler::stb_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6209,7 +6215,6 @@ instruct storeC(memory mem, iRegI src) %{
match(Set mem (StoreC mem src)); match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %} format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3); opcode(Assembler::sth_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6220,7 +6225,6 @@ instruct storeC0(memory mem, immI0 src) %{
match(Set mem (StoreC mem src)); match(Set mem (StoreC mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STH $src,$mem\t! short" %} format %{ "STH $src,$mem\t! short" %}
opcode(Assembler::sth_op3); opcode(Assembler::sth_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6232,7 +6236,6 @@ instruct storeI(memory mem, iRegI src) %{
match(Set mem (StoreI mem src)); match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %} format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6243,7 +6246,6 @@ instruct storeI(memory mem, iRegI src) %{
instruct storeL(memory mem, iRegL src) %{ instruct storeL(memory mem, iRegL src) %{
match(Set mem (StoreL mem src)); match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem\t! long" %} format %{ "STX $src,$mem\t! long" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6254,7 +6256,6 @@ instruct storeI0(memory mem, immI0 src) %{
match(Set mem (StoreI mem src)); match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem" %} format %{ "STW $src,$mem" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6265,7 +6266,6 @@ instruct storeL0(memory mem, immL0 src) %{
match(Set mem (StoreL mem src)); match(Set mem (StoreL mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %} format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6277,7 +6277,6 @@ instruct storeI_Freg(memory mem, regF src) %{
match(Set mem (StoreI mem src)); match(Set mem (StoreI mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem\t! after fstoi/fdtoi" %} format %{ "STF $src,$mem\t! after fstoi/fdtoi" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6288,7 +6287,6 @@ instruct storeI_Freg(memory mem, regF src) %{
instruct storeP(memory dst, sp_ptr_RegP src) %{ instruct storeP(memory dst, sp_ptr_RegP src) %{
match(Set dst (StoreP dst src)); match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
#ifndef _LP64 #ifndef _LP64
format %{ "STW $src,$dst\t! ptr" %} format %{ "STW $src,$dst\t! ptr" %}
@ -6304,7 +6302,6 @@ instruct storeP(memory dst, sp_ptr_RegP src) %{
instruct storeP0(memory dst, immP0 src) %{ instruct storeP0(memory dst, immP0 src) %{
match(Set dst (StoreP dst src)); match(Set dst (StoreP dst src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
#ifndef _LP64 #ifndef _LP64
format %{ "STW $src,$dst\t! ptr" %} format %{ "STW $src,$dst\t! ptr" %}
@ -6379,7 +6376,6 @@ instruct storeD( memory mem, regD src) %{
match(Set mem (StoreD mem src)); match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$mem" %} format %{ "STDF $src,$mem" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6390,7 +6386,6 @@ instruct storeD0( memory mem, immD0 src) %{
match(Set mem (StoreD mem src)); match(Set mem (StoreD mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$mem" %} format %{ "STX $src,$mem" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -6402,7 +6397,6 @@ instruct storeF( memory mem, regF src) %{
match(Set mem (StoreF mem src)); match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$mem" %} format %{ "STF $src,$mem" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg( mem, src ) ); ins_encode(simple_form3_mem_reg( mem, src ) );
@ -6413,7 +6407,6 @@ instruct storeF0( memory mem, immF0 src) %{
match(Set mem (StoreF mem src)); match(Set mem (StoreF mem src));
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$mem\t! storeF0" %} format %{ "STW $src,$mem\t! storeF0" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( mem, R_G0 ) ); ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
@ -7068,7 +7061,6 @@ instruct loadPLocked(iRegP dst, memory mem) %{
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
#ifndef _LP64 #ifndef _LP64
size(4);
format %{ "LDUW $mem,$dst\t! ptr" %} format %{ "LDUW $mem,$dst\t! ptr" %}
opcode(Assembler::lduw_op3, 0, REGP_OP); opcode(Assembler::lduw_op3, 0, REGP_OP);
#else #else
@ -8138,7 +8130,6 @@ instruct MoveF2I_stack_reg(iRegI dst, stackSlotF src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $src,$dst\t! MoveF2I" %} format %{ "LDUW $src,$dst\t! MoveF2I" %}
opcode(Assembler::lduw_op3); opcode(Assembler::lduw_op3);
ins_encode(simple_form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
@ -8150,7 +8141,6 @@ instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDF $src,$dst\t! MoveI2F" %} format %{ "LDF $src,$dst\t! MoveI2F" %}
opcode(Assembler::ldf_op3); opcode(Assembler::ldf_op3);
ins_encode(simple_form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
@ -8162,7 +8152,6 @@ instruct MoveD2L_stack_reg(iRegL dst, stackSlotD src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDX $src,$dst\t! MoveD2L" %} format %{ "LDX $src,$dst\t! MoveD2L" %}
opcode(Assembler::ldx_op3); opcode(Assembler::ldx_op3);
ins_encode(simple_form3_mem_reg( src, dst ) ); ins_encode(simple_form3_mem_reg( src, dst ) );
@ -8174,7 +8163,6 @@ instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDDF $src,$dst\t! MoveL2D" %} format %{ "LDDF $src,$dst\t! MoveL2D" %}
opcode(Assembler::lddf_op3); opcode(Assembler::lddf_op3);
ins_encode(simple_form3_mem_reg(src, dst)); ins_encode(simple_form3_mem_reg(src, dst));
@ -8186,7 +8174,6 @@ instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STF $src,$dst\t! MoveF2I" %} format %{ "STF $src,$dst\t! MoveF2I" %}
opcode(Assembler::stf_op3); opcode(Assembler::stf_op3);
ins_encode(simple_form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
@ -8198,7 +8185,6 @@ instruct MoveI2F_reg_stack(stackSlotF dst, iRegI src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STW $src,$dst\t! MoveI2F" %} format %{ "STW $src,$dst\t! MoveI2F" %}
opcode(Assembler::stw_op3); opcode(Assembler::stw_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -8210,7 +8196,6 @@ instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STDF $src,$dst\t! MoveD2L" %} format %{ "STDF $src,$dst\t! MoveD2L" %}
opcode(Assembler::stdf_op3); opcode(Assembler::stdf_op3);
ins_encode(simple_form3_mem_reg(dst, src)); ins_encode(simple_form3_mem_reg(dst, src));
@ -8222,7 +8207,6 @@ instruct MoveL2D_reg_stack(stackSlotD dst, iRegL src) %{
effect(DEF dst, USE src); effect(DEF dst, USE src);
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "STX $src,$dst\t! MoveL2D" %} format %{ "STX $src,$dst\t! MoveL2D" %}
opcode(Assembler::stx_op3); opcode(Assembler::stx_op3);
ins_encode(simple_form3_mem_reg( dst, src ) ); ins_encode(simple_form3_mem_reg( dst, src ) );
@ -8427,7 +8411,6 @@ instruct convI2D_reg(regD_low dst, iRegI src) %{
instruct convI2D_mem(regD_low dst, memory mem) %{ instruct convI2D_mem(regD_low dst, memory mem) %{
match(Set dst (ConvI2D (LoadI mem))); match(Set dst (ConvI2D (LoadI mem)));
ins_cost(DEFAULT_COST + MEMORY_REF_COST); ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t" format %{ "LDF $mem,$dst\n\t"
"FITOD $dst,$dst" %} "FITOD $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitod_opf); opcode(Assembler::ldf_op3, Assembler::fitod_opf);
@ -8468,7 +8451,6 @@ instruct convI2F_reg(regF dst, iRegI src) %{
instruct convI2F_mem( regF dst, memory mem ) %{ instruct convI2F_mem( regF dst, memory mem ) %{
match(Set dst (ConvI2F (LoadI mem))); match(Set dst (ConvI2F (LoadI mem)));
ins_cost(DEFAULT_COST + MEMORY_REF_COST); ins_cost(DEFAULT_COST + MEMORY_REF_COST);
size(8);
format %{ "LDF $mem,$dst\n\t" format %{ "LDF $mem,$dst\n\t"
"FITOS $dst,$dst" %} "FITOS $dst,$dst" %}
opcode(Assembler::ldf_op3, Assembler::fitos_opf); opcode(Assembler::ldf_op3, Assembler::fitos_opf);

View File

@ -463,3 +463,37 @@ unsigned int VM_Version::calc_parallel_worker_threads() {
} }
return result; return result;
} }
int VM_Version::parse_features(const char* implementation) {
int features = unknown_m;
// Convert to UPPER case before compare.
char* impl = os::strdup_check_oom(implementation);
for (int i = 0; impl[i] != 0; i++)
impl[i] = (char)toupper((uint)impl[i]);
if (strstr(impl, "SPARC64") != NULL) {
features |= sparc64_family_m;
} else if (strstr(impl, "SPARC-M") != NULL) {
// M-series SPARC is based on T-series.
features |= (M_family_m | T_family_m);
} else if (strstr(impl, "SPARC-T") != NULL) {
features |= T_family_m;
if (strstr(impl, "SPARC-T1") != NULL) {
features |= T1_model_m;
}
} else {
if (strstr(impl, "SPARC") == NULL) {
#ifndef PRODUCT
// kstat on Solaris 8 virtual machines (branded zones)
// returns "(unsupported)" implementation. Solaris 8 is not
// supported anymore, but include this check to be on the
// safe side.
warning("Can't parse CPU implementation = '%s', assume generic SPARC", impl);
#endif
}
}
os::free((void*)impl);
return features;
}

View File

@ -121,7 +121,7 @@ protected:
static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); } static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
static int maximum_niagara1_processor_count() { return 32; } static int maximum_niagara1_processor_count() { return 32; }
static int parse_features(const char* implementation);
public: public:
// Initialization // Initialization
static void initialize(); static void initialize();

View File

@ -161,13 +161,7 @@ address TemplateInterpreterGenerator::generate_exception_handler_common(
create_klass_exception), create_klass_exception),
rarg, rarg2); rarg, rarg2);
} else { } else {
// kind of lame ExternalAddress can't take NULL because __ lea(rarg2, ExternalAddress((address)message));
// external_word_Relocation will assert.
if (message != NULL) {
__ lea(rarg2, ExternalAddress((address)message));
} else {
__ movptr(rarg2, NULL_WORD);
}
__ call_VM(rax, __ call_VM(rax,
CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception),
rarg, rarg2); rarg, rarg2);

View File

@ -7236,6 +7236,7 @@ instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlags
instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
predicate(VM_Version::supports_cx8()); predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t" "MOV $res,0\n\t"
@ -7249,6 +7250,7 @@ instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL
instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t" "MOV $res,0\n\t"
@ -7261,6 +7263,7 @@ instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP new
instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
"MOV $res,0\n\t" "MOV $res,0\n\t"
@ -7271,6 +7274,31 @@ instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newv
ins_pipe( pipe_cmpxchg ); ins_pipe( pipe_cmpxchg );
%} %}
instruct compareAndExchangeL( eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg8(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeP( pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeI( pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
ins_encode( enc_cmpxchg(mem_ptr) );
ins_pipe( pipe_cmpxchg );
%}
instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{ instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
predicate(n->as_LoadStore()->result_not_used()); predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add)); match(Set dummy (GetAndAddI mem add));

View File

@ -7281,6 +7281,7 @@ instruct compareAndSwapP(rRegI res,
%{ %{
predicate(VM_Version::supports_cx8()); predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "cmpxchgq $mem_ptr,$newval\t# " format %{ "cmpxchgq $mem_ptr,$newval\t# "
@ -7305,6 +7306,7 @@ instruct compareAndSwapL(rRegI res,
%{ %{
predicate(VM_Version::supports_cx8()); predicate(VM_Version::supports_cx8());
match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "cmpxchgq $mem_ptr,$newval\t# " format %{ "cmpxchgq $mem_ptr,$newval\t# "
@ -7328,6 +7330,7 @@ instruct compareAndSwapI(rRegI res,
rFlagsReg cr) rFlagsReg cr)
%{ %{
match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "cmpxchgl $mem_ptr,$newval\t# " format %{ "cmpxchgl $mem_ptr,$newval\t# "
@ -7351,6 +7354,7 @@ instruct compareAndSwapN(rRegI res,
rax_RegN oldval, rRegN newval, rax_RegN oldval, rRegN newval,
rFlagsReg cr) %{ rFlagsReg cr) %{
match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
effect(KILL cr, KILL oldval); effect(KILL cr, KILL oldval);
format %{ "cmpxchgl $mem_ptr,$newval\t# " format %{ "cmpxchgl $mem_ptr,$newval\t# "
@ -7368,6 +7372,83 @@ instruct compareAndSwapN(rRegI res,
ins_pipe( pipe_cmpxchg ); ins_pipe( pipe_cmpxchg );
%} %}
instruct compareAndExchangeI(
memory mem_ptr,
rax_RegI oldval, rRegI newval,
rFlagsReg cr)
%{
match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeL(
memory mem_ptr,
rax_RegL oldval, rRegL newval,
rFlagsReg cr)
%{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem_wide(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeN(
memory mem_ptr,
rax_RegN oldval, rRegN newval,
rFlagsReg cr) %{
match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgl $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct compareAndExchangeP(
memory mem_ptr,
rax_RegP oldval, rRegP newval,
rFlagsReg cr)
%{
predicate(VM_Version::supports_cx8());
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
effect(KILL cr);
format %{ "cmpxchgq $mem_ptr,$newval\t# "
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
opcode(0x0F, 0xB1);
ins_encode(lock_prefix,
REX_reg_mem_wide(newval, mem_ptr),
OpcP, OpcS,
reg_mem(newval, mem_ptr) // lock cmpxchg
);
ins_pipe( pipe_cmpxchg );
%}
instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
predicate(n->as_LoadStore()->result_not_used()); predicate(n->as_LoadStore()->result_not_used());
match(Set dummy (GetAndAddI mem add)); match(Set dummy (GetAndAddI mem add));

View File

@ -22,6 +22,7 @@
*/ */
package jdk.vm.ci.amd64; package jdk.vm.ci.amd64;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE; import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
import static jdk.vm.ci.code.Register.SPECIAL; import static jdk.vm.ci.code.Register.SPECIAL;
@ -220,7 +221,7 @@ public class AMD64 extends Architecture {
private final AMD64Kind largestKind; private final AMD64Kind largestKind;
public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) { public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, 8); super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8);
this.features = features; this.features = features;
this.flags = flags; this.flags = flags;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64"; assert features.contains(CPUFeature.SSE2) : "minimum config for x64";

View File

@ -1141,7 +1141,7 @@ public class HotSpotVMConfig {
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset; @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_sp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaSpOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset; @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_pc", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable private int javaFrameAnchorLastJavaPcOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, archs = {"amd64"}) @Stable private int javaFrameAnchorLastJavaFpOffset; @HotSpotVMField(name = "JavaFrameAnchor::_last_Java_fp", type = "intptr_t*", get = HotSpotVMField.Type.OFFSET, archs = {"aarch64, amd64"}) @Stable private int javaFrameAnchorLastJavaFpOffset;
@HotSpotVMField(name = "JavaFrameAnchor::_flags", type = "int", get = HotSpotVMField.Type.OFFSET, archs = {"sparc"}) @Stable private int javaFrameAnchorFlagsOffset; @HotSpotVMField(name = "JavaFrameAnchor::_flags", type = "int", get = HotSpotVMField.Type.OFFSET, archs = {"sparc"}) @Stable private int javaFrameAnchorFlagsOffset;
public int threadLastJavaSpOffset() { public int threadLastJavaSpOffset() {
@ -1152,11 +1152,8 @@ public class HotSpotVMConfig {
return javaThreadAnchorOffset + javaFrameAnchorLastJavaPcOffset; return javaThreadAnchorOffset + javaFrameAnchorLastJavaPcOffset;
} }
/**
* This value is only valid on AMD64.
*/
public int threadLastJavaFpOffset() { public int threadLastJavaFpOffset() {
// TODO add an assert for AMD64 assert getHostArchitectureName().equals("aarch64") || getHostArchitectureName().equals("amd64");
return javaThreadAnchorOffset + javaFrameAnchorLastJavaFpOffset; return javaThreadAnchorOffset + javaFrameAnchorLastJavaFpOffset;
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 SAP SE. All rights reserved. * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,7 @@
#include "compiler/compileBroker.hpp" #include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "jvm_aix.h" #include "jvm_aix.h"
#include "logging/log.hpp"
#include "libo4.hpp" #include "libo4.hpp"
#include "libperfstat_aix.hpp" #include "libperfstat_aix.hpp"
#include "libodm_aix.hpp" #include "libodm_aix.hpp"
@ -791,13 +792,8 @@ static void *java_start(Thread *thread) {
const pthread_t pthread_id = ::pthread_self(); const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self(); const tid_t kernel_thread_id = ::thread_self();
trcVerbose("newborn Thread : pthread-id %u, ktid " UINT64_FORMAT log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
", stack %p ... %p, stacksize 0x%IX (%IB)", os::current_thread_id(), (uintx) kernel_thread_id);
pthread_id, kernel_thread_id,
thread->stack_end(),
thread->stack_base(),
thread->stack_size(),
thread->stack_size());
// Normally, pthread stacks on AIX live in the data segment (are allocated with malloc() // Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()
// by the pthread library). In rare cases, this may not be the case, e.g. when third-party // by the pthread library). In rare cases, this may not be the case, e.g. when third-party
@ -805,7 +801,7 @@ static void *java_start(Thread *thread) {
// guard pages on those stacks, because the stacks may reside in memory which is not // guard pages on those stacks, because the stacks may reside in memory which is not
// protectable (shmated). // protectable (shmated).
if (thread->stack_base() > ::sbrk(0)) { if (thread->stack_base() > ::sbrk(0)) {
trcVerbose("Thread " UINT64_FORMAT ": stack not in data segment.", (uint64_t) pthread_id); log_warning(os, thread)("Thread stack not in data segment.");
} }
// Try to randomize the cache line index of hot stack frames. // Try to randomize the cache line index of hot stack frames.
@ -839,8 +835,8 @@ static void *java_start(Thread *thread) {
// Call one more level start routine. // Call one more level start routine.
thread->run(); thread->run();
trcVerbose("Thread finished : pthread-id %u, ktid " UINT64_FORMAT ".", log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
pthread_id, kernel_thread_id); os::current_thread_id(), (uintx) kernel_thread_id);
return 0; return 0;
} }
@ -908,20 +904,19 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
pthread_t tid; pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
if (ret == 0) { if (ret != 0) {
trcVerbose("Created New Thread : pthread-id %u", tid);
} else {
if (os::Aix::on_pase()) {
// QIBM_MULTI_THREADED=Y is needed when the launcher is started on iSeries
// using QSH. Otherwise pthread_create fails with errno=11.
trcVerbose("(Please make sure you set the environment variable "
"QIBM_MULTI_THREADED=Y before running this program.)");
}
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far // Need to clean up stuff we've allocated so far
thread->set_osthread(NULL); thread->set_osthread(NULL);
delete osthread; delete osthread;
@ -958,13 +953,6 @@ bool os::create_attached_thread(JavaThread* thread) {
const pthread_t pthread_id = ::pthread_self(); const pthread_t pthread_id = ::pthread_self();
const tid_t kernel_thread_id = ::thread_self(); const tid_t kernel_thread_id = ::thread_self();
trcVerbose("attaching Thread : pthread-id %u, ktid " UINT64_FORMAT ", stack %p ... %p, stacksize 0x%IX (%IB)",
pthread_id, kernel_thread_id,
thread->stack_end(),
thread->stack_base(),
thread->stack_size(),
thread->stack_size());
// OSThread::thread_id is the pthread id. // OSThread::thread_id is the pthread id.
osthread->set_thread_id(pthread_id); osthread->set_thread_id(pthread_id);
@ -990,6 +978,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask // and save the caller's signal mask
os::Aix::hotspot_sigmask(thread); os::Aix::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) kernel_thread_id);
return true; return true;
} }

View File

@ -32,6 +32,7 @@
#include "compiler/disassembler.hpp" #include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "jvm_bsd.h" #include "jvm_bsd.h"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp" #include "memory/filemap.hpp"
#include "mutex_bsd.inline.hpp" #include "mutex_bsd.inline.hpp"
@ -681,6 +682,9 @@ static void *java_start(Thread *thread) {
osthread->set_thread_id(os::Bsd::gettid()); osthread->set_thread_id(os::Bsd::gettid());
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
#ifdef __APPLE__ #ifdef __APPLE__
uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id()); uint64_t unique_thread_id = locate_unique_thread_id(osthread->thread_id());
guarantee(unique_thread_id != 0, "unique thread id was not found"); guarantee(unique_thread_id != 0, "unique thread id was not found");
@ -716,6 +720,9 @@ static void *java_start(Thread *thread) {
// call one more level start routine // call one more level start routine
thread->run(); thread->run();
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return 0; return 0;
} }
@ -776,12 +783,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
pthread_t tid; pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
if (ret != 0) { if (ret != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far // Need to clean up stuff we've allocated so far
thread->set_osthread(NULL); thread->set_osthread(NULL);
delete osthread; delete osthread;
@ -858,6 +871,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask // and save the caller's signal mask
os::Bsd::hotspot_sigmask(thread); os::Bsd::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return true; return true;
} }

View File

@ -662,6 +662,9 @@ static void *java_start(Thread *thread) {
osthread->set_thread_id(os::current_thread_id()); osthread->set_thread_id(os::current_thread_id());
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
if (UseNUMA) { if (UseNUMA) {
int lgrp_id = os::numa_get_group_id(); int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) { if (lgrp_id != -1) {
@ -691,6 +694,9 @@ static void *java_start(Thread *thread) {
// call one more level start routine // call one more level start routine
thread->run(); thread->run();
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return 0; return 0;
} }
@ -756,12 +762,18 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
pthread_t tid; pthread_t tid;
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
char buf[64];
if (ret == 0) {
log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
} else {
log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",
strerror(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));
}
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
if (ret != 0) { if (ret != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("pthread_create()");
}
// Need to clean up stuff we've allocated so far // Need to clean up stuff we've allocated so far
thread->set_osthread(NULL); thread->set_osthread(NULL);
delete osthread; delete osthread;
@ -858,6 +870,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask // and save the caller's signal mask
os::Linux::hotspot_sigmask(thread); os::Linux::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",
os::current_thread_id(), (uintx) pthread_self());
return true; return true;
} }

View File

@ -1071,6 +1071,19 @@ void os::Posix::ucontext_set_pc(ucontext_t* ctx, address pc) {
#endif #endif
} }
char* os::Posix::describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr) {
size_t stack_size = 0;
size_t guard_size = 0;
int detachstate = 0;
pthread_attr_getstacksize(attr, &stack_size);
pthread_attr_getguardsize(attr, &guard_size);
pthread_attr_getdetachstate(attr, &detachstate);
jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s",
stack_size / 1024, guard_size / 1024,
(detachstate == PTHREAD_CREATE_DETACHED ? "detached" : "joinable"));
return buf;
}
os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");

View File

@ -76,6 +76,11 @@ public:
static address ucontext_get_pc(const ucontext_t* ctx); static address ucontext_get_pc(const ucontext_t* ctx);
// Set PC into context. Needed for continuation after signal. // Set PC into context. Needed for continuation after signal.
static void ucontext_set_pc(ucontext_t* ctx, address pc); static void ucontext_set_pc(ucontext_t* ctx, address pc);
// Helper function; describes pthread attributes as short string. String is written
// to buf with len buflen; buf is returned.
static char* describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr);
}; };
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,6 +32,7 @@
#include "compiler/disassembler.hpp" #include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "jvm_solaris.h" #include "jvm_solaris.h"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp" #include "memory/filemap.hpp"
#include "mutex_solaris.inline.hpp" #include "mutex_solaris.inline.hpp"
@ -68,6 +69,7 @@
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
#include "utilities/events.hpp" #include "utilities/events.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
#include "utilities/vmError.hpp" #include "utilities/vmError.hpp"
// put OS-includes here // put OS-includes here
@ -736,6 +738,9 @@ extern "C" void* java_start(void* thread_addr) {
osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound
thread->_schedctl = (void *) schedctl_init(); thread->_schedctl = (void *) schedctl_init();
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").",
os::current_thread_id());
if (UseNUMA) { if (UseNUMA) {
int lgrp_id = os::numa_get_group_id(); int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) { if (lgrp_id != -1) {
@ -781,6 +786,8 @@ extern "C" void* java_start(void* thread_addr) {
Atomic::dec(&os::Solaris::_os_thread_count); Atomic::dec(&os::Solaris::_os_thread_count);
} }
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
if (UseDetachedThreads) { if (UseDetachedThreads) {
thr_exit(NULL); thr_exit(NULL);
ShouldNotReachHere(); ShouldNotReachHere();
@ -853,6 +860,9 @@ bool os::create_attached_thread(JavaThread* thread) {
// and save the caller's signal mask // and save the caller's signal mask
os::Solaris::hotspot_sigmask(thread); os::Solaris::hotspot_sigmask(thread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",
os::current_thread_id());
return true; return true;
} }
@ -879,6 +889,24 @@ bool os::create_main_thread(JavaThread* thread) {
return true; return true;
} }
// Helper function to trace thread attributes, similar to os::Posix::describe_pthread_attr()
static char* describe_thr_create_attributes(char* buf, size_t buflen,
size_t stacksize, long flags) {
stringStream ss(buf, buflen);
ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);
ss.print("flags: ");
#define PRINT_FLAG(f) if (flags & f) ss.print( #f " ");
#define ALL(X) \
X(THR_SUSPENDED) \
X(THR_DETACHED) \
X(THR_BOUND) \
X(THR_NEW_LWP) \
X(THR_DAEMON)
ALL(PRINT_FLAG)
#undef ALL
#undef PRINT_FLAG
return buf;
}
bool os::create_thread(Thread* thread, ThreadType thr_type, bool os::create_thread(Thread* thread, ThreadType thr_type,
size_t stack_size) { size_t stack_size) {
@ -974,10 +1002,17 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
osthread->set_thread_id(-1); osthread->set_thread_id(-1);
status = thr_create(NULL, stack_size, java_start, thread, flags, &tid); status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
char buf[64];
if (status == 0) {
log_info(os, thread)("Thread started (tid: " UINTX_FORMAT ", attributes: %s). ",
(uintx) tid, describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags));
} else {
log_warning(os, thread)("Failed to start thread - thr_create failed (%s) for attributes: %s.",
strerror(status), describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags));
}
if (status != 0) { if (status != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
perror("os::create_thread");
}
thread->set_osthread(NULL); thread->set_osthread(NULL);
// Need to clean up stuff we've allocated so far // Need to clean up stuff we've allocated so far
delete osthread; delete osthread;

View File

@ -35,6 +35,7 @@
#include "compiler/disassembler.hpp" #include "compiler/disassembler.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
#include "jvm_windows.h" #include "jvm_windows.h"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp" #include "memory/filemap.hpp"
#include "mutex_windows.inline.hpp" #include "mutex_windows.inline.hpp"
@ -71,6 +72,7 @@
#include "utilities/defaultStream.hpp" #include "utilities/defaultStream.hpp"
#include "utilities/events.hpp" #include "utilities/events.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
#include "utilities/vmError.hpp" #include "utilities/vmError.hpp"
#ifdef _DEBUG #ifdef _DEBUG
@ -436,6 +438,8 @@ static unsigned __stdcall java_start(Thread* thread) {
res = 20115; // java thread res = 20115; // java thread
} }
log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id());
// Install a win32 structured exception handler around every thread created // Install a win32 structured exception handler around every thread created
// by VM, so VM can generate error dump when an exception occurred in non- // by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread). // Java thread (e.g. VM thread).
@ -446,6 +450,8 @@ static unsigned __stdcall java_start(Thread* thread) {
// Nothing to do. // Nothing to do.
} }
log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id());
// One less thread is executing // One less thread is executing
// When the VMThread gets here, the main thread may have already exited // When the VMThread gets here, the main thread may have already exited
// which frees the CodeHeap containing the Atomic::add code // which frees the CodeHeap containing the Atomic::add code
@ -509,6 +515,10 @@ bool os::create_attached_thread(JavaThread* thread) {
osthread->set_state(RUNNABLE); osthread->set_state(RUNNABLE);
thread->set_osthread(osthread); thread->set_osthread(osthread);
log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").",
os::current_thread_id());
return true; return true;
} }
@ -530,6 +540,27 @@ bool os::create_main_thread(JavaThread* thread) {
return true; return true;
} }
// Helper function to trace _beginthreadex attributes,
// similar to os::Posix::describe_pthread_attr()
static char* describe_beginthreadex_attributes(char* buf, size_t buflen,
size_t stacksize, unsigned initflag) {
stringStream ss(buf, buflen);
if (stacksize == 0) {
ss.print("stacksize: default, ");
} else {
ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024);
}
ss.print("flags: ");
#define PRINT_FLAG(f) if (initflag & f) ss.print( #f " ");
#define ALL(X) \
X(CREATE_SUSPENDED) \
X(STACK_SIZE_PARAM_IS_A_RESERVATION)
ALL(PRINT_FLAG)
#undef ALL
#undef PRINT_FLAG
return buf;
}
// Allocate and initialize a new OSThread // Allocate and initialize a new OSThread
bool os::create_thread(Thread* thread, ThreadType thr_type, bool os::create_thread(Thread* thread, ThreadType thr_type,
size_t stack_size) { size_t stack_size) {
@ -596,14 +627,24 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
// document because JVM uses C runtime library. The good news is that the // document because JVM uses C runtime library. The good news is that the
// flag appears to work with _beginthredex() as well. // flag appears to work with _beginthredex() as well.
const unsigned initflag = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
HANDLE thread_handle = HANDLE thread_handle =
(HANDLE)_beginthreadex(NULL, (HANDLE)_beginthreadex(NULL,
(unsigned)stack_size, (unsigned)stack_size,
(unsigned (__stdcall *)(void*)) java_start, (unsigned (__stdcall *)(void*)) java_start,
thread, thread,
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, initflag,
&thread_id); &thread_id);
char buf[64];
if (thread_handle != NULL) {
log_info(os, thread)("Thread started (tid: %u, attributes: %s)",
thread_id, describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
} else {
log_warning(os, thread)("Failed to start thread - _beginthreadex failed (%s) for attributes: %s.",
strerror(errno), describe_beginthreadex_attributes(buf, sizeof(buf), stack_size, initflag));
}
if (thread_handle == NULL) { if (thread_handle == NULL) {
// Need to clean up stuff we've allocated so far // Need to clean up stuff we've allocated so far
CloseHandle(osthread->interrupt_event()); CloseHandle(osthread->interrupt_event());
@ -1668,8 +1709,7 @@ void os::win32::print_windows_version(outputStream* st) {
if (is_workstation) { if (is_workstation) {
st->print("10"); st->print("10");
} else { } else {
// The server version name of Windows 10 is not known at this time st->print("Server 2016");
st->print("%d.%d", major_version, minor_version);
} }
break; break;

View File

@ -264,6 +264,7 @@ void PICL::close_library() {
// We need to keep these here as long as we have to build on Solaris // We need to keep these here as long as we have to build on Solaris
// versions before 10. // versions before 10.
#ifndef SI_ARCHITECTURE_32 #ifndef SI_ARCHITECTURE_32
#define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */ #define SI_ARCHITECTURE_32 516 /* basic 32-bit SI_ARCHITECTURE */
#endif #endif
@ -272,36 +273,87 @@ void PICL::close_library() {
#define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */ #define SI_ARCHITECTURE_64 517 /* basic 64-bit SI_ARCHITECTURE */
#endif #endif
static void do_sysinfo(int si, const char* string, int* features, int mask) { #ifndef SI_CPUBRAND
char tmp; #define SI_CPUBRAND 523 /* return cpu brand string */
size_t bufsize = sysinfo(si, &tmp, 1); #endif
// All SI defines used below must be supported. class Sysinfo {
guarantee(bufsize != -1, "must be supported"); char* _string;
public:
Sysinfo(int si) : _string(NULL) {
char tmp;
size_t bufsize = sysinfo(si, &tmp, 1);
char* buf = (char*) os::malloc(bufsize, mtInternal); if (bufsize != -1) {
char* buf = (char*) os::malloc(bufsize, mtInternal);
if (buf == NULL) if (buf != NULL) {
return; if (sysinfo(si, buf, bufsize) == bufsize) {
_string = buf;
if (sysinfo(si, buf, bufsize) == bufsize) { } else {
// Compare the string. os::free(buf);
if (strcmp(buf, string) == 0) { }
*features |= mask; }
} }
} }
os::free(buf); ~Sysinfo() {
} if (_string != NULL) {
os::free(_string);
}
}
const char* value() const {
return _string;
}
bool valid() const {
return _string != NULL;
}
bool match(const char* s) const {
return valid() ? strcmp(_string, s) == 0 : false;
}
bool match_substring(const char* s) const {
return valid() ? strstr(_string, s) != NULL : false;
}
};
class Sysconf {
int _value;
public:
Sysconf(int sc) : _value(-1) {
_value = sysconf(sc);
}
bool valid() const {
return _value != -1;
}
int value() const {
return _value;
}
};
#ifndef _SC_DCACHE_LINESZ
#define _SC_DCACHE_LINESZ 508 /* Data cache line size */
#endif
#ifndef _SC_L2CACHE_LINESZ
#define _SC_L2CACHE_LINESZ 527 /* Size of L2 cache line */
#endif
int VM_Version::platform_features(int features) { int VM_Version::platform_features(int features) {
assert(os::Solaris::supports_getisax(), "getisax() must be available"); assert(os::Solaris::supports_getisax(), "getisax() must be available");
// Check 32-bit architecture. // Check 32-bit architecture.
do_sysinfo(SI_ARCHITECTURE_32, "sparc", &features, v8_instructions_m); if (Sysinfo(SI_ARCHITECTURE_32).match("sparc")) {
features |= v8_instructions_m;
}
// Check 64-bit architecture. // Check 64-bit architecture.
do_sysinfo(SI_ARCHITECTURE_64, "sparcv9", &features, generic_v9_m); if (Sysinfo(SI_ARCHITECTURE_64).match("sparcv9")) {
features |= generic_v9_m;
}
// Extract valid instruction set extensions. // Extract valid instruction set extensions.
uint_t avs[2]; uint_t avs[2];
@ -388,67 +440,63 @@ int VM_Version::platform_features(int features) {
if (av & AV_SPARC_SHA512) features |= sha512_instruction_m; if (av & AV_SPARC_SHA512) features |= sha512_instruction_m;
// Determine the machine type. // Determine the machine type.
do_sysinfo(SI_MACHINE, "sun4v", &features, sun4v_m); if (Sysinfo(SI_MACHINE).match("sun4v")) {
features |= sun4v_m;
}
{ bool use_solaris_12_api = false;
// Using kstat to determine the machine type. Sysinfo impl(SI_CPUBRAND);
if (impl.valid()) {
// If SI_CPUBRAND works, that means Solaris 12 API to get the cache line sizes
// is available to us as well
use_solaris_12_api = true;
features |= parse_features(impl.value());
} else {
// Otherwise use kstat to determine the machine type.
kstat_ctl_t* kc = kstat_open(); kstat_ctl_t* kc = kstat_open();
kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL); kstat_t* ksp = kstat_lookup(kc, (char*)"cpu_info", -1, NULL);
const char* implementation = "UNKNOWN"; const char* implementation;
bool has_implementation = false;
if (ksp != NULL) { if (ksp != NULL) {
if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) { if (kstat_read(kc, ksp, NULL) != -1 && ksp->ks_data != NULL) {
kstat_named_t* knm = (kstat_named_t *)ksp->ks_data; kstat_named_t* knm = (kstat_named_t *)ksp->ks_data;
for (int i = 0; i < ksp->ks_ndata; i++) { for (int i = 0; i < ksp->ks_ndata; i++) {
if (strcmp((const char*)&(knm[i].name),"implementation") == 0) { if (strcmp((const char*)&(knm[i].name),"implementation") == 0) {
implementation = KSTAT_NAMED_STR_PTR(&knm[i]); implementation = KSTAT_NAMED_STR_PTR(&knm[i]);
has_implementation = true;
#ifndef PRODUCT #ifndef PRODUCT
if (PrintMiscellaneous && Verbose) { if (PrintMiscellaneous && Verbose) {
tty->print_cr("cpu_info.implementation: %s", implementation); tty->print_cr("cpu_info.implementation: %s", implementation);
} }
#endif #endif
// Convert to UPPER case before compare. features |= parse_features(implementation);
char* impl = os::strdup_check_oom(implementation);
for (int i = 0; impl[i] != 0; i++)
impl[i] = (char)toupper((uint)impl[i]);
if (strstr(impl, "SPARC64") != NULL) {
features |= sparc64_family_m;
} else if (strstr(impl, "SPARC-M") != NULL) {
// M-series SPARC is based on T-series.
features |= (M_family_m | T_family_m);
} else if (strstr(impl, "SPARC-T") != NULL) {
features |= T_family_m;
if (strstr(impl, "SPARC-T1") != NULL) {
features |= T1_model_m;
}
} else {
if (strstr(impl, "SPARC") == NULL) {
#ifndef PRODUCT
// kstat on Solaris 8 virtual machines (branded zones)
// returns "(unsupported)" implementation. Solaris 8 is not
// supported anymore, but include this check to be on the
// safe side.
warning("kstat cpu_info implementation = '%s', assume generic SPARC", impl);
#endif
implementation = "SPARC";
}
}
os::free((void*)impl);
break; break;
} }
} // for( } // for(
} }
} }
assert(strcmp(implementation, "UNKNOWN") != 0, assert(has_implementation, "unknown cpu info (changed kstat interface?)");
"unknown cpu info (changed kstat interface?)");
kstat_close(kc); kstat_close(kc);
} }
// Figure out cache line sizes using PICL bool is_sun4v = (features & sun4v_m) != 0;
PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0); if (use_solaris_12_api && is_sun4v) {
_L1_data_cache_line_size = picl.L1_data_cache_line_size(); // If Solaris 12 API is supported and it's sun4v use sysconf() to get the cache line sizes
_L2_data_cache_line_size = picl.L2_data_cache_line_size(); Sysconf l1_dcache_line_size(_SC_DCACHE_LINESZ);
if (l1_dcache_line_size.valid()) {
_L1_data_cache_line_size = l1_dcache_line_size.value();
}
Sysconf l2_dcache_line_size(_SC_L2CACHE_LINESZ);
if (l2_dcache_line_size.valid()) {
_L2_data_cache_line_size = l2_dcache_line_size.value();
}
} else {
// Otherwise figure out the cache line sizes using PICL
bool is_fujitsu = (features & sparc64_family_m) != 0;
PICL picl(is_fujitsu, is_sun4v);
_L1_data_cache_line_size = picl.L1_data_cache_line_size();
_L2_data_cache_line_size = picl.L2_data_cache_line_size();
}
return features; return features;
} }

View File

@ -51,11 +51,8 @@ void MacroAssembler::int3() {
// movl reg, [reg + thread_ptr_offset] Load thread // movl reg, [reg + thread_ptr_offset] Load thread
// //
void MacroAssembler::get_thread(Register thread) { void MacroAssembler::get_thread(Register thread) {
// can't use ExternalAddress because it can't take NULL
AddressLiteral null(0, relocInfo::none);
prefix(FS_segment); prefix(FS_segment);
movptr(thread, null); movptr(thread, ExternalAddress(NULL));
assert(os::win32::get_thread_ptr_offset() != 0, assert(os::win32::get_thread_ptr_offset() != 0,
"Thread Pointer Offset has not been initialized"); "Thread Pointer Offset has not been initialized");
movl(thread, Address(thread, os::win32::get_thread_ptr_offset())); movl(thread, Address(thread, os::win32::get_thread_ptr_offset()));

View File

@ -3491,6 +3491,8 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"LoadPLocked", "LoadPLocked",
"StorePConditional", "StoreIConditional", "StoreLConditional", "StorePConditional", "StoreIConditional", "StoreLConditional",
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
"WeakCompareAndSwapI", "WeakCompareAndSwapL", "WeakCompareAndSwapP", "WeakCompareAndSwapN",
"CompareAndExchangeI", "CompareAndExchangeL", "CompareAndExchangeP", "CompareAndExchangeN",
"StoreCM", "StoreCM",
"ClearArray", "ClearArray",
"GetAndAddI", "GetAndSetI", "GetAndSetP", "GetAndAddI", "GetAndSetI", "GetAndSetP",

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -34,7 +34,9 @@
// compilation for later analysis. // compilation for later analysis.
class CFGPrinterOutput; class CFGPrinterOutput;
class IntervalList; class Interval;
typedef GrowableArray<Interval*> IntervalList;
class CFGPrinter : public AllStatic { class CFGPrinter : public AllStatic {
private: private:

View File

@ -222,27 +222,36 @@ void Canonicalizer::do_StoreField (StoreField* x) {
} }
void Canonicalizer::do_ArrayLength (ArrayLength* x) { void Canonicalizer::do_ArrayLength (ArrayLength* x) {
NewArray* array = x->array()->as_NewArray(); NewArray* na;
if (array != NULL && array->length() != NULL) { Constant* ct;
Constant* length = array->length()->as_Constant(); LoadField* lf;
if (length != NULL) {
// do not use the Constant itself, but create a new Constant if ((na = x->array()->as_NewArray()) != NULL) {
// with same value Otherwise a Constant is live over multiple // New arrays might have the known length.
// blocks without being registered in a state array. // Do not use the Constant itself, but create a new Constant
// with same value Otherwise a Constant is live over multiple
// blocks without being registered in a state array.
Constant* length;
if (na->length() != NULL &&
(length = na->length()->as_Constant()) != NULL) {
assert(length->type()->as_IntConstant() != NULL, "array length must be integer"); assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
set_constant(length->type()->as_IntConstant()->value()); set_constant(length->type()->as_IntConstant()->value());
} }
} else {
LoadField* lf = x->array()->as_LoadField(); } else if ((ct = x->array()->as_Constant()) != NULL) {
if (lf != NULL) { // Constant arrays have constant lengths.
ciField* field = lf->field(); ArrayConstant* cnst = ct->type()->as_ArrayConstant();
if (field->is_constant() && field->is_static()) { if (cnst != NULL) {
// final static field set_constant(cnst->value()->length());
ciObject* c = field->constant_value().as_object(); }
if (c->is_array()) {
ciArray* array = (ciArray*) c; } else if ((lf = x->array()->as_LoadField()) != NULL) {
set_constant(array->length()); ciField* field = lf->field();
} if (field->is_constant() && field->is_static()) {
assert(PatchALot || ScavengeRootsInCode < 2, "Constant field loads are folded during parsing");
ciObject* c = field->constant_value().as_object();
if (!c->is_null_object()) {
set_constant(c->as_array()->length());
} }
} }
} }

View File

@ -228,8 +228,6 @@ bool Compiler::is_intrinsic_supported(const methodHandle& method) {
case vmIntrinsics::_getCharStringU: case vmIntrinsics::_getCharStringU:
case vmIntrinsics::_putCharStringU: case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS #ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_classID:
case vmIntrinsics::_threadID:
case vmIntrinsics::_counterTime: case vmIntrinsics::_counterTime:
#endif #endif
break; break;

View File

@ -43,6 +43,9 @@
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
#include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
#ifdef TRACE_HAVE_INTRINSICS
#include "trace/traceMacros.hpp"
#endif
#ifdef ASSERT #ifdef ASSERT
#define __ gen()->lir(__FILE__, __LINE__)-> #define __ gen()->lir(__FILE__, __LINE__)->
@ -3067,42 +3070,7 @@ void LIRGenerator::do_RuntimeCall(address routine, Intrinsic* x) {
__ move(reg, result); __ move(reg, result);
} }
#ifdef TRACE_HAVE_INTRINSICS
void LIRGenerator::do_ThreadIDIntrinsic(Intrinsic* x) {
LIR_Opr thread = getThreadPointer();
LIR_Opr osthread = new_pointer_register();
__ move(new LIR_Address(thread, in_bytes(JavaThread::osthread_offset()), osthread->type()), osthread);
size_t thread_id_size = OSThread::thread_id_size();
if (thread_id_size == (size_t) BytesPerLong) {
LIR_Opr id = new_register(T_LONG);
__ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_LONG), id);
__ convert(Bytecodes::_l2i, id, rlock_result(x));
} else if (thread_id_size == (size_t) BytesPerInt) {
__ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_INT), rlock_result(x));
} else {
ShouldNotReachHere();
}
}
void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
CodeEmitInfo* info = state_for(x);
CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
BasicType klass_pointer_type = NOT_LP64(T_INT) LP64_ONLY(T_LONG);
assert(info != NULL, "must have info");
LIRItem arg(x->argument_at(1), this);
arg.load_item();
LIR_Opr klass = new_pointer_register();
__ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), klass_pointer_type), klass, info);
LIR_Opr id = new_register(T_LONG);
ByteSize offset = TRACE_ID_OFFSET;
LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
__ move(trace_id_addr, id);
__ logical_or(id, LIR_OprFact::longConst(0x01l), id);
__ store(id, trace_id_addr);
__ logical_and(id, LIR_OprFact::longConst(~0x3l), id);
__ move(id, rlock_result(x));
}
#endif
void LIRGenerator::do_Intrinsic(Intrinsic* x) { void LIRGenerator::do_Intrinsic(Intrinsic* x) {
switch (x->id()) { switch (x->id()) {
@ -3115,8 +3083,6 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) {
} }
#ifdef TRACE_HAVE_INTRINSICS #ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_threadID: do_ThreadIDIntrinsic(x); break;
case vmIntrinsics::_classID: do_ClassIDIntrinsic(x); break;
case vmIntrinsics::_counterTime: case vmIntrinsics::_counterTime:
do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x); do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), x);
break; break;

View File

@ -440,10 +440,7 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure {
void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux); void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux);
void do_RuntimeCall(address routine, Intrinsic* x); void do_RuntimeCall(address routine, Intrinsic* x);
#ifdef TRACE_HAVE_INTRINSICS
void do_ThreadIDIntrinsic(Intrinsic* x);
void do_ClassIDIntrinsic(Intrinsic* x);
#endif
ciKlass* profile_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k, ciKlass* profile_type(ciMethodData* md, int md_first_offset, int md_offset, intptr_t profiled_k,
Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_at_call_k, Value arg, LIR_Opr& mdp, bool not_null, ciKlass* signature_at_call_k,
ciKlass* callee_signature_k); ciKlass* callee_signature_k);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -1434,42 +1434,74 @@ int LinearScan::interval_cmp(Interval** a, Interval** b) {
} }
#ifndef PRODUCT #ifndef PRODUCT
bool LinearScan::is_sorted(IntervalArray* intervals) { int interval_cmp(Interval* const& l, Interval* const& r) {
int from = -1; return l->from() - r->from();
int i, j; }
for (i = 0; i < intervals->length(); i ++) {
Interval* it = intervals->at(i); bool find_interval(Interval* interval, IntervalArray* intervals) {
if (it != NULL) { bool found;
if (from > it->from()) { int idx = intervals->find_sorted<Interval*, interval_cmp>(interval, found);
assert(false, "");
return false; if (!found) {
} return false;
from = it->from(); }
int from = interval->from();
// The index we've found using binary search is pointing to an interval
// that is defined in the same place as the interval we were looking for.
// So now we have to look around that index and find exact interval.
for (int i = idx; i >= 0; i--) {
if (intervals->at(i) == interval) {
return true;
}
if (intervals->at(i)->from() != from) {
break;
} }
} }
// check in both directions if sorted list and unsorted list contain same intervals for (int i = idx + 1; i < intervals->length(); i++) {
for (i = 0; i < interval_count(); i++) { if (intervals->at(i) == interval) {
if (interval_at(i) != NULL) { return true;
int num_found = 0; }
for (j = 0; j < intervals->length(); j++) { if (intervals->at(i)->from() != from) {
if (interval_at(i) == intervals->at(j)) { break;
num_found++;
}
}
assert(num_found == 1, "lists do not contain same intervals");
} }
} }
for (j = 0; j < intervals->length(); j++) {
int num_found = 0; return false;
for (i = 0; i < interval_count(); i++) { }
if (interval_at(i) == intervals->at(j)) {
num_found++; bool LinearScan::is_sorted(IntervalArray* intervals) {
} int from = -1;
int null_count = 0;
for (int i = 0; i < intervals->length(); i++) {
Interval* it = intervals->at(i);
if (it != NULL) {
assert(from <= it->from(), "Intervals are unordered");
from = it->from();
} else {
null_count++;
} }
assert(num_found == 1, "lists do not contain same intervals");
} }
assert(null_count == 0, "Sorted intervals should not contain nulls");
null_count = 0;
for (int i = 0; i < interval_count(); i++) {
Interval* interval = interval_at(i);
if (interval != NULL) {
assert(find_interval(interval, intervals), "Lists do not contain same intervals");
} else {
null_count++;
}
}
assert(interval_count() - null_count == intervals->length(),
"Sorted list should contain the same amount of non-NULL intervals as unsorted list");
return true; return true;
} }
#endif #endif
@ -1536,7 +1568,7 @@ void LinearScan::sort_intervals_before_allocation() {
sorted_len++; sorted_len++;
} }
} }
IntervalArray* sorted_list = new IntervalArray(sorted_len); IntervalArray* sorted_list = new IntervalArray(sorted_len, sorted_len, NULL);
// special sorting algorithm: the original interval-list is almost sorted, // special sorting algorithm: the original interval-list is almost sorted,
// only some intervals are swapped. So this is much faster than a complete QuickSort // only some intervals are swapped. So this is much faster than a complete QuickSort
@ -1574,8 +1606,8 @@ void LinearScan::sort_intervals_after_allocation() {
_needs_full_resort = false; _needs_full_resort = false;
} }
IntervalArray* old_list = _sorted_intervals; IntervalArray* old_list = _sorted_intervals;
IntervalList* new_list = _new_intervals_from_allocation; IntervalList* new_list = _new_intervals_from_allocation;
int old_len = old_list->length(); int old_len = old_list->length();
int new_len = new_list->length(); int new_len = new_list->length();
@ -1589,7 +1621,8 @@ void LinearScan::sort_intervals_after_allocation() {
new_list->sort(interval_cmp); new_list->sort(interval_cmp);
// merge old and new list (both already sorted) into one combined list // merge old and new list (both already sorted) into one combined list
IntervalArray* combined_list = new IntervalArray(old_len + new_len); int combined_list_len = old_len + new_len;
IntervalArray* combined_list = new IntervalArray(combined_list_len, combined_list_len, NULL);
int old_idx = 0; int old_idx = 0;
int new_idx = 0; int new_idx = 0;
@ -3211,6 +3244,10 @@ void LinearScan::verify_intervals() {
has_error = true; has_error = true;
} }
// special intervals that are created in MoveResolver
// -> ignore them because the range information has no meaning there
if (i1->from() == 1 && i1->to() == 2) continue;
if (i1->first() == Range::end()) { if (i1->first() == Range::end()) {
tty->print_cr("Interval %d has no Range", i1->reg_num()); i1->print(); tty->cr(); tty->print_cr("Interval %d has no Range", i1->reg_num()); i1->print(); tty->cr();
has_error = true; has_error = true;
@ -3225,18 +3262,13 @@ void LinearScan::verify_intervals() {
for (int j = i + 1; j < len; j++) { for (int j = i + 1; j < len; j++) {
Interval* i2 = interval_at(j); Interval* i2 = interval_at(j);
if (i2 == NULL) continue; if (i2 == NULL || (i2->from() == 1 && i2->to() == 2)) continue;
// special intervals that are created in MoveResolver
// -> ignore them because the range information has no meaning there
if (i1->from() == 1 && i1->to() == 2) continue;
if (i2->from() == 1 && i2->to() == 2) continue;
int r1 = i1->assigned_reg(); int r1 = i1->assigned_reg();
int r1Hi = i1->assigned_regHi(); int r1Hi = i1->assigned_regHi();
int r2 = i2->assigned_reg(); int r2 = i2->assigned_reg();
int r2Hi = i2->assigned_regHi(); int r2Hi = i2->assigned_regHi();
if (i1->intersects(i2) && (r1 == r2 || r1 == r2Hi || (r1Hi != any_reg && (r1Hi == r2 || r1Hi == r2Hi)))) { if ((r1 == r2 || r1 == r2Hi || (r1Hi != any_reg && (r1Hi == r2 || r1Hi == r2Hi))) && i1->intersects(i2)) {
tty->print_cr("Intervals %d and %d overlap and have the same register assigned", i1->reg_num(), i2->reg_num()); tty->print_cr("Intervals %d and %d overlap and have the same register assigned", i1->reg_num(), i2->reg_num());
i1->print(); tty->cr(); i1->print(); tty->cr();
i2->print(); tty->cr(); i2->print(); tty->cr();
@ -3429,7 +3461,8 @@ void LinearScan::verify_registers() {
void RegisterVerifier::verify(BlockBegin* start) { void RegisterVerifier::verify(BlockBegin* start) {
// setup input registers (method arguments) for first block // setup input registers (method arguments) for first block
IntervalList* input_state = new IntervalList(state_size(), NULL); int input_state_len = state_size();
IntervalList* input_state = new IntervalList(input_state_len, input_state_len, NULL);
CallingConvention* args = compilation()->frame_map()->incoming_arguments(); CallingConvention* args = compilation()->frame_map()->incoming_arguments();
for (int n = 0; n < args->length(); n++) { for (int n = 0; n < args->length(); n++) {
LIR_Opr opr = args->at(n); LIR_Opr opr = args->at(n);
@ -3543,7 +3576,7 @@ void RegisterVerifier::process_successor(BlockBegin* block, IntervalList* input_
IntervalList* RegisterVerifier::copy(IntervalList* input_state) { IntervalList* RegisterVerifier::copy(IntervalList* input_state) {
IntervalList* copy_state = new IntervalList(input_state->length()); IntervalList* copy_state = new IntervalList(input_state->length());
copy_state->push_all(input_state); copy_state->appendAll(input_state);
return copy_state; return copy_state;
} }
@ -5506,7 +5539,7 @@ void LinearScanWalker::split_and_spill_intersecting_intervals(int reg, int regHi
IntervalList* processed = _spill_intervals[reg]; IntervalList* processed = _spill_intervals[reg];
for (int i = 0; i < _spill_intervals[regHi]->length(); i++) { for (int i = 0; i < _spill_intervals[regHi]->length(); i++) {
Interval* it = _spill_intervals[regHi]->at(i); Interval* it = _spill_intervals[regHi]->at(i);
if (processed->index_of(it) == -1) { if (processed->find_from_end(it) == -1) {
remove_from_list(it); remove_from_list(it);
split_and_spill_interval(it); split_and_spill_interval(it);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,8 +42,8 @@ class LinearScan;
class MoveResolver; class MoveResolver;
class Range; class Range;
define_array(IntervalArray, Interval*) typedef GrowableArray<Interval*> IntervalArray;
define_stack(IntervalList, IntervalArray) typedef GrowableArray<Interval*> IntervalList;
define_array(IntervalsArray, IntervalList*) define_array(IntervalsArray, IntervalList*)
define_stack(IntervalsList, IntervalsArray) define_stack(IntervalsList, IntervalsArray)

View File

@ -107,8 +107,9 @@ ciConstant ciArray::element_value_by_offset(intptr_t element_offset) {
intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt);
intptr_t index = (element_offset - header) >> shift; intptr_t index = (element_offset - header) >> shift;
intptr_t offset = header + ((intptr_t)index << shift); intptr_t offset = header + ((intptr_t)index << shift);
if (offset != element_offset || index != (jint)index) if (offset != element_offset || index != (jint)index || index < 0 || index >= length()) {
return ciConstant(); return ciConstant();
}
return element_value((jint) index); return element_value((jint) index);
} }

View File

@ -41,58 +41,37 @@ ciConstantPoolCache::ciConstantPoolCache(Arena* arena,
_keys = new (arena) GrowableArray<int>(arena, expected_size, 0, 0); _keys = new (arena) GrowableArray<int>(arena, expected_size, 0, 0);
} }
int ciConstantPoolCache::key_compare(const int& key, const int& elt) {
if (key < elt) return -1;
else if (key > elt) return 1;
else return 0;
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciConstantPoolCache::get // ciConstantPoolCache::get
// //
// Get the entry at some index // Get the entry at some index
void* ciConstantPoolCache::get(int index) { void* ciConstantPoolCache::get(int index) {
ASSERT_IN_VM; ASSERT_IN_VM;
int pos = find(index); bool found = false;
if (pos >= _keys->length() || int pos = _keys->find_sorted<int, ciConstantPoolCache::key_compare>(index, found);
_keys->at(pos) != index) { if (!found) {
// This element is not present in the cache. // This element is not present in the cache.
return NULL; return NULL;
} }
return _elements->at(pos); return _elements->at(pos);
} }
// ------------------------------------------------------------------
// ciConstantPoolCache::find
//
// Use binary search to find the position of this index in the cache.
// If there is no entry in the cache corresponding to this oop, return
// the position at which the index would be inserted.
int ciConstantPoolCache::find(int key) {
int min = 0;
int max = _keys->length()-1;
while (max >= min) {
int mid = (max + min) / 2;
int value = _keys->at(mid);
if (value < key) {
min = mid + 1;
} else if (value > key) {
max = mid - 1;
} else {
return mid;
}
}
return min;
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciConstantPoolCache::insert // ciConstantPoolCache::insert
// //
// Insert a ciObject into the table at some index. // Insert a ciObject into the table at some index.
void ciConstantPoolCache::insert(int index, void* elem) { void ciConstantPoolCache::insert(int index, void* elem) {
int i; bool found = false;
int pos = find(index); int pos = _keys->find_sorted<int, ciConstantPoolCache::key_compare>(index, found);
for (i = _keys->length()-1; i >= pos; i--) { assert(!found, "duplicate");
_keys->at_put_grow(i+1, _keys->at(i)); _keys->insert_before(pos, index);
_elements->at_put_grow(i+1, _elements->at(i)); _elements->insert_before(pos, elem);
}
_keys->at_put_grow(pos, index);
_elements->at_put_grow(pos, elem);
} }
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ private:
GrowableArray<int>* _keys; GrowableArray<int>* _keys;
GrowableArray<void*>* _elements; GrowableArray<void*>* _elements;
int find(int index); static int key_compare(const int& key, const int& elt);
public: public:
ciConstantPoolCache(Arena* arena, int expected_size); ciConstantPoolCache(Arena* arena, int expected_size);

View File

@ -260,6 +260,13 @@ ciObject* ciObjectFactory::get(oop key) {
return new_object; return new_object;
} }
int ciObjectFactory::metadata_compare(Metadata* const& key, ciMetadata* const& elt) {
Metadata* value = elt->constant_encoding();
if (key < value) return -1;
else if (key > value) return 1;
else return 0;
}
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// ciObjectFactory::get_metadata // ciObjectFactory::get_metadata
// //
@ -280,7 +287,8 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
} }
#endif // ASSERT #endif // ASSERT
int len = _ci_metadata->length(); int len = _ci_metadata->length();
int index = find(key, _ci_metadata); bool found = false;
int index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
#ifdef ASSERT #ifdef ASSERT
if (CIObjectFactoryVerify) { if (CIObjectFactoryVerify) {
for (int i=0; i<_ci_metadata->length(); i++) { for (int i=0; i<_ci_metadata->length(); i++) {
@ -290,7 +298,8 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
} }
} }
#endif #endif
if (!is_found_at(index, key, _ci_metadata)) {
if (!found) {
// The ciMetadata does not yet exist. Create it and insert it // The ciMetadata does not yet exist. Create it and insert it
// into the cache. // into the cache.
ciMetadata* new_object = create_new_metadata(key); ciMetadata* new_object = create_new_metadata(key);
@ -300,10 +309,10 @@ ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
if (len != _ci_metadata->length()) { if (len != _ci_metadata->length()) {
// creating the new object has recursively entered new objects // creating the new object has recursively entered new objects
// into the table. We need to recompute our index. // into the table. We need to recompute our index.
index = find(key, _ci_metadata); index = _ci_metadata->find_sorted<Metadata*, ciObjectFactory::metadata_compare>(key, found);
} }
assert(!is_found_at(index, key, _ci_metadata), "no double insert"); assert(!found, "no double insert");
insert(index, new_object, _ci_metadata); _ci_metadata->insert_before(index, new_object);
return new_object; return new_object;
} }
return _ci_metadata->at(index)->as_metadata(); return _ci_metadata->at(index)->as_metadata();
@ -655,60 +664,6 @@ void ciObjectFactory::init_ident_of(ciBaseObject* obj) {
obj->set_ident(_next_ident++); obj->set_ident(_next_ident++);
} }
// ------------------------------------------------------------------
// ciObjectFactory::find
//
// Use binary search to find the position of this oop in the cache.
// If there is no entry in the cache corresponding to this oop, return
// the position at which the oop should be inserted.
int ciObjectFactory::find(Metadata* key, GrowableArray<ciMetadata*>* objects) {
int min = 0;
int max = objects->length()-1;
// print_contents();
while (max >= min) {
int mid = (max + min) / 2;
Metadata* value = objects->at(mid)->constant_encoding();
if (value < key) {
min = mid + 1;
} else if (value > key) {
max = mid - 1;
} else {
return mid;
}
}
return min;
}
// ------------------------------------------------------------------
// ciObjectFactory::is_found_at
//
// Verify that the binary seach found the given key.
bool ciObjectFactory::is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects) {
return (index < objects->length() &&
objects->at(index)->constant_encoding() == key);
}
// ------------------------------------------------------------------
// ciObjectFactory::insert
//
// Insert a ciObject into the table at some index.
void ciObjectFactory::insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects) {
int len = objects->length();
if (len == index) {
objects->append(obj);
} else {
objects->append(objects->at(len-1));
int pos;
for (pos = len-2; pos >= index; pos--) {
objects->at_put(pos+1,objects->at(pos));
}
objects->at_put(index, obj);
}
}
static ciObjectFactory::NonPermObject* emptyBucket = NULL; static ciObjectFactory::NonPermObject* emptyBucket = NULL;
// ------------------------------------------------------------------ // ------------------------------------------------------------------

View File

@ -68,9 +68,7 @@ private:
NonPermObject* _non_perm_bucket[NON_PERM_BUCKETS]; NonPermObject* _non_perm_bucket[NON_PERM_BUCKETS];
int _non_perm_count; int _non_perm_count;
int find(Metadata* key, GrowableArray<ciMetadata*>* objects); static int metadata_compare(Metadata* const& key, ciMetadata* const& elt);
bool is_found_at(int index, Metadata* key, GrowableArray<ciMetadata*>* objects);
void insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects);
ciObject* create_new_object(oop o); ciObject* create_new_object(oop o);
ciMetadata* create_new_metadata(Metadata* o); ciMetadata* create_new_metadata(Metadata* o);

View File

@ -5380,7 +5380,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, TRAPS) {
} }
} }
TRACE_INIT_ID(ik); TRACE_INIT_KLASS_ID(ik);
// If we reach here, all is well. // If we reach here, all is well.
// Now remove the InstanceKlass* from the _klass_to_deallocate field // Now remove the InstanceKlass* from the _klass_to_deallocate field

View File

@ -37,6 +37,7 @@
#include "gc/shared/generation.hpp" #include "gc/shared/generation.hpp"
#include "interpreter/bytecodeStream.hpp" #include "interpreter/bytecodeStream.hpp"
#include "interpreter/oopMapCache.hpp" #include "interpreter/oopMapCache.hpp"
#include "logging/logTag.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp" #include "memory/filemap.hpp"
#include "memory/oopFactory.hpp" #include "memory/oopFactory.hpp"
@ -417,34 +418,30 @@ bool ClassPathImageEntry::is_jrt() {
#if INCLUDE_CDS #if INCLUDE_CDS
void ClassLoader::exit_with_path_failure(const char* error, const char* message) { void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
assert(DumpSharedSpaces, "only called at dump time"); assert(DumpSharedSpaces, "only called at dump time");
tty->print_cr("Hint: enable -XX:+TraceClassPaths to diagnose the failure"); tty->print_cr("Hint: enable -Xlog:classpath=info to diagnose the failure");
vm_exit_during_initialization(error, message); vm_exit_during_initialization(error, message);
} }
#endif #endif
void ClassLoader::trace_class_path(outputStream* out, const char* msg, const char* name) { void ClassLoader::trace_class_path(const char* msg, const char* name) {
if (!TraceClassPaths) { if (log_is_enabled(Info, classpath)) {
return; ResourceMark rm;
} outputStream* out = LogHandle(classpath)::info_stream();
if (msg) {
if (msg) { out->print("%s", msg);
out->print("%s", msg); }
} if (name) {
if (name) { if (strlen(name) < 256) {
if (strlen(name) < 256) { out->print("%s", name);
out->print("%s", name); } else {
} else { // For very long paths, we need to print each character separately,
// For very long paths, we need to print each character separately, // as print_cr() has a length limit
// as print_cr() has a length limit while (name[0] != '\0') {
while (name[0] != '\0') { out->print("%c", name[0]);
out->print("%c", name[0]); name++;
name++; }
} }
} }
}
if (msg && msg[0] == '[') {
out->print_cr("]");
} else {
out->cr(); out->cr();
} }
} }
@ -470,11 +467,13 @@ void ClassLoader::check_shared_classpath(const char *path) {
void ClassLoader::setup_bootstrap_search_path() { void ClassLoader::setup_bootstrap_search_path() {
assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); assert(_first_entry == NULL, "should not setup bootstrap class search path twice");
const char* sys_class_path = Arguments::get_sysclasspath(); const char* sys_class_path = Arguments::get_sysclasspath();
const char* java_class_path = Arguments::get_appclasspath();
if (PrintSharedArchiveAndExit) { if (PrintSharedArchiveAndExit) {
// Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily // Don't print sys_class_path - this is the bootcp of this current VM process, not necessarily
// the same as the bootcp of the shared archive. // the same as the bootcp of the shared archive.
} else { } else {
trace_class_path(tty, "[Bootstrap loader class path=", sys_class_path); trace_class_path("bootstrap loader class path=", sys_class_path);
trace_class_path("classpath: ", java_class_path);
} }
#if INCLUDE_CDS #if INCLUDE_CDS
if (DumpSharedSpaces) { if (DumpSharedSpaces) {
@ -578,9 +577,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
} }
} }
} }
if (TraceClassPaths) { log_info(classpath)("opened: %s", path);
tty->print_cr("[Opened %s]", path);
}
log_info(classload)("opened: %s", path); log_info(classload)("opened: %s", path);
} else { } else {
// Directory // Directory

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -331,7 +331,7 @@ class ClassLoader: AllStatic {
static void exit_with_path_failure(const char* error, const char* message); static void exit_with_path_failure(const char* error, const char* message);
#endif #endif
static void trace_class_path(outputStream* out, const char* msg, const char* name = NULL); static void trace_class_path(const char* msg, const char* name = NULL);
// VM monitoring and management support // VM monitoring and management support
static jlong classloader_time_ms(); static jlong classloader_time_ms();

View File

@ -135,8 +135,10 @@ void DictionaryEntry::add_protection_domain(Dictionary* dict, oop protection_dom
// via a store to _pd_set. // via a store to _pd_set.
OrderAccess::release_store_ptr(&_pd_set, new_head); OrderAccess::release_store_ptr(&_pd_set, new_head);
} }
if (TraceProtectionDomainVerification && WizardMode) { if (log_is_enabled(Trace, protectiondomain)) {
print(); ResourceMark rm;
outputStream* log = LogHandle(protectiondomain)::trace_stream();
print_count(log);
} }
} }

View File

@ -29,6 +29,7 @@
#include "oops/instanceKlass.hpp" #include "oops/instanceKlass.hpp"
#include "oops/oop.hpp" #include "oops/oop.hpp"
#include "utilities/hashtable.hpp" #include "utilities/hashtable.hpp"
#include "utilities/ostream.hpp"
class DictionaryEntry; class DictionaryEntry;
class PSPromotionManager; class PSPromotionManager;
@ -323,14 +324,14 @@ class DictionaryEntry : public HashtableEntry<Klass*, mtClass> {
return (klass->name() == class_name && _loader_data == loader_data); return (klass->name() == class_name && _loader_data == loader_data);
} }
void print() { void print_count(outputStream *st) {
int count = 0; int count = 0;
for (ProtectionDomainEntry* current = _pd_set; for (ProtectionDomainEntry* current = _pd_set;
current != NULL; current != NULL;
current = current->_next) { current = current->_next) {
count++; count++;
} }
tty->print_cr("pd set = #%d", count); st->print_cr("pd set count = #%d", count);
} }
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@
#include "classfile/klassFactory.hpp" #include "classfile/klassFactory.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
#include "prims/jvmtiEnvBase.hpp" #include "prims/jvmtiEnvBase.hpp"
#include "trace/traceMacros.hpp"
static ClassFileStream* prologue(ClassFileStream* stream, static ClassFileStream* prologue(ClassFileStream* stream,
Symbol* name, Symbol* name,
@ -136,5 +137,7 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream,
result->set_cached_class_file(cached_class_file); result->set_cached_class_file(cached_class_file);
} }
TRACE_KLASS_CREATION(result, parser, THREAD);
return result; return result;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,15 +26,15 @@
#include "classfile/classLoader.hpp" #include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderData.inline.hpp"
#include "classfile/sharedPathsMiscInfo.hpp" #include "classfile/sharedPathsMiscInfo.hpp"
#include "logging/log.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/metaspaceShared.hpp" #include "memory/metaspaceShared.hpp"
#include "runtime/arguments.hpp" #include "runtime/arguments.hpp"
#include "utilities/ostream.hpp"
void SharedPathsMiscInfo::add_path(const char* path, int type) { void SharedPathsMiscInfo::add_path(const char* path, int type) {
if (TraceClassPaths) { log_info(classpath)("type=%s ", type_name(type));
tty->print("[type=%s] ", type_name(type)); ClassLoader::trace_class_path("add misc shared path ", path);
trace_class_path("[Add misc shared path ", path);
}
write(path, strlen(path) + 1); write(path, strlen(path) + 1);
write_jint(jint(type)); write_jint(jint(type));
} }
@ -67,11 +67,29 @@ bool SharedPathsMiscInfo::read(void* ptr, size_t size) {
} }
bool SharedPathsMiscInfo::fail(const char* msg, const char* name) { bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
ClassLoader::trace_class_path(tty, msg, name); ClassLoader::trace_class_path(msg, name);
MetaspaceShared::set_archive_loading_failed(); MetaspaceShared::set_archive_loading_failed();
return false; return false;
} }
void SharedPathsMiscInfo::print_path(int type, const char* path) {
ResourceMark rm;
outputStream* out = LogHandle(classpath)::info_stream();
switch (type) {
case BOOT:
out->print("Expecting -Dsun.boot.class.path=%s", path);
break;
case NON_EXIST:
out->print("Expecting that %s does not exist", path);
break;
case REQUIRED:
out->print("Expecting that file %s must exist and is not altered", path);
break;
default:
ShouldNotReachHere();
}
}
bool SharedPathsMiscInfo::check() { bool SharedPathsMiscInfo::check() {
// The whole buffer must be 0 terminated so that we can use strlen and strcmp // The whole buffer must be 0 terminated so that we can use strlen and strcmp
// without fear. // without fear.
@ -90,17 +108,14 @@ bool SharedPathsMiscInfo::check() {
if (!read_jint(&type)) { if (!read_jint(&type)) {
return fail("Corrupted archive file header"); return fail("Corrupted archive file header");
} }
if (TraceClassPaths) { log_info(classpath)("type=%s ", type_name(type));
tty->print("[type=%s ", type_name(type)); print_path(type, path);
print_path(tty, type, path);
tty->print_cr("]");
}
if (!check(type, path)) { if (!check(type, path)) {
if (!PrintSharedArchiveAndExit) { if (!PrintSharedArchiveAndExit) {
return false; return false;
} }
} else { } else {
trace_class_path("[ok"); ClassLoader::trace_class_path("ok");
} }
} }

View File

@ -64,9 +64,6 @@ protected:
void write(const void* ptr, size_t size); void write(const void* ptr, size_t size);
bool read(void* ptr, size_t size); bool read(void* ptr, size_t size);
static void trace_class_path(const char* msg, const char* name = NULL) {
ClassLoader::trace_class_path(tty, msg, name);
}
protected: protected:
static bool fail(const char* msg, const char* name = NULL); static bool fail(const char* msg, const char* name = NULL);
virtual bool check(jint type, const char* path); virtual bool check(jint type, const char* path);
@ -144,21 +141,7 @@ public:
} }
} }
virtual void print_path(outputStream* out, int type, const char* path) { virtual void print_path(int type, const char* path);
switch (type) {
case BOOT:
out->print("Expecting -Dsun.boot.class.path=%s", path);
break;
case NON_EXIST:
out->print("Expecting that %s does not exist", path);
break;
case REQUIRED:
out->print("Expecting that file %s must exist and is not altered", path);
break;
default:
ShouldNotReachHere();
}
}
bool check(); bool check();
bool read_jint(jint *ptr) { bool read_jint(jint *ptr) {

View File

@ -430,12 +430,15 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
// Now we have to call back to java to check if the initating class has access // Now we have to call back to java to check if the initating class has access
JavaValue result(T_VOID); JavaValue result(T_VOID);
if (TraceProtectionDomainVerification) { if (log_is_enabled(Debug, protectiondomain)) {
ResourceMark rm;
// Print out trace information // Print out trace information
tty->print_cr("Checking package access"); outputStream* log = LogHandle(protectiondomain)::debug_stream();
tty->print(" - class loader: "); class_loader()->print_value_on(tty); tty->cr(); log->print_cr("Checking package access");
tty->print(" - protection domain: "); protection_domain()->print_value_on(tty); tty->cr(); log->print("class loader: "); class_loader()->print_value_on(log);
tty->print(" - loading: "); klass()->print_value_on(tty); tty->cr(); log->print(" protection domain: "); protection_domain()->print_value_on(log);
log->print(" loading: "); klass()->print_value_on(log);
log->cr();
} }
KlassHandle system_loader(THREAD, SystemDictionary::ClassLoader_klass()); KlassHandle system_loader(THREAD, SystemDictionary::ClassLoader_klass());
@ -448,13 +451,10 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
protection_domain, protection_domain,
THREAD); THREAD);
if (TraceProtectionDomainVerification) { if (HAS_PENDING_EXCEPTION) {
if (HAS_PENDING_EXCEPTION) { log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!");
tty->print_cr(" -> DENIED !!!!!!!!!!!!!!!!!!!!!"); } else {
} else { log_debug(protectiondomain)("granted");
tty->print_cr(" -> granted");
}
tty->cr();
} }
if (HAS_PENDING_EXCEPTION) return; if (HAS_PENDING_EXCEPTION) return;

View File

@ -328,8 +328,6 @@ bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
assert(id != vmIntrinsics::_none, "must be a VM intrinsic"); assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
switch(id) { switch(id) {
#ifdef TRACE_HAVE_INTRINSICS #ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_classID:
case vmIntrinsics::_threadID:
case vmIntrinsics::_counterTime: case vmIntrinsics::_counterTime:
#endif #endif
case vmIntrinsics::_currentTimeMillis: case vmIntrinsics::_currentTimeMillis:
@ -544,6 +542,42 @@ bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
case vmIntrinsics::_putLongVolatile: case vmIntrinsics::_putLongVolatile:
case vmIntrinsics::_putFloatVolatile: case vmIntrinsics::_putFloatVolatile:
case vmIntrinsics::_putDoubleVolatile: case vmIntrinsics::_putDoubleVolatile:
case vmIntrinsics::_getObjectAcquire:
case vmIntrinsics::_getBooleanAcquire:
case vmIntrinsics::_getByteAcquire:
case vmIntrinsics::_getShortAcquire:
case vmIntrinsics::_getCharAcquire:
case vmIntrinsics::_getIntAcquire:
case vmIntrinsics::_getLongAcquire:
case vmIntrinsics::_getFloatAcquire:
case vmIntrinsics::_getDoubleAcquire:
case vmIntrinsics::_putObjectRelease:
case vmIntrinsics::_putBooleanRelease:
case vmIntrinsics::_putByteRelease:
case vmIntrinsics::_putShortRelease:
case vmIntrinsics::_putCharRelease:
case vmIntrinsics::_putIntRelease:
case vmIntrinsics::_putLongRelease:
case vmIntrinsics::_putFloatRelease:
case vmIntrinsics::_putDoubleRelease:
case vmIntrinsics::_getObjectOpaque:
case vmIntrinsics::_getBooleanOpaque:
case vmIntrinsics::_getByteOpaque:
case vmIntrinsics::_getShortOpaque:
case vmIntrinsics::_getCharOpaque:
case vmIntrinsics::_getIntOpaque:
case vmIntrinsics::_getLongOpaque:
case vmIntrinsics::_getFloatOpaque:
case vmIntrinsics::_getDoubleOpaque:
case vmIntrinsics::_putObjectOpaque:
case vmIntrinsics::_putBooleanOpaque:
case vmIntrinsics::_putByteOpaque:
case vmIntrinsics::_putShortOpaque:
case vmIntrinsics::_putCharOpaque:
case vmIntrinsics::_putIntOpaque:
case vmIntrinsics::_putLongOpaque:
case vmIntrinsics::_putFloatOpaque:
case vmIntrinsics::_putDoubleOpaque:
case vmIntrinsics::_getByte_raw: case vmIntrinsics::_getByte_raw:
case vmIntrinsics::_getShort_raw: case vmIntrinsics::_getShort_raw:
case vmIntrinsics::_getChar_raw: case vmIntrinsics::_getChar_raw:
@ -569,9 +603,27 @@ bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
case vmIntrinsics::_loadFence: case vmIntrinsics::_loadFence:
case vmIntrinsics::_storeFence: case vmIntrinsics::_storeFence:
case vmIntrinsics::_fullFence: case vmIntrinsics::_fullFence:
case vmIntrinsics::_compareAndSwapObject:
case vmIntrinsics::_compareAndSwapLong: case vmIntrinsics::_compareAndSwapLong:
case vmIntrinsics::_weakCompareAndSwapLong:
case vmIntrinsics::_weakCompareAndSwapLongAcquire:
case vmIntrinsics::_weakCompareAndSwapLongRelease:
case vmIntrinsics::_compareAndSwapInt: case vmIntrinsics::_compareAndSwapInt:
case vmIntrinsics::_weakCompareAndSwapInt:
case vmIntrinsics::_weakCompareAndSwapIntAcquire:
case vmIntrinsics::_weakCompareAndSwapIntRelease:
case vmIntrinsics::_compareAndSwapObject:
case vmIntrinsics::_weakCompareAndSwapObject:
case vmIntrinsics::_weakCompareAndSwapObjectAcquire:
case vmIntrinsics::_weakCompareAndSwapObjectRelease:
case vmIntrinsics::_compareAndExchangeIntVolatile:
case vmIntrinsics::_compareAndExchangeIntAcquire:
case vmIntrinsics::_compareAndExchangeIntRelease:
case vmIntrinsics::_compareAndExchangeLongVolatile:
case vmIntrinsics::_compareAndExchangeLongAcquire:
case vmIntrinsics::_compareAndExchangeLongRelease:
case vmIntrinsics::_compareAndExchangeObjectVolatile:
case vmIntrinsics::_compareAndExchangeObjectAcquire:
case vmIntrinsics::_compareAndExchangeObjectRelease:
if (!InlineUnsafeOps) return true; if (!InlineUnsafeOps) return true;
break; break;
case vmIntrinsics::_getShortUnaligned: case vmIntrinsics::_getShortUnaligned:

View File

@ -1146,6 +1146,64 @@
do_intrinsic(_putFloatVolatile, jdk_internal_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \ do_intrinsic(_putFloatVolatile, jdk_internal_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
do_intrinsic(_putDoubleVolatile, jdk_internal_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \ do_intrinsic(_putDoubleVolatile, jdk_internal_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \
\ \
do_name(getObjectOpaque_name,"getObjectOpaque") do_name(putObjectOpaque_name,"putObjectOpaque") \
do_name(getBooleanOpaque_name,"getBooleanOpaque") do_name(putBooleanOpaque_name,"putBooleanOpaque") \
do_name(getByteOpaque_name,"getByteOpaque") do_name(putByteOpaque_name,"putByteOpaque") \
do_name(getShortOpaque_name,"getShortOpaque") do_name(putShortOpaque_name,"putShortOpaque") \
do_name(getCharOpaque_name,"getCharOpaque") do_name(putCharOpaque_name,"putCharOpaque") \
do_name(getIntOpaque_name,"getIntOpaque") do_name(putIntOpaque_name,"putIntOpaque") \
do_name(getLongOpaque_name,"getLongOpaque") do_name(putLongOpaque_name,"putLongOpaque") \
do_name(getFloatOpaque_name,"getFloatOpaque") do_name(putFloatOpaque_name,"putFloatOpaque") \
do_name(getDoubleOpaque_name,"getDoubleOpaque") do_name(putDoubleOpaque_name,"putDoubleOpaque") \
\
do_intrinsic(_getObjectOpaque, jdk_internal_misc_Unsafe, getObjectOpaque_name, getObject_signature, F_R) \
do_intrinsic(_getBooleanOpaque, jdk_internal_misc_Unsafe, getBooleanOpaque_name, getBoolean_signature, F_R) \
do_intrinsic(_getByteOpaque, jdk_internal_misc_Unsafe, getByteOpaque_name, getByte_signature, F_R) \
do_intrinsic(_getShortOpaque, jdk_internal_misc_Unsafe, getShortOpaque_name, getShort_signature, F_R) \
do_intrinsic(_getCharOpaque, jdk_internal_misc_Unsafe, getCharOpaque_name, getChar_signature, F_R) \
do_intrinsic(_getIntOpaque, jdk_internal_misc_Unsafe, getIntOpaque_name, getInt_signature, F_R) \
do_intrinsic(_getLongOpaque, jdk_internal_misc_Unsafe, getLongOpaque_name, getLong_signature, F_R) \
do_intrinsic(_getFloatOpaque, jdk_internal_misc_Unsafe, getFloatOpaque_name, getFloat_signature, F_R) \
do_intrinsic(_getDoubleOpaque, jdk_internal_misc_Unsafe, getDoubleOpaque_name, getDouble_signature, F_R) \
do_intrinsic(_putObjectOpaque, jdk_internal_misc_Unsafe, putObjectOpaque_name, putObject_signature, F_R) \
do_intrinsic(_putBooleanOpaque, jdk_internal_misc_Unsafe, putBooleanOpaque_name, putBoolean_signature, F_R) \
do_intrinsic(_putByteOpaque, jdk_internal_misc_Unsafe, putByteOpaque_name, putByte_signature, F_R) \
do_intrinsic(_putShortOpaque, jdk_internal_misc_Unsafe, putShortOpaque_name, putShort_signature, F_R) \
do_intrinsic(_putCharOpaque, jdk_internal_misc_Unsafe, putCharOpaque_name, putChar_signature, F_R) \
do_intrinsic(_putIntOpaque, jdk_internal_misc_Unsafe, putIntOpaque_name, putInt_signature, F_R) \
do_intrinsic(_putLongOpaque, jdk_internal_misc_Unsafe, putLongOpaque_name, putLong_signature, F_R) \
do_intrinsic(_putFloatOpaque, jdk_internal_misc_Unsafe, putFloatOpaque_name, putFloat_signature, F_R) \
do_intrinsic(_putDoubleOpaque, jdk_internal_misc_Unsafe, putDoubleOpaque_name, putDouble_signature, F_R) \
\
do_name(getObjectAcquire_name, "getObjectAcquire") do_name(putObjectRelease_name, "putObjectRelease") \
do_name(getBooleanAcquire_name, "getBooleanAcquire") do_name(putBooleanRelease_name, "putBooleanRelease") \
do_name(getByteAcquire_name, "getByteAcquire") do_name(putByteRelease_name, "putByteRelease") \
do_name(getShortAcquire_name, "getShortAcquire") do_name(putShortRelease_name, "putShortRelease") \
do_name(getCharAcquire_name, "getCharAcquire") do_name(putCharRelease_name, "putCharRelease") \
do_name(getIntAcquire_name, "getIntAcquire") do_name(putIntRelease_name, "putIntRelease") \
do_name(getLongAcquire_name, "getLongAcquire") do_name(putLongRelease_name, "putLongRelease") \
do_name(getFloatAcquire_name, "getFloatAcquire") do_name(putFloatRelease_name, "putFloatRelease") \
do_name(getDoubleAcquire_name, "getDoubleAcquire") do_name(putDoubleRelease_name, "putDoubleRelease") \
\
do_intrinsic(_getObjectAcquire, jdk_internal_misc_Unsafe, getObjectAcquire_name, getObject_signature, F_R) \
do_intrinsic(_getBooleanAcquire, jdk_internal_misc_Unsafe, getBooleanAcquire_name, getBoolean_signature, F_R) \
do_intrinsic(_getByteAcquire, jdk_internal_misc_Unsafe, getByteAcquire_name, getByte_signature, F_R) \
do_intrinsic(_getShortAcquire, jdk_internal_misc_Unsafe, getShortAcquire_name, getShort_signature, F_R) \
do_intrinsic(_getCharAcquire, jdk_internal_misc_Unsafe, getCharAcquire_name, getChar_signature, F_R) \
do_intrinsic(_getIntAcquire, jdk_internal_misc_Unsafe, getIntAcquire_name, getInt_signature, F_R) \
do_intrinsic(_getLongAcquire, jdk_internal_misc_Unsafe, getLongAcquire_name, getLong_signature, F_R) \
do_intrinsic(_getFloatAcquire, jdk_internal_misc_Unsafe, getFloatAcquire_name, getFloat_signature, F_R) \
do_intrinsic(_getDoubleAcquire, jdk_internal_misc_Unsafe, getDoubleAcquire_name, getDouble_signature, F_R) \
do_intrinsic(_putObjectRelease, jdk_internal_misc_Unsafe, putObjectRelease_name, putObject_signature, F_R) \
do_intrinsic(_putBooleanRelease, jdk_internal_misc_Unsafe, putBooleanRelease_name, putBoolean_signature, F_R) \
do_intrinsic(_putByteRelease, jdk_internal_misc_Unsafe, putByteRelease_name, putByte_signature, F_R) \
do_intrinsic(_putShortRelease, jdk_internal_misc_Unsafe, putShortRelease_name, putShort_signature, F_R) \
do_intrinsic(_putCharRelease, jdk_internal_misc_Unsafe, putCharRelease_name, putChar_signature, F_R) \
do_intrinsic(_putIntRelease, jdk_internal_misc_Unsafe, putIntRelease_name, putInt_signature, F_R) \
do_intrinsic(_putLongRelease, jdk_internal_misc_Unsafe, putLongRelease_name, putLong_signature, F_R) \
do_intrinsic(_putFloatRelease, jdk_internal_misc_Unsafe, putFloatRelease_name, putFloat_signature, F_R) \
do_intrinsic(_putDoubleRelease, jdk_internal_misc_Unsafe, putDoubleRelease_name, putDouble_signature, F_R) \
\
do_name(getShortUnaligned_name,"getShortUnaligned") do_name(putShortUnaligned_name,"putShortUnaligned") \ do_name(getShortUnaligned_name,"getShortUnaligned") do_name(putShortUnaligned_name,"putShortUnaligned") \
do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \ do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \
do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \ do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \
@ -1197,24 +1255,68 @@
do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \ do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \
do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \ do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \
\ \
do_intrinsic(_compareAndSwapObject, jdk_internal_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_R) \ do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
do_name( compareAndSwapObject_name, "compareAndSwapObject") \ do_signature(compareAndExchangeObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \
do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \ do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
do_intrinsic(_compareAndSwapLong, jdk_internal_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_R) \ do_signature(compareAndExchangeLong_signature, "(Ljava/lang/Object;JJJ)J") \
do_name( compareAndSwapLong_name, "compareAndSwapLong") \ do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \ do_signature(compareAndExchangeInt_signature, "(Ljava/lang/Object;JII)I") \
do_intrinsic(_compareAndSwapInt, jdk_internal_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_R) \ \
do_name( compareAndSwapInt_name, "compareAndSwapInt") \ do_name(compareAndSwapObject_name, "compareAndSwapObject") \
do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \ do_name(compareAndExchangeObjectVolatile_name, "compareAndExchangeObjectVolatile") \
do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_R) \ do_name(compareAndExchangeObjectAcquire_name, "compareAndExchangeObjectAcquire") \
do_name( putOrderedObject_name, "putOrderedObject") \ do_name(compareAndExchangeObjectRelease_name, "compareAndExchangeObjectRelease") \
do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \ do_name(compareAndSwapLong_name, "compareAndSwapLong") \
do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_R) \ do_name(compareAndExchangeLongVolatile_name, "compareAndExchangeLongVolatile") \
do_name( putOrderedLong_name, "putOrderedLong") \ do_name(compareAndExchangeLongAcquire_name, "compareAndExchangeLongAcquire") \
do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \ do_name(compareAndExchangeLongRelease_name, "compareAndExchangeLongRelease") \
do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_R) \ do_name(compareAndSwapInt_name, "compareAndSwapInt") \
do_name( putOrderedInt_name, "putOrderedInt") \ do_name(compareAndExchangeIntVolatile_name, "compareAndExchangeIntVolatile") \
do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \ do_name(compareAndExchangeIntAcquire_name, "compareAndExchangeIntAcquire") \
do_name(compareAndExchangeIntRelease_name, "compareAndExchangeIntRelease") \
\
do_name(weakCompareAndSwapObject_name, "weakCompareAndSwapObject") \
do_name(weakCompareAndSwapObjectAcquire_name, "weakCompareAndSwapObjectAcquire") \
do_name(weakCompareAndSwapObjectRelease_name, "weakCompareAndSwapObjectRelease") \
do_name(weakCompareAndSwapLong_name, "weakCompareAndSwapLong") \
do_name(weakCompareAndSwapLongAcquire_name, "weakCompareAndSwapLongAcquire") \
do_name(weakCompareAndSwapLongRelease_name, "weakCompareAndSwapLongRelease") \
do_name(weakCompareAndSwapInt_name, "weakCompareAndSwapInt") \
do_name(weakCompareAndSwapIntAcquire_name, "weakCompareAndSwapIntAcquire") \
do_name(weakCompareAndSwapIntRelease_name, "weakCompareAndSwapIntRelease") \
\
do_intrinsic(_compareAndSwapObject, jdk_internal_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_RN) \
do_intrinsic(_compareAndExchangeObjectVolatile, jdk_internal_misc_Unsafe, compareAndExchangeObjectVolatile_name, compareAndExchangeObject_signature, F_RN) \
do_intrinsic(_compareAndExchangeObjectAcquire, jdk_internal_misc_Unsafe, compareAndExchangeObjectAcquire_name, compareAndExchangeObject_signature, F_R) \
do_intrinsic(_compareAndExchangeObjectRelease, jdk_internal_misc_Unsafe, compareAndExchangeObjectRelease_name, compareAndExchangeObject_signature, F_R) \
do_intrinsic(_compareAndSwapLong, jdk_internal_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_RN) \
do_intrinsic(_compareAndExchangeLongVolatile, jdk_internal_misc_Unsafe, compareAndExchangeLongVolatile_name, compareAndExchangeLong_signature, F_RN) \
do_intrinsic(_compareAndExchangeLongAcquire, jdk_internal_misc_Unsafe, compareAndExchangeLongAcquire_name, compareAndExchangeLong_signature, F_R) \
do_intrinsic(_compareAndExchangeLongRelease, jdk_internal_misc_Unsafe, compareAndExchangeLongRelease_name, compareAndExchangeLong_signature, F_R) \
do_intrinsic(_compareAndSwapInt, jdk_internal_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_RN) \
do_intrinsic(_compareAndExchangeIntVolatile, jdk_internal_misc_Unsafe, compareAndExchangeIntVolatile_name, compareAndExchangeInt_signature, F_RN) \
do_intrinsic(_compareAndExchangeIntAcquire, jdk_internal_misc_Unsafe, compareAndExchangeIntAcquire_name, compareAndExchangeInt_signature, F_R) \
do_intrinsic(_compareAndExchangeIntRelease, jdk_internal_misc_Unsafe, compareAndExchangeIntRelease_name, compareAndExchangeInt_signature, F_R) \
\
do_intrinsic(_weakCompareAndSwapObject, jdk_internal_misc_Unsafe, weakCompareAndSwapObject_name, compareAndSwapObject_signature, F_R) \
do_intrinsic(_weakCompareAndSwapObjectAcquire, jdk_internal_misc_Unsafe, weakCompareAndSwapObjectAcquire_name, compareAndSwapObject_signature, F_R) \
do_intrinsic(_weakCompareAndSwapObjectRelease, jdk_internal_misc_Unsafe, weakCompareAndSwapObjectRelease_name, compareAndSwapObject_signature, F_R) \
do_intrinsic(_weakCompareAndSwapLong, jdk_internal_misc_Unsafe, weakCompareAndSwapLong_name, compareAndSwapLong_signature, F_R) \
do_intrinsic(_weakCompareAndSwapLongAcquire, jdk_internal_misc_Unsafe, weakCompareAndSwapLongAcquire_name, compareAndSwapLong_signature, F_R) \
do_intrinsic(_weakCompareAndSwapLongRelease, jdk_internal_misc_Unsafe, weakCompareAndSwapLongRelease_name, compareAndSwapLong_signature, F_R) \
do_intrinsic(_weakCompareAndSwapInt, jdk_internal_misc_Unsafe, weakCompareAndSwapInt_name, compareAndSwapInt_signature, F_R) \
do_intrinsic(_weakCompareAndSwapIntAcquire, jdk_internal_misc_Unsafe, weakCompareAndSwapIntAcquire_name, compareAndSwapInt_signature, F_R) \
do_intrinsic(_weakCompareAndSwapIntRelease, jdk_internal_misc_Unsafe, weakCompareAndSwapIntRelease_name, compareAndSwapInt_signature, F_R) \
\
do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \
do_name( putOrderedObject_name, "putOrderedObject") \
do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \
do_name( putOrderedLong_name, "putOrderedLong") \
do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \
do_name( putOrderedInt_name, "putOrderedInt") \
do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
\ \
do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \ do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
do_name( getAndAddInt_name, "getAndAddInt") \ do_name( getAndAddInt_name, "getAndAddInt") \

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