This commit is contained in:
Alejandro Murillo 2016-06-02 14:58:50 -07:00
commit faccce5581
424 changed files with 8577 additions and 6471 deletions

View File

@ -144,42 +144,6 @@ def isJVMCIEnabled(vm):
assert vm in _jdkJvmVariants
return True
class JvmciJDKDeployedDist(object):
def __init__(self, name, compilers=False):
self._name = name
self._compilers = compilers
def dist(self):
return mx.distribution(self._name)
def deploy(self, jdkDir):
mx.nyi('deploy', self)
def post_parse_cmd_line(self):
self.set_archiveparticipant()
def set_archiveparticipant(self):
dist = self.dist()
dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))
class ExtJDKDeployedDist(JvmciJDKDeployedDist):
def __init__(self, name):
JvmciJDKDeployedDist.__init__(self, name)
"""
The monolithic JVMCI distribution is deployed through use of -Xbootclasspath/p
so that it's not necessary to run JDK make after editing JVMCI sources.
The latter causes all JDK Java sources to be rebuilt since JVMCI is
(currently) in java.base.
"""
_monolithicJvmci = JvmciJDKDeployedDist('JVMCI')
"""
List of distributions that are deployed on the boot class path.
Note: In jvmci-8, they were deployed directly into the JDK directory.
"""
jdkDeployedDists = [_monolithicJvmci]
def _makehelp():
return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
@ -194,7 +158,7 @@ To build hotspot and import it into the JDK: "mx make hotspot import-hotspot"
# JDK9 must be bootstrapped with a JDK8
compliance = mx.JavaCompliance('8')
jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=none', '--disable-precompiled-headers',
cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=external', '--disable-precompiled-headers',
'--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home]
mx.run(cmd, cwd=_jdkSourceRoot)
cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
@ -217,7 +181,10 @@ To build hotspot and import it into the JDK: "mx make hotspot import-hotspot"
# The OpenJDK build creates an empty cacerts file so copy one from
# the default JDK (which is assumed to be an OracleJDK)
srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
srcCerts = join(mx.get_jdk(tag='default').home, 'lib', 'security', 'cacerts')
if not exists(srcCerts):
# Might be building with JDK8 which has cacerts under jre/
srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
dstCerts = join(jdkImageDir, 'lib', 'security', 'cacerts')
shutil.copyfile(srcCerts, dstCerts)
@ -673,24 +640,6 @@ def jol(args):
run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
class JVMCIArchiveParticipant:
def __init__(self, dist):
self.dist = dist
def __opened__(self, arc, srcArc, services):
self.services = services
self.jvmciServices = services
self.arc = arc
def __add__(self, arcname, contents):
return False
def __addsrc__(self, arcname, contents):
return False
def __closing__(self):
pass
def _get_openjdk_os():
# See: common/autoconf/platform.m4
os = mx.get_os()
@ -744,10 +693,6 @@ def _get_hotspot_build_dir(jvmVariant=None, debugLevel=None):
name = '{}_{}_{}'.format(os, arch, buildname)
return join(_get_jdk_build_dir(debugLevel=debugLevel), 'hotspot', name)
def add_bootclasspath_prepend(dep):
assert isinstance(dep, mx.ClasspathDependency)
_jvmci_bootclasspath_prepends.append(dep)
class JVMCI9JDKConfig(mx.JDKConfig):
def __init__(self, debugLevel):
self.debugLevel = debugLevel
@ -771,20 +716,6 @@ class JVMCI9JDKConfig(mx.JDKConfig):
cp = os.pathsep.join([e for e in cp.split(os.pathsep) if e not in excluded])
args[cpIndex] = cp
jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
if jvmciModeArgs:
bcpDeps = [jdkDist.dist() for jdkDist in jdkDeployedDists]
if bcpDeps:
args = ['-Xbootclasspath/p:' + os.pathsep.join([d.classpath_repr() for d in bcpDeps])] + args
# Set the default JVMCI compiler
for jdkDist in reversed(jdkDeployedDists):
assert isinstance(jdkDist, JvmciJDKDeployedDist), jdkDist
if jdkDist._compilers:
jvmciCompiler = jdkDist._compilers[-1]
args = ['-Djvmci.compiler=' + jvmciCompiler] + args
break
if '-version' in args:
ignoredArgs = args[args.index('-version') + 1:]
if len(ignoredArgs) > 0:
@ -877,41 +808,3 @@ def mx_post_parse_cmd_line(opts):
mx.warn('Ignoring "--jvmci-mode" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
_vm.update(jvmVariant, debugLevel, jvmciMode)
for jdkDist in jdkDeployedDists:
jdkDist.post_parse_cmd_line()
def _update_JDK9_STUBS_library():
"""
Sets the "path" and "sha1" attributes of the "JDK9_STUBS" library.
"""
jdk9InternalLib = _suite.suiteDict['libraries']['JDK9_STUBS']
jarInputDir = join(_suite.get_output_root(), 'jdk9-stubs')
jarPath = join(_suite.get_output_root(), 'jdk9-stubs.jar')
stubs = [
('jdk.internal.misc', 'VM', """package jdk.internal.misc;
public class VM {
public static String getSavedProperty(String key) {
throw new InternalError("should not reach here");
}
}
""")
]
if not exists(jarPath):
sourceFiles = []
for (package, className, source) in stubs:
sourceFile = join(jarInputDir, package.replace('.', os.sep), className + '.java')
mx.ensure_dir_exists(os.path.dirname(sourceFile))
with open(sourceFile, 'w') as fp:
fp.write(source)
sourceFiles.append(sourceFile)
jdk = mx.get_jdk(tag='default')
mx.run([jdk.javac, '-d', jarInputDir] + sourceFiles)
mx.run([jdk.jar, 'cf', jarPath, '.'], cwd=jarInputDir)
jdk9InternalLib['path'] = jarPath
jdk9InternalLib['sha1'] = mx.sha1OfFile(jarPath)
_update_JDK9_STUBS_library()

View File

@ -1,5 +1,5 @@
suite = {
"mxversion" : "5.6.16",
"mxversion" : "5.23.1",
"name" : "jvmci",
"url" : "http://openjdk.java.net/projects/graal",
"developer" : {
@ -36,13 +36,6 @@ suite = {
"urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"],
"sha1" : "6feb3e964aeb7097aff30c372aac3ec0f8d87ede",
},
# Stubs for classes introduced in JDK9 that allow compilation with a JDK8 javac and Eclipse.
# The "path" and "sha1" attributes are added when mx_jvmci is loaded
# (see mx_jvmci._update_JDK9_STUBS_library()).
"JDK9_STUBS" : {
"license" : "GPLv2-CPE",
},
},
"projects" : {
@ -52,7 +45,7 @@ suite = {
"jdk.vm.ci.services" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -62,7 +55,7 @@ suite = {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -70,7 +63,7 @@ suite = {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -79,7 +72,7 @@ suite = {
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.meta"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -94,7 +87,7 @@ suite = {
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -103,9 +96,10 @@ suite = {
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.code",
"jdk.vm.ci.services",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -118,18 +112,10 @@ suite = {
"jdk.vm.ci.runtime",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
"jdk.vm.ci.inittimer" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"workingSets" : "JVMCI",
},
# ------------- JVMCI:HotSpot -------------
"jdk.vm.ci.aarch64" : {
@ -137,7 +123,7 @@ suite = {
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.code"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,AArch64",
},
@ -146,7 +132,7 @@ suite = {
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.code"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,AMD64",
},
@ -155,7 +141,7 @@ suite = {
"sourceDirs" : ["src"],
"dependencies" : ["jdk.vm.ci.code"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,SPARC",
},
@ -165,13 +151,15 @@ suite = {
"dependencies" : [
"jdk.vm.ci.hotspotvmconfig",
"jdk.vm.ci.common",
"jdk.vm.ci.inittimer",
"jdk.vm.ci.runtime",
"jdk.vm.ci.services",
"JDK9_STUBS",
],
"imports" : [
"jdk.internal.misc",
"jdk.internal.org.objectweb.asm",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI",
},
@ -183,7 +171,7 @@ suite = {
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "API,JVMCI",
},
@ -191,7 +179,7 @@ suite = {
"subDir" : "src/jdk.vm.ci/share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,HotSpot",
},
@ -203,7 +191,7 @@ suite = {
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,HotSpot,AArch64",
},
@ -215,7 +203,7 @@ suite = {
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,HotSpot,AMD64",
},
@ -227,7 +215,7 @@ suite = {
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "1.8",
"javaCompliance" : "9",
"workingSets" : "JVMCI,HotSpot,SPARC",
},
@ -249,7 +237,6 @@ suite = {
"JVMCI_API" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"dependencies" : [
"jdk.vm.ci.inittimer",
"jdk.vm.ci.runtime",
"jdk.vm.ci.common",
"jdk.vm.ci.aarch64",
@ -292,31 +279,5 @@ suite = {
],
"exclude" : ["mx:JUNIT"],
},
# This exists to have a monolithic jvmci.jar file which simplifies
# using the -Xoverride option in JDK9.
"JVMCI" : {
"subDir" : "src/jdk.vm.ci/share/classes",
"overlaps" : [
"JVMCI_API",
"JVMCI_SERVICES",
"JVMCI_HOTSPOT",
"JVMCI_HOTSPOTVMCONFIG",
],
"dependencies" : [
"jdk.vm.ci.services",
"jdk.vm.ci.inittimer",
"jdk.vm.ci.runtime",
"jdk.vm.ci.common",
"jdk.vm.ci.aarch64",
"jdk.vm.ci.amd64",
"jdk.vm.ci.sparc",
"jdk.vm.ci.hotspotvmconfig",
"jdk.vm.ci.hotspot.aarch64",
"jdk.vm.ci.hotspot.amd64",
"jdk.vm.ci.hotspot.sparc",
],
"exclude" : ["JDK9_STUBS"]
},
},
}

View File

@ -3331,7 +3331,6 @@ const bool Matcher::match_rule_supported(int opcode) {
switch (opcode) {
case Op_StrComp:
case Op_StrIndexOf:
if (CompactStrings) return false;
break;
default:
@ -4744,7 +4743,8 @@ encode %{
__ br(Assembler::EQ, cont);
} else {
Label retry_load;
__ prfm(Address(oop), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
__ prfm(Address(oop), PSTL1STRM);
__ bind(retry_load);
__ ldaxr(tmp, oop);
__ cmp(tmp, disp_hdr);
@ -4799,7 +4799,8 @@ encode %{
__ cmp(rscratch1, disp_hdr);
} else {
Label retry_load, fail;
__ prfm(Address(tmp), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
__ prfm(Address(tmp), PSTL1STRM);
__ bind(retry_load);
__ ldaxr(rscratch1, tmp);
__ cmp(disp_hdr, rscratch1);
@ -4893,7 +4894,8 @@ encode %{
__ cmp(tmp, box);
} else {
Label retry_load;
__ prfm(Address(oop), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
__ prfm(Address(oop), PSTL1STRM);
__ bind(retry_load);
__ ldxr(tmp, oop);
__ cmp(box, tmp);
@ -14953,26 +14955,83 @@ instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 c
ins_pipe(pipe_class_memory);
%}
instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result" %}
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
-1, $result$$Register);
-1, $result$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
-1, $result$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
-1, $result$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexofLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LU)" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
-1, $result$$Register, StrIntrinsicNode::LU);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
@ -14980,7 +15039,7 @@ instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result" %}
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
@ -14988,7 +15047,70 @@ instruct string_indexof_con(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
$cnt1$$Register, zr,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
icnt2, $result$$Register);
icnt2, $result$$Register, StrIntrinsicNode::UU);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, zr,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
icnt2, $result$$Register, StrIntrinsicNode::LL);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, zr,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
icnt2, $result$$Register, StrIntrinsicNode::UL);
%}
ins_pipe(pipe_class_memory);
%}
instruct string_indexof_conLU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2,
immI_1 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LU);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LU)" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, zr,
$tmp1$$Register, $tmp2$$Register,
$tmp3$$Register, $tmp4$$Register,
icnt2, $result$$Register, StrIntrinsicNode::LU);
%}
ins_pipe(pipe_class_memory);
%}

View File

@ -23,8 +23,8 @@
*
*/
#ifndef CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
#define CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
#ifndef CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP
#define CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP
// ArrayCopyStub needs access to bailout
friend class ArrayCopyStub;
@ -78,4 +78,4 @@ enum { call_stub_size = 12 * NativeInstruction::instruction_size,
exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(175),
deopt_handler_size = 7 * NativeInstruction::instruction_size };
#endif // CPU_X86_VM_C1_LIRASSEMBLER_X86_HPP
#endif // CPU_AARCH64_VM_C1_LIRASSEMBLER_AARCH64_HPP

View File

@ -92,9 +92,11 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
#ifndef PRODUCT
NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
// read the value once
volatile intptr_t data = method_holder->data();
assert(data == 0 || data == (intptr_t)callee(),
"a) MT-unsafe modification of inline cache");
assert(method_holder->data() == 0 || jump->jump_destination() == entry,
assert(data == 0 || jump->jump_destination() == entry,
"b) MT-unsafe modification of inline cache");
#endif
// Update stub.

View File

@ -1643,7 +1643,8 @@ void MacroAssembler::atomic_incw(Register counter_addr, Register tmp, Register t
return;
}
Label retry_load;
prfm(Address(counter_addr), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
prfm(Address(counter_addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
ldxrw(tmp, counter_addr);
@ -2084,7 +2085,8 @@ void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Reg
membar(AnyAny);
} else {
Label retry_load, nope;
prfm(Address(addr), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
@ -2120,7 +2122,8 @@ void MacroAssembler::cmpxchgw(Register oldv, Register newv, Register addr, Regis
membar(AnyAny);
} else {
Label retry_load, nope;
prfm(Address(addr), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
// flush and load exclusive from the memory location
// and fail if it is not what we expect
@ -2155,7 +2158,8 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
} else {
BLOCK_COMMENT("cmpxchg {");
Label retry_load, done;
prfm(Address(addr), PSTL1STRM);
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH))
prfm(Address(addr), PSTL1STRM);
bind(retry_load);
load_exclusive(tmp, addr, size, acquire);
if (size == xword)
@ -2194,7 +2198,8 @@ void MacroAssembler::atomic_##NAME(Register prev, RegisterOrConstant incr, Regis
result = different(prev, incr, addr) ? prev : rscratch2; \
\
Label retry_load; \
prfm(Address(addr), PSTL1STRM); \
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
prfm(Address(addr), PSTL1STRM); \
bind(retry_load); \
LDXR(result, addr); \
OP(rscratch1, result, incr); \
@ -2224,7 +2229,8 @@ void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) {
result = different(prev, newv, addr) ? prev : rscratch2; \
\
Label retry_load; \
prfm(Address(addr), PSTL1STRM); \
if ((VM_Version::features() & VM_Version::CPU_STXR_PREFETCH)) \
prfm(Address(addr), PSTL1STRM); \
bind(retry_load); \
LDXR(result, addr); \
STXR(rscratch1, newv, addr); \
@ -4136,13 +4142,14 @@ void MacroAssembler::remove_frame(int framesize) {
}
}
typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
// Search for str1 in str2 and return index or -1
void MacroAssembler::string_indexof(Register str2, Register str1,
Register cnt2, Register cnt1,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
int icnt1, Register result) {
int icnt1, Register result, int ae) {
Label BM, LINEARSEARCH, DONE, NOMATCH, MATCH;
Register ch1 = rscratch1;
@ -4153,6 +4160,21 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
Register cnt2_neg = cnt2;
Register result_tmp = tmp4;
bool isL = ae == StrIntrinsicNode::LL;
bool str1_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL;
bool str2_isL = ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::LU;
int str1_chr_shift = str1_isL ? 0:1;
int str2_chr_shift = str2_isL ? 0:1;
int str1_chr_size = str1_isL ? 1:2;
int str2_chr_size = str2_isL ? 1:2;
chr_insn str1_load_1chr = str1_isL ? (chr_insn)&MacroAssembler::ldrb :
(chr_insn)&MacroAssembler::ldrh;
chr_insn str2_load_1chr = str2_isL ? (chr_insn)&MacroAssembler::ldrb :
(chr_insn)&MacroAssembler::ldrh;
chr_insn load_2chr = isL ? (chr_insn)&MacroAssembler::ldrh : (chr_insn)&MacroAssembler::ldrw;
chr_insn load_4chr = isL ? (chr_insn)&MacroAssembler::ldrw : (chr_insn)&MacroAssembler::ldr;
// Note, inline_string_indexOf() generates checks:
// if (substr.count > string.count) return -1;
// if (substr.count == 0) return 0;
@ -4242,7 +4264,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
mov(cnt1tmp, 0);
sub(cnt1end, cnt1, 1);
BIND(BCLOOP);
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
cmp(ch1, 128);
add(cnt1tmp, cnt1tmp, 1);
br(HS, BCSKIP);
@ -4254,36 +4276,36 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
mov(result_tmp, str2);
sub(cnt2, cnt2, cnt1);
add(str2end, str2, cnt2, LSL, 1);
add(str2end, str2, cnt2, LSL, str2_chr_shift);
BIND(BMLOOPSTR2);
sub(cnt1tmp, cnt1, 1);
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
ldrh(skipch, Address(str2, cnt1tmp, Address::lsl(1)));
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
(this->*str2_load_1chr)(skipch, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
cmp(ch1, skipch);
br(NE, BMSKIP);
subs(cnt1tmp, cnt1tmp, 1);
br(LT, BMMATCH);
BIND(BMLOOPSTR1);
ldrh(ch1, Address(str1, cnt1tmp, Address::lsl(1)));
ldrh(ch2, Address(str2, cnt1tmp, Address::lsl(1)));
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp, Address::lsl(str1_chr_shift)));
(this->*str2_load_1chr)(ch2, Address(str2, cnt1tmp, Address::lsl(str2_chr_shift)));
cmp(ch1, ch2);
br(NE, BMSKIP);
subs(cnt1tmp, cnt1tmp, 1);
br(GE, BMLOOPSTR1);
BIND(BMMATCH);
sub(result_tmp, str2, result_tmp);
lsr(result, result_tmp, 1);
sub(result, str2, result_tmp);
if (!str2_isL) lsr(result, result, 1);
add(sp, sp, 128);
b(DONE);
BIND(BMADV);
add(str2, str2, 2);
add(str2, str2, str2_chr_size);
b(BMCHECKEND);
BIND(BMSKIP);
cmp(skipch, 128);
br(HS, BMADV);
ldrb(ch2, Address(sp, skipch));
add(str2, str2, cnt1, LSL, 1);
sub(str2, str2, ch2, LSL, 1);
add(str2, str2, cnt1, LSL, str2_chr_shift);
sub(str2, str2, ch2, LSL, str2_chr_shift);
BIND(BMCHECKEND);
cmp(str2, str2end);
br(LE, BMLOOPSTR2);
@ -4300,119 +4322,113 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
if (icnt1 == -1)
{
Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT, LAST_WORD;
Label DOSHORT, FIRST_LOOP, STR2_NEXT, STR1_LOOP, STR1_NEXT;
cmp(cnt1, 4);
cmp(cnt1, str1_isL == str2_isL ? 4 : 2);
br(LT, DOSHORT);
sub(cnt2, cnt2, cnt1);
sub(cnt1, cnt1, 4);
mov(result_tmp, cnt2);
lea(str1, Address(str1, cnt1, Address::uxtw(1)));
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt1_neg, zr, cnt1, LSL, 1);
sub(cnt2_neg, zr, cnt2, LSL, 1);
ldr(first, Address(str1, cnt1_neg));
lea(str1, Address(str1, cnt1, Address::lsl(str1_chr_shift)));
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt1_neg, zr, cnt1, LSL, str1_chr_shift);
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
(this->*str1_load_1chr)(first, Address(str1, cnt1_neg));
BIND(FIRST_LOOP);
ldr(ch2, Address(str2, cnt2_neg));
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
cmp(first, ch2);
br(EQ, STR1_LOOP);
BIND(STR2_NEXT);
adds(cnt2_neg, cnt2_neg, 2);
adds(cnt2_neg, cnt2_neg, str2_chr_size);
br(LE, FIRST_LOOP);
b(NOMATCH);
BIND(STR1_LOOP);
adds(cnt1tmp, cnt1_neg, 8);
add(cnt2tmp, cnt2_neg, 8);
br(GE, LAST_WORD);
adds(cnt1tmp, cnt1_neg, str1_chr_size);
add(cnt2tmp, cnt2_neg, str2_chr_size);
br(GE, MATCH);
BIND(STR1_NEXT);
ldr(ch1, Address(str1, cnt1tmp));
ldr(ch2, Address(str2, cnt2tmp));
(this->*str1_load_1chr)(ch1, Address(str1, cnt1tmp));
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
cmp(ch1, ch2);
br(NE, STR2_NEXT);
adds(cnt1tmp, cnt1tmp, 8);
add(cnt2tmp, cnt2tmp, 8);
adds(cnt1tmp, cnt1tmp, str1_chr_size);
add(cnt2tmp, cnt2tmp, str2_chr_size);
br(LT, STR1_NEXT);
BIND(LAST_WORD);
ldr(ch1, Address(str1));
sub(str2tmp, str2, cnt1_neg); // adjust to corresponding
ldr(ch2, Address(str2tmp, cnt2_neg)); // word in str2
cmp(ch1, ch2);
br(NE, STR2_NEXT);
b(MATCH);
BIND(DOSHORT);
if (str1_isL == str2_isL) {
cmp(cnt1, 2);
br(LT, DO1);
br(GT, DO3);
}
}
if (icnt1 == 4) {
Label CH1_LOOP;
ldr(ch1, str1);
(this->*load_4chr)(ch1, str1);
sub(cnt2, cnt2, 4);
mov(result_tmp, cnt2);
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt2_neg, zr, cnt2, LSL, 1);
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
BIND(CH1_LOOP);
ldr(ch2, Address(str2, cnt2_neg));
(this->*load_4chr)(ch2, Address(str2, cnt2_neg));
cmp(ch1, ch2);
br(EQ, MATCH);
adds(cnt2_neg, cnt2_neg, 2);
adds(cnt2_neg, cnt2_neg, str2_chr_size);
br(LE, CH1_LOOP);
b(NOMATCH);
}
if (icnt1 == -1 || icnt1 == 2) {
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 2) {
Label CH1_LOOP;
BIND(DO2);
ldrw(ch1, str1);
(this->*load_2chr)(ch1, str1);
sub(cnt2, cnt2, 2);
mov(result_tmp, cnt2);
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt2_neg, zr, cnt2, LSL, 1);
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
BIND(CH1_LOOP);
ldrw(ch2, Address(str2, cnt2_neg));
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
cmp(ch1, ch2);
br(EQ, MATCH);
adds(cnt2_neg, cnt2_neg, 2);
adds(cnt2_neg, cnt2_neg, str2_chr_size);
br(LE, CH1_LOOP);
b(NOMATCH);
}
if (icnt1 == -1 || icnt1 == 3) {
if ((icnt1 == -1 && str1_isL == str2_isL) || icnt1 == 3) {
Label FIRST_LOOP, STR2_NEXT, STR1_LOOP;
BIND(DO3);
ldrw(first, str1);
ldrh(ch1, Address(str1, 4));
(this->*load_2chr)(first, str1);
(this->*str1_load_1chr)(ch1, Address(str1, 2*str1_chr_size));
sub(cnt2, cnt2, 3);
mov(result_tmp, cnt2);
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt2_neg, zr, cnt2, LSL, 1);
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
BIND(FIRST_LOOP);
ldrw(ch2, Address(str2, cnt2_neg));
(this->*load_2chr)(ch2, Address(str2, cnt2_neg));
cmpw(first, ch2);
br(EQ, STR1_LOOP);
BIND(STR2_NEXT);
adds(cnt2_neg, cnt2_neg, 2);
adds(cnt2_neg, cnt2_neg, str2_chr_size);
br(LE, FIRST_LOOP);
b(NOMATCH);
BIND(STR1_LOOP);
add(cnt2tmp, cnt2_neg, 4);
ldrh(ch2, Address(str2, cnt2tmp));
add(cnt2tmp, cnt2_neg, 2*str2_chr_size);
(this->*str2_load_1chr)(ch2, Address(str2, cnt2tmp));
cmp(ch1, ch2);
br(NE, STR2_NEXT);
b(MATCH);
@ -4423,24 +4439,31 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
Label DO1_SHORT, DO1_LOOP;
BIND(DO1);
ldrh(ch1, str1);
cmp(cnt2, 4);
(this->*str1_load_1chr)(ch1, str1);
cmp(cnt2, 8);
br(LT, DO1_SHORT);
if (str2_isL) {
if (!str1_isL) {
tst(ch1, 0xff00);
br(NE, NOMATCH);
}
orr(ch1, ch1, ch1, LSL, 8);
}
orr(ch1, ch1, ch1, LSL, 16);
orr(ch1, ch1, ch1, LSL, 32);
sub(cnt2, cnt2, 4);
sub(cnt2, cnt2, 8/str2_chr_size);
mov(result_tmp, cnt2);
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt2_neg, zr, cnt2, LSL, 1);
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
mov(tmp3, 0x0001000100010001);
mov(tmp3, str2_isL ? 0x0101010101010101 : 0x0001000100010001);
BIND(CH1_LOOP);
ldr(ch2, Address(str2, cnt2_neg));
eor(ch2, ch1, ch2);
sub(tmp1, ch2, tmp3);
orr(tmp2, ch2, 0x7fff7fff7fff7fff);
orr(tmp2, ch2, str2_isL ? 0x7f7f7f7f7f7f7f7f : 0x7fff7fff7fff7fff);
bics(tmp1, tmp1, tmp2);
br(NE, HAS_ZERO);
adds(cnt2_neg, cnt2_neg, 8);
@ -4459,13 +4482,13 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
BIND(DO1_SHORT);
mov(result_tmp, cnt2);
lea(str2, Address(str2, cnt2, Address::uxtw(1)));
sub(cnt2_neg, zr, cnt2, LSL, 1);
lea(str2, Address(str2, cnt2, Address::lsl(str2_chr_shift)));
sub(cnt2_neg, zr, cnt2, LSL, str2_chr_shift);
BIND(DO1_LOOP);
ldrh(ch2, Address(str2, cnt2_neg));
(this->*str2_load_1chr)(ch2, Address(str2, cnt2_neg));
cmpw(ch1, ch2);
br(EQ, MATCH);
adds(cnt2_neg, cnt2_neg, 2);
adds(cnt2_neg, cnt2_neg, str2_chr_size);
br(LT, DO1_LOOP);
}
}
@ -4473,7 +4496,7 @@ void MacroAssembler::string_indexof(Register str2, Register str1,
mov(result, -1);
b(DONE);
BIND(MATCH);
add(result, result_tmp, cnt2_neg, ASR, 1);
add(result, result_tmp, cnt2_neg, ASR, str2_chr_shift);
BIND(DONE);
}

View File

@ -545,6 +545,15 @@ public:
mrs(0b011, 0b0000, 0b0000, 0b111, reg);
}
// CTR_EL0: op1 == 011
// CRn == 0000
// CRm == 0000
// op2 == 001
inline void get_ctr_el0(Register reg)
{
mrs(0b011, 0b0000, 0b0000, 0b001, reg);
}
// idiv variant which deals with MINLONG as dividend and -1 as divisor
int corrected_idivl(Register result, Register ra, Register rb,
bool want_remainder, Register tmp = rscratch1);
@ -1217,7 +1226,7 @@ public:
Register cnt1, Register cnt2,
Register tmp1, Register tmp2,
Register tmp3, Register tmp4,
int int_cnt1, Register result);
int int_cnt1, Register result, int ae);
private:
void add2_with_carry(Register final_dest_hi, Register dest_hi, Register dest_lo,
Register src1, Register src2);

View File

@ -105,6 +105,9 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
__ get_dczid_el0(rscratch1);
__ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::dczid_el0_offset())));
__ get_ctr_el0(rscratch1);
__ strw(rscratch1, Address(c_rarg0, in_bytes(VM_Version::ctr_el0_offset())));
__ leave();
__ ret(lr);
@ -124,16 +127,20 @@ void VM_Version::get_processor_features() {
getPsrInfo_stub(&_psr_info);
int dcache_line = VM_Version::dcache_line_size();
if (FLAG_IS_DEFAULT(AllocatePrefetchDistance))
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 256);
FLAG_SET_DEFAULT(AllocatePrefetchDistance, 3*dcache_line);
if (FLAG_IS_DEFAULT(AllocatePrefetchStepSize))
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, 64);
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 256);
FLAG_SET_DEFAULT(PrefetchFieldsAhead, 256);
FLAG_SET_DEFAULT(AllocatePrefetchStepSize, dcache_line);
if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes))
FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 3*dcache_line);
if (FLAG_IS_DEFAULT(PrefetchCopyIntervalInBytes))
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 256);
if ((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768)) {
warning("PrefetchCopyIntervalInBytes must be a multiple of 8 and < 32768");
FLAG_SET_DEFAULT(PrefetchCopyIntervalInBytes, 3*dcache_line);
if (PrefetchCopyIntervalInBytes != -1 &&
((PrefetchCopyIntervalInBytes & 7) || (PrefetchCopyIntervalInBytes >= 32768))) {
warning("PrefetchCopyIntervalInBytes must be -1, or a multiple of 8 and < 32768");
PrefetchCopyIntervalInBytes &= ~7;
if (PrefetchCopyIntervalInBytes >= 32768)
PrefetchCopyIntervalInBytes = 32760;
@ -170,6 +177,7 @@ void VM_Version::get_processor_features() {
// Enable vendor specific features
if (_cpu == CPU_CAVIUM && _variant == 0) _features |= CPU_DMB_ATOMICS;
if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) _features |= CPU_A53MAC;
if (_cpu == CPU_ARM && (_model == 0xd07 || _model2 == 0xd07)) _features |= CPU_STXR_PREFETCH;
// If an olde style /proc/cpuinfo (cpu_lines == 1) then if _model is an A57 (0xd07)
// we assume the worst and assume we could be on a big little system and have
// undisclosed A53 cores which we could be swapped to at any stage

View File

@ -42,6 +42,7 @@ protected:
struct PsrInfo {
uint32_t dczid_el0;
uint32_t ctr_el0;
};
static PsrInfo _psr_info;
static void get_processor_features();
@ -78,6 +79,7 @@ public:
CPU_SHA2 = (1<<6),
CPU_CRC32 = (1<<7),
CPU_LSE = (1<<8),
CPU_STXR_PREFETCH= (1 << 29),
CPU_A53MAC = (1 << 30),
CPU_DMB_ATOMICS = (1 << 31),
};
@ -88,6 +90,7 @@ public:
static int cpu_variant() { return _variant; }
static int cpu_revision() { return _revision; }
static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
static ByteSize ctr_el0_offset() { return byte_offset_of(PsrInfo, ctr_el0); }
static bool is_zva_enabled() {
// Check the DZP bit (bit 4) of dczid_el0 is zero
// and block size (bit 0~3) is not zero.
@ -98,6 +101,12 @@ public:
assert(is_zva_enabled(), "ZVA not available");
return 4 << (_psr_info.dczid_el0 & 0xf);
}
static int icache_line_size() {
return (1 << (_psr_info.ctr_el0 & 0x0f)) * 4;
}
static int dcache_line_size() {
return (1 << ((_psr_info.ctr_el0 >> 16) & 0x0f)) * 4;
}
};
#endif // CPU_AARCH64_VM_VM_VERSION_AARCH64_HPP

View File

@ -2563,15 +2563,21 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
if (is_64bit) {
__ cmpxchgd(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
MacroAssembler::MemBarFenceAfter,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, /*check without ldarx first*/true);
} else {
__ cmpxchgw(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
MacroAssembler::MemBarFenceAfter,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, /*check without ldarx first*/true);
}
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
}

View File

@ -1353,7 +1353,11 @@ void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
}
}
__ membar();
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ membar_acquire();
} else {
__ membar();
}
}

View File

@ -178,10 +178,15 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
#ifdef ASSERT
// read the value once
volatile intptr_t data = method_holder->data();
volatile address destination = jump->jump_destination();
assert(data == 0 || data == (intptr_t)callee(),
"a) MT-unsafe modification of inline cache");
assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
assert(destination == (address)-1 || destination == entry,
"b) MT-unsafe modification of inline cache");
#endif
// Update stub.
method_holder->set_data((intptr_t)callee());

View File

@ -1404,7 +1404,7 @@ address MacroAssembler::get_stack_bang_address(int instruction, void *ucontext)
void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
Register compare_value, Register exchange_value,
Register addr_base, int semantics, bool cmpxchgx_hint,
Register int_flag_success, bool contention_hint) {
Register int_flag_success, bool contention_hint, bool weak) {
Label retry;
Label failed;
Label done;
@ -1414,6 +1414,7 @@ void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_valu
bool use_result_reg = (int_flag_success != noreg);
bool preset_result_reg = (int_flag_success != dest_current_value && int_flag_success != compare_value &&
int_flag_success != exchange_value && int_flag_success != addr_base);
assert(!weak || flag == CCR0, "weak only supported with CCR0");
if (use_result_reg && preset_result_reg) {
li(int_flag_success, 0); // preset (assume cas failed)
@ -1445,10 +1446,12 @@ void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_valu
// fall through => (flag == eq), (dest_current_value == compare_value)
stwcx_(exchange_value, addr_base);
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0.
} else {
bne( CCR0, retry); // StXcx_ sets CCR0.
if (!weak || use_result_reg) {
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
} else {
bne( CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
}
}
// fall through => (flag == eq), (dest_current_value == compare_value), (swapped)
@ -1498,7 +1501,7 @@ void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_valu
void MacroAssembler::cmpxchgd(ConditionRegister flag,
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
Register addr_base, int semantics, bool cmpxchgx_hint,
Register int_flag_success, Label* failed_ext, bool contention_hint) {
Register int_flag_success, Label* failed_ext, bool contention_hint, bool weak) {
Label retry;
Label failed_int;
Label& failed = (failed_ext != NULL) ? *failed_ext : failed_int;
@ -1508,6 +1511,7 @@ void MacroAssembler::cmpxchgd(ConditionRegister flag,
bool use_result_reg = (int_flag_success!=noreg);
bool preset_result_reg = (int_flag_success!=dest_current_value && int_flag_success!=compare_value.register_or_noreg() &&
int_flag_success!=exchange_value && int_flag_success!=addr_base);
assert(!weak || flag == CCR0, "weak only supported with CCR0");
assert(int_flag_success == noreg || failed_ext == NULL, "cannot have both");
if (use_result_reg && preset_result_reg) {
@ -1538,10 +1542,12 @@ void MacroAssembler::cmpxchgd(ConditionRegister flag,
}
stdcx_(exchange_value, addr_base);
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
bne_predict_not_taken(CCR0, retry); // stXcx_ sets CCR0
} else {
bne( CCR0, retry); // stXcx_ sets CCR0
if (!weak || use_result_reg || failed_ext) {
if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
bne_predict_not_taken(CCR0, weak ? failed : retry); // stXcx_ sets CCR0
} else {
bne( CCR0, weak ? failed : retry); // stXcx_ sets CCR0
}
}
// result in register (must do this at the end because int_flag_success can be the same register as one above)

View File

@ -430,11 +430,11 @@ class MacroAssembler: public Assembler {
void cmpxchgw(ConditionRegister flag,
Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base,
int semantics, bool cmpxchgx_hint = false,
Register int_flag_success = noreg, bool contention_hint = false);
Register int_flag_success = noreg, bool contention_hint = false, bool weak = false);
void cmpxchgd(ConditionRegister flag,
Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
Register addr_base, int semantics, bool cmpxchgx_hint = false,
Register int_flag_success = noreg, Label* failed = NULL, bool contention_hint = false);
Register int_flag_success = noreg, Label* failed = NULL, bool contention_hint = false, bool weak = false);
// interface method calling
void lookup_interface_method(Register recv_klass,

View File

@ -3083,7 +3083,11 @@ encode %{
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
__ fence();
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
@ -3108,7 +3112,11 @@ encode %{
__ bne( CCR0, Lretry);
}
if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
__ fence();
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
@ -3132,7 +3140,11 @@ encode %{
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
__ fence();
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
@ -3156,7 +3168,11 @@ encode %{
__ bne( CCR0, Lretry);
}
if (RegCollision) __ mr(Rres, Rtmp);
__ fence();
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
// This enc_class is needed so that scheduler gets proper
@ -7553,6 +7569,8 @@ instruct loadPLocked(iRegPdst dst, memory mem) %{
// (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))" cannot be
// matched.
// Strong versions:
instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
effect(TEMP cr0);
@ -7562,8 +7580,13 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
@ -7577,8 +7600,13 @@ instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
@ -7592,8 +7620,13 @@ instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
@ -7607,12 +7640,312 @@ instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
$res$$Register, NULL, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
// Weak versions:
instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
// Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
// value is never passed to caller.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
// Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
// value is never passed to caller.
__ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
// value is never passed to caller.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
// Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
// value is never passed to caller.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP cr0);
format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
// Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
// value is never passed to caller.
__ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
%}
ins_pipe(pipe_class_default);
%}
// CompareAndExchange
instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
// isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
// isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
// isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, true);
%}
ins_pipe(pipe_class_default);
%}
instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
effect(TEMP_DEF res, TEMP cr0);
format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
// Variable size: instruction count smaller if regs are disjoint.
ins_encode %{
// TODO: PPC port $archOpcode(ppc64Opcode_compound);
// CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
__ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
noreg, NULL, true);
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
// isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
__ sync();
}
%}
ins_pipe(pipe_class_default);
%}
// Special RMW
instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
match(Set res (GetAndAddI mem_ptr src));
effect(TEMP cr0);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 SAP SE. All rights reserved.
* Copyright (c) 2015, 2016 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -562,10 +562,16 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
return NULL;
}
// Actually we should never reach here since we do stack overflow checks before pushing any frame.
address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
address entry = __ pc();
__ unimplemented("generate_StackOverflowError_handler");
// Expression stack must be empty before entering the VM if an
// exception happened.
__ empty_expression_stack();
// Throw exception.
__ call_VM(noreg,
CAST_FROM_FN_PTR(address,
InterpreterRuntime::throw_StackOverflowError));
return entry;
}
@ -944,7 +950,7 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc
// The top most frame needs an abi space of 112 bytes. This space is needed,
// since we call to c. The c function may spill their arguments to the caller
// frame. When we call to java, we don't need these spill slots. In order to save
// space on the stack, we resize the caller. However, java local reside in
// space on the stack, we resize the caller. However, java locals reside in
// the caller frame and the frame has to be increased. The frame_size for the
// current frame was calculated based on max_stack as size for the expression
// stack. At the call, just a part of the expression stack might be used.
@ -1007,7 +1013,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
{
if (!native_call) {
// --------------------------------------------------------------------------
// Stack overflow check
@ -1047,7 +1053,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
__ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
__ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
// Get mirror and store it in the frame as GC root for this Method*
// Get mirror and store it in the frame as GC root for this Method*.
__ load_mirror(R12_scratch2, R19_method);
// Store values.
@ -1133,6 +1139,29 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
return entry;
}
void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// Quick & dirty stack overflow checking: bang the stack & handle trap.
// Note that we do the banging after the frame is setup, since the exception
// handling code expects to find a valid interpreter frame on the stack.
// Doing the banging earlier fails if the caller frame is not an interpreter
// frame.
// (Also, the exception throwing code expects to unlock any synchronized
// method receiever, so do the banging after locking the receiver.)
// Bang each page in the shadow zone. We can't assume it's been done for
// an interpreter frame with greater than a page of locals, so each page
// needs to be checked. Only true for non-native.
if (UseStackBanging) {
const int page_size = os::vm_page_size();
const int n_shadow_pages = ((int)JavaThread::stack_shadow_zone_size()) / page_size;
const int start_page = native_call ? n_shadow_pages : 1;
BLOCK_COMMENT("bang_stack_shadow_pages:");
for (int pages = start_page; pages <= n_shadow_pages; pages++) {
__ bang_stack_with_offset(pages*page_size);
}
}
}
// Interpreter stub for calling a native method. (asm interpreter)
// This sets up a somewhat different looking stack for calling the
// native method than the typical interpreter frame setup.
@ -1156,7 +1185,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// This is not a full-blown interpreter frame, but in particular, the
// following registers are valid after this:
// - R19_method
// - R18_local (points to start of argumuments to native function)
// - R18_local (points to start of arguments to native function)
//
// abstract stack (grows up)
// [ IJava (caller of JNI callee) ] <-- ASP
@ -1207,6 +1236,11 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
BIND(continue_after_compile);
}
bang_stack_shadow_pages(true);
if (inc_counter) {
// Reset the _do_not_unlock_if_synchronized flag.
if (synchronized) {
__ li(R0, 0);
@ -1595,6 +1629,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
// Does also a stack check to assure this frame fits on the stack.
generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
// --------------------------------------------------------------------------
@ -1651,7 +1686,11 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
}
__ bind(profile_method_continue);
}
bang_stack_shadow_pages(false);
if (inc_counter || ProfileInterpreter) {
// Reset the _do_not_unlock_if_synchronized flag.
if (synchronized) {
__ li(R0, 0);

View File

@ -101,10 +101,15 @@ void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry)
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
#ifdef ASSERT
// read the value once
intptr_t data = method_holder->data();
address destination = jump->jump_destination();
assert(data == 0 || data == (intptr_t)callee(),
"a) MT-unsafe modification of inline cache");
assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
assert(destination == (address)-1 || destination == entry,
"b) MT-unsafe modification of inline cache");
#endif
// Update stub.
method_holder->set_data((intptr_t)callee());

View File

@ -2584,6 +2584,11 @@ void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, in
}
// Use this method when MacroAssembler version of call_VM_leaf_base() should be called from Interpreter.
void MacroAssembler::call_VM_leaf0(address entry_point) {
MacroAssembler::call_VM_leaf_base(entry_point, 0);
}
void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) {
call_VM_leaf_base(entry_point, number_of_arguments);
}
@ -5629,235 +5634,6 @@ void MacroAssembler::incr_allocated_bytes(Register thread,
#endif
}
void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int num_fpu_regs_in_use) {
pusha();
// if we are coming from c1, xmm registers may be live
int num_xmm_regs = LP64_ONLY(16) NOT_LP64(8);
if (UseAVX > 2) {
num_xmm_regs = LP64_ONLY(32) NOT_LP64(8);
}
if (UseSSE == 1) {
subptr(rsp, sizeof(jdouble)*8);
for (int n = 0; n < 8; n++) {
movflt(Address(rsp, n*sizeof(jdouble)), as_XMMRegister(n));
}
} else if (UseSSE >= 2) {
if (UseAVX > 2) {
push(rbx);
movl(rbx, 0xffff);
kmovwl(k1, rbx);
pop(rbx);
}
#ifdef COMPILER2
if (MaxVectorSize > 16) {
if(UseAVX > 2) {
// Save upper half of ZMM registers
subptr(rsp, 32*num_xmm_regs);
for (int n = 0; n < num_xmm_regs; n++) {
vextractf64x4_high(Address(rsp, n*32), as_XMMRegister(n));
}
}
assert(UseAVX > 0, "256 bit vectors are supported only with AVX");
// Save upper half of YMM registers
subptr(rsp, 16*num_xmm_regs);
for (int n = 0; n < num_xmm_regs; n++) {
vextractf128_high(Address(rsp, n*16), as_XMMRegister(n));
}
}
#endif
// Save whole 128bit (16 bytes) XMM registers
subptr(rsp, 16*num_xmm_regs);
#ifdef _LP64
if (VM_Version::supports_evex()) {
for (int n = 0; n < num_xmm_regs; n++) {
vextractf32x4(Address(rsp, n*16), as_XMMRegister(n), 0);
}
} else {
for (int n = 0; n < num_xmm_regs; n++) {
movdqu(Address(rsp, n*16), as_XMMRegister(n));
}
}
#else
for (int n = 0; n < num_xmm_regs; n++) {
movdqu(Address(rsp, n*16), as_XMMRegister(n));
}
#endif
}
// Preserve registers across runtime call
int incoming_argument_and_return_value_offset = -1;
if (num_fpu_regs_in_use > 1) {
// Must preserve all other FPU regs (could alternatively convert
// SharedRuntime::dsin, dcos etc. into assembly routines known not to trash
// FPU state, but can not trust C compiler)
NEEDS_CLEANUP;
// NOTE that in this case we also push the incoming argument(s) to
// the stack and restore it later; we also use this stack slot to
// hold the return value from dsin, dcos etc.
for (int i = 0; i < num_fpu_regs_in_use; i++) {
subptr(rsp, sizeof(jdouble));
fstp_d(Address(rsp, 0));
}
incoming_argument_and_return_value_offset = sizeof(jdouble)*(num_fpu_regs_in_use-1);
for (int i = nb_args-1; i >= 0; i--) {
fld_d(Address(rsp, incoming_argument_and_return_value_offset-i*sizeof(jdouble)));
}
}
subptr(rsp, nb_args*sizeof(jdouble));
for (int i = 0; i < nb_args; i++) {
fstp_d(Address(rsp, i*sizeof(jdouble)));
}
#ifdef _LP64
if (nb_args > 0) {
movdbl(xmm0, Address(rsp, 0));
}
if (nb_args > 1) {
movdbl(xmm1, Address(rsp, sizeof(jdouble)));
}
assert(nb_args <= 2, "unsupported number of args");
#endif // _LP64
// NOTE: we must not use call_VM_leaf here because that requires a
// complete interpreter frame in debug mode -- same bug as 4387334
// MacroAssembler::call_VM_leaf_base is perfectly safe and will
// do proper 64bit abi
NEEDS_CLEANUP;
// Need to add stack banging before this runtime call if it needs to
// be taken; however, there is no generic stack banging routine at
// the MacroAssembler level
MacroAssembler::call_VM_leaf_base(runtime_entry, 0);
#ifdef _LP64
movsd(Address(rsp, 0), xmm0);
fld_d(Address(rsp, 0));
#endif // _LP64
addptr(rsp, sizeof(jdouble)*nb_args);
if (num_fpu_regs_in_use > 1) {
// Must save return value to stack and then restore entire FPU
// stack except incoming arguments
fstp_d(Address(rsp, incoming_argument_and_return_value_offset));
for (int i = 0; i < num_fpu_regs_in_use - nb_args; i++) {
fld_d(Address(rsp, 0));
addptr(rsp, sizeof(jdouble));
}
fld_d(Address(rsp, (nb_args-1)*sizeof(jdouble)));
addptr(rsp, sizeof(jdouble)*nb_args);
}
if (UseSSE == 1) {
for (int n = 0; n < 8; n++) {
movflt(as_XMMRegister(n), Address(rsp, n*sizeof(jdouble)));
}
addptr(rsp, sizeof(jdouble)*8);
} else if (UseSSE >= 2) {
// Restore whole 128bit (16 bytes) XMM registers
#ifdef _LP64
if (VM_Version::supports_evex()) {
for (int n = 0; n < num_xmm_regs; n++) {
vinsertf32x4(as_XMMRegister(n), as_XMMRegister(n), Address(rsp, n*16), 0);
}
} else {
for (int n = 0; n < num_xmm_regs; n++) {
movdqu(as_XMMRegister(n), Address(rsp, n*16));
}
}
#else
for (int n = 0; n < num_xmm_regs; n++) {
movdqu(as_XMMRegister(n), Address(rsp, n*16));
}
#endif
addptr(rsp, 16*num_xmm_regs);
#ifdef COMPILER2
if (MaxVectorSize > 16) {
// Restore upper half of YMM registers.
for (int n = 0; n < num_xmm_regs; n++) {
vinsertf128_high(as_XMMRegister(n), Address(rsp, n*16));
}
addptr(rsp, 16*num_xmm_regs);
if(UseAVX > 2) {
for (int n = 0; n < num_xmm_regs; n++) {
vinsertf64x4_high(as_XMMRegister(n), Address(rsp, n*32));
}
addptr(rsp, 32*num_xmm_regs);
}
}
#endif
}
popa();
}
static const double pi_4 = 0.7853981633974483;
void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) {
// A hand-coded argument reduction for values in fabs(pi/4, pi/2)
// was attempted in this code; unfortunately it appears that the
// switch to 80-bit precision and back causes this to be
// unprofitable compared with simply performing a runtime call if
// the argument is out of the (-pi/4, pi/4) range.
Register tmp = noreg;
if (!VM_Version::supports_cmov()) {
// fcmp needs a temporary so preserve rbx,
tmp = rbx;
push(tmp);
}
Label slow_case, done;
if (trig == 't') {
ExternalAddress pi4_adr = (address)&pi_4;
if (reachable(pi4_adr)) {
// x ?<= pi/4
fld_d(pi4_adr);
fld_s(1); // Stack: X PI/4 X
fabs(); // Stack: |X| PI/4 X
fcmp(tmp);
jcc(Assembler::above, slow_case);
// fastest case: -pi/4 <= x <= pi/4
ftan();
jmp(done);
}
}
// slow case: runtime call
bind(slow_case);
switch(trig) {
case 's':
{
fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), 1, num_fpu_regs_in_use);
}
break;
case 'c':
{
fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), 1, num_fpu_regs_in_use);
}
break;
case 't':
{
fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 1, num_fpu_regs_in_use);
}
break;
default:
assert(false, "bad intrinsic");
break;
}
// Come here with result in F-TOS
bind(done);
if (tmp != noreg) {
pop(tmp);
}
}
// Look up the method for a megamorphic invokeinterface call.
// The target method is determined by <intf_klass, itable_index>.
// The receiver klass is in recv_klass.

View File

@ -259,6 +259,7 @@ class MacroAssembler: public Assembler {
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
void super_call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, Register arg_4, bool check_exceptions = true);
void call_VM_leaf0(address entry_point);
void call_VM_leaf(address entry_point,
int number_of_arguments = 0);
void call_VM_leaf(address entry_point,
@ -453,15 +454,6 @@ class MacroAssembler: public Assembler {
void cmpss2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less);
void cmpsd2int(XMMRegister opr1, XMMRegister opr2, Register dst, bool unordered_is_less);
// Inlined sin/cos generator for Java; must not use CPU instruction
// directly on Intel as it does not have high enough precision
// outside of the range [-pi/4, pi/4]. Extra argument indicate the
// number of FPU stack slots in use; all but the topmost will
// require saving if a slow case is necessary. Assumes argument is
// on FP TOS; result is on FP TOS. No cpu registers are changed by
// this code.
void trigfunc(char trig, int num_fpu_regs_in_use = 1);
// branch to L if FPU flag C2 is set/not set
// tmp is a temporary register, if none is available use noreg
void jC2 (Register tmp, Label& L);
@ -1036,9 +1028,6 @@ class MacroAssembler: public Assembler {
private:
// call runtime as a fallback for trig functions and pow/exp.
void fp_runtime_fallback(address runtime_entry, int nb_args, int num_fpu_regs_in_use);
// these are private because users should be doing movflt/movdbl
void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); }

View File

@ -3858,21 +3858,46 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
}
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
StubRoutines::x86::_L_2il0floatpacket_0_adr = (address)StubRoutines::x86::_L_2il0floatpacket_0;
StubRoutines::x86::_Pi4Inv_adr = (address)StubRoutines::x86::_Pi4Inv;
StubRoutines::x86::_Pi4x3_adr = (address)StubRoutines::x86::_Pi4x3;
StubRoutines::x86::_Pi4x4_adr = (address)StubRoutines::x86::_Pi4x4;
StubRoutines::x86::_ones_adr = (address)StubRoutines::x86::_ones;
StubRoutines::_dexp = generate_libmExp();
StubRoutines::_dlog = generate_libmLog();
StubRoutines::_dlog10 = generate_libmLog10();
StubRoutines::_dpow = generate_libmPow();
StubRoutines::_dlibm_reduce_pi04l = generate_libm_reduce_pi04l();
StubRoutines::_dlibm_sin_cos_huge = generate_libm_sin_cos_huge();
StubRoutines::_dsin = generate_libmSin();
StubRoutines::_dcos = generate_libmCos();
StubRoutines::_dlibm_tan_cot_huge = generate_libm_tan_cot_huge();
StubRoutines::_dtan = generate_libmTan();
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::x86::_L_2il0floatpacket_0_adr = (address)StubRoutines::x86::_L_2il0floatpacket_0;
StubRoutines::x86::_Pi4Inv_adr = (address)StubRoutines::x86::_Pi4Inv;
StubRoutines::x86::_Pi4x3_adr = (address)StubRoutines::x86::_Pi4x3;
StubRoutines::x86::_Pi4x4_adr = (address)StubRoutines::x86::_Pi4x4;
StubRoutines::x86::_ones_adr = (address)StubRoutines::x86::_ones;
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) {
StubRoutines::_dexp = generate_libmExp();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
StubRoutines::_dlog = generate_libmLog();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
StubRoutines::_dlog10 = generate_libmLog10();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
StubRoutines::_dpow = generate_libmPow();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::_dlibm_reduce_pi04l = generate_libm_reduce_pi04l();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
StubRoutines::_dlibm_sin_cos_huge = generate_libm_sin_cos_huge();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
StubRoutines::_dsin = generate_libmSin();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
StubRoutines::_dcos = generate_libmCos();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::_dlibm_tan_cot_huge = generate_libm_tan_cot_huge();
StubRoutines::_dtan = generate_libmTan();
}
}
}

View File

@ -5128,27 +5128,45 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::_updateBytesCRC32C = generate_updateBytesCRC32C(supports_clmul);
}
if (VM_Version::supports_sse2() && UseLibmIntrinsic) {
StubRoutines::x86::_ONEHALF_adr = (address)StubRoutines::x86::_ONEHALF;
StubRoutines::x86::_P_2_adr = (address)StubRoutines::x86::_P_2;
StubRoutines::x86::_SC_4_adr = (address)StubRoutines::x86::_SC_4;
StubRoutines::x86::_Ctable_adr = (address)StubRoutines::x86::_Ctable;
StubRoutines::x86::_SC_2_adr = (address)StubRoutines::x86::_SC_2;
StubRoutines::x86::_SC_3_adr = (address)StubRoutines::x86::_SC_3;
StubRoutines::x86::_SC_1_adr = (address)StubRoutines::x86::_SC_1;
StubRoutines::x86::_PI_INV_TABLE_adr = (address)StubRoutines::x86::_PI_INV_TABLE;
StubRoutines::x86::_PI_4_adr = (address)StubRoutines::x86::_PI_4;
StubRoutines::x86::_PI32INV_adr = (address)StubRoutines::x86::_PI32INV;
StubRoutines::x86::_SIGN_MASK_adr = (address)StubRoutines::x86::_SIGN_MASK;
StubRoutines::x86::_P_1_adr = (address)StubRoutines::x86::_P_1;
StubRoutines::x86::_P_3_adr = (address)StubRoutines::x86::_P_3;
StubRoutines::x86::_NEG_ZERO_adr = (address)StubRoutines::x86::_NEG_ZERO;
StubRoutines::_dexp = generate_libmExp();
StubRoutines::_dlog = generate_libmLog();
StubRoutines::_dlog10 = generate_libmLog10();
StubRoutines::_dpow = generate_libmPow();
StubRoutines::_dtan = generate_libmTan();
StubRoutines::_dsin = generate_libmSin();
StubRoutines::_dcos = generate_libmCos();
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos) ||
vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::x86::_ONEHALF_adr = (address)StubRoutines::x86::_ONEHALF;
StubRoutines::x86::_P_2_adr = (address)StubRoutines::x86::_P_2;
StubRoutines::x86::_SC_4_adr = (address)StubRoutines::x86::_SC_4;
StubRoutines::x86::_Ctable_adr = (address)StubRoutines::x86::_Ctable;
StubRoutines::x86::_SC_2_adr = (address)StubRoutines::x86::_SC_2;
StubRoutines::x86::_SC_3_adr = (address)StubRoutines::x86::_SC_3;
StubRoutines::x86::_SC_1_adr = (address)StubRoutines::x86::_SC_1;
StubRoutines::x86::_PI_INV_TABLE_adr = (address)StubRoutines::x86::_PI_INV_TABLE;
StubRoutines::x86::_PI_4_adr = (address)StubRoutines::x86::_PI_4;
StubRoutines::x86::_PI32INV_adr = (address)StubRoutines::x86::_PI32INV;
StubRoutines::x86::_SIGN_MASK_adr = (address)StubRoutines::x86::_SIGN_MASK;
StubRoutines::x86::_P_1_adr = (address)StubRoutines::x86::_P_1;
StubRoutines::x86::_P_3_adr = (address)StubRoutines::x86::_P_3;
StubRoutines::x86::_NEG_ZERO_adr = (address)StubRoutines::x86::_NEG_ZERO;
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dexp)) {
StubRoutines::_dexp = generate_libmExp();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog)) {
StubRoutines::_dlog = generate_libmLog();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dlog10)) {
StubRoutines::_dlog10 = generate_libmLog10();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dpow)) {
StubRoutines::_dpow = generate_libmPow();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dsin)) {
StubRoutines::_dsin = generate_libmSin();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dcos)) {
StubRoutines::_dcos = generate_libmCos();
}
if (vmIntrinsics::is_intrinsic_available(vmIntrinsics::_dtan)) {
StubRoutines::_dtan = generate_libmTan();
}
}
}

View File

@ -350,7 +350,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dsin));
}
__ addptr(rsp, 2 * wordSize);
break;
@ -360,7 +360,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dcos));
}
__ addptr(rsp, 2 * wordSize);
break;
@ -370,7 +370,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dtan() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
}
__ addptr(rsp, 2 * wordSize);
break;
@ -386,7 +386,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dlog() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog));
}
__ addptr(rsp, 2 * wordSize);
break;
@ -396,7 +396,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dlog10() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10));
}
__ addptr(rsp, 2 * wordSize);
break;
@ -408,7 +408,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dpow() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dpow)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dpow));
}
__ addptr(rsp, 4 * wordSize);
break;
@ -418,7 +418,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dexp() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dexp));
}
__ addptr(rsp, 2*wordSize);
break;

View File

@ -377,35 +377,35 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dexp() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dexp));
}
} else if (kind == Interpreter::java_lang_math_log) {
__ movdbl(xmm0, Address(rsp, wordSize));
if (StubRoutines::dlog() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog));
}
} else if (kind == Interpreter::java_lang_math_log10) {
__ movdbl(xmm0, Address(rsp, wordSize));
if (StubRoutines::dlog10() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10));
}
} else if (kind == Interpreter::java_lang_math_sin) {
__ movdbl(xmm0, Address(rsp, wordSize));
if (StubRoutines::dsin() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dsin));
}
} else if (kind == Interpreter::java_lang_math_cos) {
__ movdbl(xmm0, Address(rsp, wordSize));
if (StubRoutines::dcos() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dcos));
}
} else if (kind == Interpreter::java_lang_math_pow) {
__ movdbl(xmm1, Address(rsp, wordSize));
@ -413,23 +413,23 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
if (StubRoutines::dpow() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dpow)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dpow));
}
} else if (kind == Interpreter::java_lang_math_tan) {
__ movdbl(xmm0, Address(rsp, wordSize));
if (StubRoutines::dtan() != NULL) {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
} else {
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan)));
__ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
}
} else {
__ fld_d(Address(rsp, wordSize));
switch (kind) {
case Interpreter::java_lang_math_abs:
__ fabs();
break;
default :
ShouldNotReachHere();
case Interpreter::java_lang_math_abs:
__ fabs();
break;
default:
ShouldNotReachHere();
}
// return double result in xmm0 for interpreter and compilers.
@ -447,3 +447,4 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
return entry_point;
}

View File

@ -1712,7 +1712,8 @@ public class CommandProcessor {
// called after debuggee attach
private void postAttach() {
// create JavaScript engine and start it
jsengine = new JSJavaScriptEngine() {
try {
jsengine = new JSJavaScriptEngine() {
private ObjectReader reader = new ObjectReader();
private JSJavaFactory factory = new JSJavaFactoryImpl();
public ObjectReader getObjectReader() {
@ -1735,17 +1736,24 @@ public class CommandProcessor {
return err;
}
};
try {
jsengine.defineFunction(this,
try {
jsengine.defineFunction(this,
this.getClass().getMethod("registerCommand",
new Class[] {
String.class, String.class, String.class
}));
} catch (NoSuchMethodException exp) {
// should not happen, see below...!!
exp.printStackTrace();
} catch (NoSuchMethodException exp) {
// should not happen, see below...!!
exp.printStackTrace();
}
jsengine.start();
}
catch (Exception ex) {
System.out.println("Warning! JS Engine can't start, some commands will not be available.");
if (verboseExceptions) {
ex.printStackTrace(out);
}
}
jsengine.start();
}
public void registerCommand(String cmd, String usage, final String func) {

View File

@ -45,12 +45,7 @@ public enum AArch64Kind implements PlatformKind {
V128_DWORD(16, DWORD),
V128_QWORD(16, QWORD),
V128_SINGLE(16, SINGLE),
V128_DOUBLE(16, DOUBLE),
MASK8(1),
MASK16(2),
MASK32(4),
MASK64(8);
V128_DOUBLE(16, DOUBLE);
private final int size;
private final int vectorLength;
@ -121,18 +116,6 @@ public enum AArch64Kind implements PlatformKind {
}
}
public boolean isMask() {
switch (this) {
case MASK8:
case MASK16:
case MASK32:
case MASK64:
return true;
default:
return false;
}
}
public char getTypeChar() {
switch (this) {
case BYTE:
@ -159,11 +142,6 @@ public enum AArch64Kind implements PlatformKind {
case V128_SINGLE:
case V128_DOUBLE:
return 'v';
case MASK8:
case MASK16:
case MASK32:
case MASK64:
return 'k';
default:
return '-';
}

View File

@ -98,6 +98,11 @@ public class BytecodeFrame extends BytecodePosition {
*/
public final boolean rethrowException;
/**
* Specifies if this object represents a frame state in the middle of executing a call. If
* true, the arguments to the call have been popped from the stack and the return value (for a
* non-void call) has not yet been pushed.
*/
public final boolean duringCall;
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -417,7 +417,7 @@ public class CodeUtil {
/**
* Create a calling convention from a {@link ResolvedJavaMethod}.
*/
public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method) {
public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, ValueKindFactory<?> valueKindFactory) {
Signature sig = method.getSignature();
JavaType retType = sig.getReturnType(null);
int sigCount = sig.getParameterCount(false);
@ -434,6 +434,6 @@ public class CodeUtil {
}
RegisterConfig registerConfig = codeCache.getRegisterConfig();
return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget());
return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory);
}
}

View File

@ -23,49 +23,15 @@
package jdk.vm.ci.code;
/**
* Simple class to provide information about the result of a compile request.
* Provides information about the result of a {@link CompilationRequest}.
*/
public final class CompilationRequestResult {
public interface CompilationRequestResult {
/**
* A user readable description of the failure.
* Determines if the compilation was successful.
*
* @return a non-null object whose {@link Object#toString()} describes the failure or null if
* compilation was successful
*/
private final String failureMessage;
/**
* Whether this is a transient failure where retrying would help.
*/
private final boolean retry;
/**
* Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root
* method.
*/
private final int inlinedBytecodes;
private CompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) {
this.failureMessage = failureMessage;
this.retry = retry;
this.inlinedBytecodes = inlinedBytecodes;
}
public static CompilationRequestResult success(int inlinedBytecodes) {
return new CompilationRequestResult(null, true, inlinedBytecodes);
}
public static CompilationRequestResult failure(String failureMessage, boolean retry) {
return new CompilationRequestResult(failureMessage, retry, 0);
}
public String getFailureMessage() {
return failureMessage;
}
public boolean getRetry() {
return retry;
}
public int getInlinedBytecodes() {
return inlinedBytecodes;
}
Object getFailure();
}

View File

@ -23,7 +23,9 @@
package jdk.vm.ci.code;
/**
* The output from compiling a method.
* Marker type for an object containing the output of a compiler in a form suitable for installing
* into a managed code heap. Since the details of a code heap are specific to each runtime, this
* interface does not specify any methods.
*/
public interface CompiledCode {
}

View File

@ -25,8 +25,8 @@ package jdk.vm.ci.code;
/**
* Constants and intrinsic definition for memory barriers.
*
* The documentation for each constant is taken from Doug Lea's <a
* href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
* The documentation for each constant is taken from Doug Lea's
* <a href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
* Writers</a>.
* <p>
* The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory

View File

@ -22,5 +22,10 @@
*/
package jdk.vm.ci.code;
/**
* Marker type for an object containing information about where the object references are in machine
* state (e.g., registers or stack locations). This is typically associated with an execution point
* in compiled code.
*/
public abstract class ReferenceMap {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,8 +22,7 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.ValueKind;
/**
* Represents a target machine register.
@ -37,17 +36,9 @@ public final class Register implements Comparable<Register> {
*/
public static final Register None = new Register(-1, -1, "noreg", SPECIAL);
/**
* Frame pointer of the current method. All spill slots and outgoing stack-based arguments are
* addressed relative to this register.
*/
public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL);
public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL);
/**
* The identifier for this register that is unique across all the registers in a
* {@link Architecture}. A valid register has {@code number > 0}.
* {@link Architecture}. A valid register has {@code number >= 0}.
*/
public final int number;
@ -144,17 +135,17 @@ public final class Register implements Comparable<Register> {
* @param kind the specified kind
* @return the {@link RegisterValue}
*/
public RegisterValue asValue(LIRKind kind) {
public RegisterValue asValue(ValueKind<?> kind) {
return new RegisterValue(kind, this);
}
/**
* Gets this register as a {@linkplain RegisterValue value} with no particular kind.
*
* @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind.
* @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind.
*/
public RegisterValue asValue() {
return asValue(LIRKind.Illegal);
return asValue(ValueKind.Illegal);
}
/**
@ -166,38 +157,6 @@ public final class Register implements Comparable<Register> {
return number >= 0;
}
/**
* Gets the maximum register {@linkplain #number number} in a given set of registers.
*
* @param registers the set of registers to process
* @return the maximum register number for any register in {@code registers}
*/
public static int maxRegisterNumber(Register[] registers) {
int max = Integer.MIN_VALUE;
for (Register r : registers) {
if (r.number > max) {
max = r.number;
}
}
return max;
}
/**
* Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
*
* @param registers the set of registers to process
* @return the maximum register encoding for any register in {@code registers}
*/
public static int maxRegisterEncoding(Register[] registers) {
int max = Integer.MIN_VALUE;
for (Register r : registers) {
if (r.encoding > max) {
max = r.encoding;
}
}
return max;
}
@Override
public String toString() {
return name;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@ import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.ValueKind;
/**
* A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
@ -46,7 +47,8 @@ public interface RegisterConfig {
}
/**
* Gets the register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound.
* Gets the register used as the frame pointer. Spill slots and outgoing stack-based arguments
* are addressed relative to this register.
*/
Register getFrameRegister();
@ -56,9 +58,9 @@ public interface RegisterConfig {
* @param type the type of calling convention being requested
* @param returnType the return type (can be null for methods returning {@code void})
* @param parameterTypes the types of the arguments of the call
* @param target the target platform
* @param valueKindFactory the factory to create custom {@link ValueKind ValueKinds}
*/
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target);
CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory);
/**
* Gets the ordered set of registers that are can be used to pass parameters according to a
@ -105,14 +107,6 @@ public interface RegisterConfig {
*/
RegisterAttributes[] getAttributesMap();
/**
* Gets the register corresponding to a runtime-defined role.
*
* @param id the identifier of a runtime-defined register role
* @return the register playing the role specified by {@code id}
*/
Register getRegisterForRole(int id);
/**
* Determines if all {@link #getAllocatableRegisters() allocatable} registers are
* {@link #getCallerSaveRegisters() caller saved}.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,23 +23,16 @@
package jdk.vm.ci.code;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.ValueKind;
/**
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
* of {@link RegisterValue} for each ({@link Register}, {@link JavaKind}) pair. Use
* {@link Register#asValue(LIRKind)} to retrieve the canonical {@link RegisterValue} instance for a
* given (register,kind) pair.
* Denotes a register that stores a value of a fixed kind.
*/
public final class RegisterValue extends AllocatableValue {
private final Register reg;
/**
* Should only be called from {@link Register#Register} to ensure canonicalization.
*/
protected RegisterValue(LIRKind kind, Register register) {
protected RegisterValue(ValueKind<?> kind, Register register) {
super(kind);
this.reg = register;
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.code;
/**
* Class representing an exception with a stack trace of the currently processed position in the
* compiled Java program instead of the stack trace of the compiler. The exception of the compiler
* is saved as the cause of this exception.
*/
public abstract class SourceStackTrace extends BailoutException {
private static final long serialVersionUID = 2144811793442316776L;
public static SourceStackTrace create(Throwable cause, String format, StackTraceElement[] elements) {
return new SourceStackTrace(cause, format) {
private static final long serialVersionUID = 6279381376051787907L;
@Override
public synchronized Throwable fillInStackTrace() {
assert elements != null;
setStackTrace(elements);
return this;
}
};
}
private SourceStackTrace(Throwable cause, String format) {
super(cause, format);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
package jdk.vm.ci.code;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.ValueKind;
/**
* Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
@ -43,16 +43,16 @@ public final class StackSlot extends AllocatableValue {
* @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
* beginning of the frame (stack pointer + total frame size).
*/
public static StackSlot get(LIRKind kind, int offset, boolean addFrameSize) {
public static StackSlot get(ValueKind<?> kind, int offset, boolean addFrameSize) {
assert addFrameSize || offset >= 0;
return new StackSlot(kind, offset, addFrameSize);
}
/**
* Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
* be used.
* Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache
* can be used.
*/
private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
private StackSlot(ValueKind<?> kind, int offset, boolean addFrameSize) {
super(kind);
this.offset = offset;
this.addFrameSize = addFrameSize;
@ -99,7 +99,7 @@ public final class StackSlot extends AllocatableValue {
public StackSlot asOutArg() {
assert offset >= 0;
if (addFrameSize) {
return get(getLIRKind(), offset, false);
return get(getValueKind(), offset, false);
}
return this;
}
@ -110,7 +110,7 @@ public final class StackSlot extends AllocatableValue {
public StackSlot asInArg() {
assert offset >= 0;
if (!addFrameSize) {
return get(getLIRKind(), offset, true);
return get(getValueKind(), offset, true);
}
return this;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,9 +23,8 @@
package jdk.vm.ci.code;
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the target machine for a compiler, including the CPU architecture, the size of
@ -56,8 +55,8 @@ public class TargetDescription {
public final JavaKind wordJavaKind;
/**
* The stack alignment requirement of the platform. For example, from Appendix D of <a
* href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
* The stack alignment requirement of the platform. For example, from Appendix D of
* <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
* Optimization Reference Manual</a>:
*
* <pre>
@ -118,13 +117,4 @@ public class TargetDescription {
public String toString() {
return identityHashCodeString(this);
}
public LIRKind getLIRKind(JavaKind javaKind) {
PlatformKind platformKind = arch.getPlatformKind(javaKind);
if (javaKind.isObject()) {
return LIRKind.reference(platformKind);
} else {
return LIRKind.value(platformKind);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -20,10 +20,15 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
package jdk.vm.ci.code;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ValueKind;
/**
* Marker interface for classes whose values are proxied during replay compilation capture.
* Can be implemented by compilers to create custom {@link ValueKind} subclasses.
*/
public interface HotSpotProxified {
public interface ValueKindFactory<K extends ValueKind<K>> {
K getValueKind(JavaKind javaKind);
}

View File

@ -22,9 +22,6 @@
*/
package jdk.vm.ci.code;
import java.util.ArrayList;
import java.util.List;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaValue;
@ -111,73 +108,4 @@ public final class ValueUtil {
return asRegister(value);
}
}
public static boolean sameRegister(Value v1, Value v2) {
return isRegister(v1) && isRegister(v2) && asRegister(v1).equals(asRegister(v2));
}
public static boolean sameRegister(Value v1, Value v2, Value v3) {
return sameRegister(v1, v2) && sameRegister(v1, v3);
}
/**
* Checks if all the provided values are different physical registers. The parameters can be
* either {@link Register registers}, {@link Value values} or arrays of them. All values that
* are not {@link RegisterValue registers} are ignored.
*/
public static boolean differentRegisters(Object... values) {
List<Register> registers = collectRegisters(values, new ArrayList<Register>());
for (int i = 1; i < registers.size(); i++) {
Register r1 = registers.get(i);
for (int j = 0; j < i; j++) {
Register r2 = registers.get(j);
if (r1.equals(r2)) {
return false;
}
}
}
return true;
}
private static List<Register> collectRegisters(Object[] values, List<Register> registers) {
for (Object o : values) {
if (o instanceof Register) {
registers.add((Register) o);
} else if (o instanceof Value) {
if (isRegister((Value) o)) {
registers.add(asRegister((Value) o));
}
} else if (o instanceof Object[]) {
collectRegisters((Object[]) o, registers);
} else {
throw new IllegalArgumentException("Not a Register or Value: " + o);
}
}
return registers;
}
/**
* Subtract sets of registers (x - y).
*
* @param x a set of register to subtract from.
* @param y a set of registers to subtract.
* @return resulting set of registers (x - y).
*/
public static Value[] subtractRegisters(Value[] x, Value[] y) {
ArrayList<Value> result = new ArrayList<>(x.length);
for (Value i : x) {
boolean append = true;
for (Value j : y) {
if (ValueUtil.sameRegister(i, j)) {
append = false;
break;
}
}
if (append) {
result.add(i);
}
}
Value[] resultArray = new Value[result.size()];
return result.toArray(resultArray);
}
}

View File

@ -21,10 +21,10 @@
* questions.
*/
/**
* Package that defines the interface between a Java application that wants to install code and the runtime.
* The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} interface.
* The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
* Package that defines the interface between a Java application that wants to install code and the
* runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
* interface. The method
* {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
* can be used to install code.
*/
package jdk.vm.ci.code;

View File

@ -26,6 +26,10 @@ import java.util.Objects;
import jdk.vm.ci.meta.VMConstant;
/**
* Represents an embedded {@link VMConstant} in the code or data section that needs to be
* {@link DataPatch patched} by the VM (e.g. an embedded pointer to a Java object).
*/
public final class ConstantReference extends Reference {
private final VMConstant constant;

View File

@ -24,12 +24,12 @@ package jdk.vm.ci.code.site;
import java.util.Objects;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.VMConstant;
/**
* Represents a code site that references some data. The associated data can be either a
* {@link DataSectionReference reference} to the data section, or it may be an inlined
* {@link JavaConstant} that needs to be patched.
* {@link VMConstant} that needs to be patched.
*/
public final class DataPatch extends Site {

View File

@ -22,6 +22,10 @@
*/
package jdk.vm.ci.code.site;
/**
* Represents a pointer to some location in the data section that should be {@link DataPatch
* patched} into the code.
*/
public final class DataSectionReference extends Reference {
private boolean initialized;

View File

@ -30,7 +30,6 @@ public enum InfopointReason {
SAFEPOINT,
CALL,
IMPLICIT_EXCEPTION,
METASPACE_ACCESS,
METHOD_START,
METHOD_END,
BYTECODE_POSITION;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,13 +25,23 @@ package jdk.vm.ci.code.site;
import java.util.Objects;
/**
* Represents a mark in the machine code that can be used by the runtime for its own purposes. A
* mark can reference other marks.
* Associates arbitrary information with a position in machine code. For example, HotSpot specific
* code in a compiler backend may use this to denote the position of a safepoint, exception handler
* entry point, verified entry point etc.
*/
public final class Mark extends Site {
/**
* An object denoting extra semantic information about the machine code position of this mark.
*/
public final Object id;
/**
* Creates a mark that associates {@code id} with the machine code position {@code pcOffset}.
*
* @param pcOffset
* @param id
*/
public Mark(int pcOffset, Object id) {
super(pcOffset);
this.id = id;
@ -40,7 +50,7 @@ public final class Mark extends Site {
@Override
public String toString() {
if (id == null) {
return String.format("%d[<mar>]", pcOffset);
return String.format("%d[<mark>]", pcOffset);
} else if (id instanceof Integer) {
return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id));
} else {

View File

@ -24,16 +24,19 @@ package jdk.vm.ci.code.stack;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Access to the object variables in a stack frame.
*/
public interface InspectedFrame {
/**
* Returns the value of the local at the given index. Currently only works for object values.
* This value is a copy iff {@link #isVirtual(int)} is true.
* Returns the value of the object local at {@code index}. This value is a copy iff
* {@link #isVirtual(int)} is true.
*/
Object getLocal(int index);
/**
* Returns whether the local at the given index is a virtual object, and therefore the object
* Returns whether the local at {@code index} is a virtual object, and therefore the object
* returned by {@link #getLocal(int)} is a copy.
*/
boolean isVirtual(int index);

View File

@ -20,7 +20,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.inittimer;
package jdk.vm.ci.common;
import java.util.concurrent.atomic.AtomicInteger;

View File

@ -31,7 +31,6 @@ import java.util.Locale;
public class JVMCIError extends Error {
private static final long serialVersionUID = 531632331813456233L;
private final ArrayList<String> context = new ArrayList<>();
public static RuntimeException unimplemented() {
throw new JVMCIError("unimplemented");
@ -101,27 +100,6 @@ public class JVMCIError extends Error {
super(cause);
}
/**
* This constructor creates a {@link JVMCIError} and adds all the
* {@linkplain #addContext(String) context} of another {@link JVMCIError}.
*
* @param e the original {@link JVMCIError}
*/
public JVMCIError(JVMCIError e) {
super(e);
context.addAll(e.context);
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append(super.toString());
for (String s : context) {
str.append("\n\tat ").append(s);
}
return str.toString();
}
private static String format(String msg, Object... args) {
if (args != null) {
// expand Iterable parameters into a list representation
@ -137,13 +115,4 @@ public class JVMCIError extends Error {
}
return String.format(Locale.ENGLISH, msg, args);
}
public JVMCIError addContext(String newContext) {
this.context.add(newContext);
return this;
}
public JVMCIError addContext(String name, Object obj) {
return addContext(format("%s: %s", name, obj));
}
}

View File

@ -20,15 +20,15 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.inittimer;
package jdk.vm.ci.common;
/**
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
*/
public @interface SuppressFBWarnings {
@interface SuppressFBWarnings {
/**
* The set of FindBugs <a
* href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
* The set of FindBugs
* <a href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
* suppressed in annotated element. The value can be a bug category, kind or pattern.
*/
String[] value();

View File

@ -1,81 +0,0 @@
/*
* Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.common;
import jdk.internal.misc.Unsafe;
/**
* Utilities for operating on raw memory with {@link Unsafe}.
*/
public class UnsafeUtil {
/**
* Copies the contents of a {@link String} to a native memory buffer as a {@code '\0'}
* terminated C string. The native memory buffer is allocated via
* {@link Unsafe#allocateMemory(long)}. The caller is responsible for releasing the buffer when
* it is no longer needed via {@link Unsafe#freeMemory(long)}.
*
* @return the native memory pointer of the C string created from {@code s}
*/
public static long createCString(Unsafe unsafe, String s) {
return writeCString(unsafe, s, unsafe.allocateMemory(s.length() + 1));
}
/**
* Reads a {@code '\0'} terminated C string from native memory and converts it to a
* {@link String}.
*
* @return a Java string
*/
public static String readCString(Unsafe unsafe, long address) {
if (address == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0;; i++) {
char c = (char) unsafe.getByte(address + i);
if (c == 0) {
break;
}
sb.append(c);
}
return sb.toString();
}
/**
* Writes the contents of a {@link String} to a native memory buffer as a {@code '\0'}
* terminated C string. The caller is responsible for ensuring the buffer is at least
* {@code s.length() + 1} bytes long. The caller is also responsible for releasing the buffer
* when it is no longer.
*
* @return the value of {@code buf}
*/
public static long writeCString(Unsafe unsafe, String s, long buf) {
int size = s.length();
for (int i = 0; i < size; i++) {
unsafe.putByte(buf + i, (byte) s.charAt(i));
}
unsafe.putByte(buf + size, (byte) '\0');
return buf;
}
}

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot.aarch64;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
@ -31,6 +31,7 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@ -38,7 +39,6 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.runtime.JVMCIBackend;
@ -68,7 +68,7 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
}
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
return new AArch64HotSpotRegisterConfig(target.arch, runtime.getConfig());
return new AArch64HotSpotRegisterConfig(target, runtime.getConfig());
}
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@ -122,7 +122,8 @@ public class AArch64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFac
}
}
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection,
StackIntrospection stackIntrospection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -64,19 +64,20 @@ import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.ValueKindFactory;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
public class AArch64HotSpotRegisterConfig implements RegisterConfig {
private final Architecture architecture;
private final TargetDescription target;
private final Register[] allocatable;
@ -104,7 +105,7 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
list.add(reg);
}
}
@ -159,13 +160,13 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
return registers;
}
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
assert callerSaved.length >= allocatable.length;
}
public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
this.architecture = architecture;
public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
this.target = target;
this.maxFrameSize = config.maxFrameSize;
this.allocatable = allocatable.clone();
@ -195,19 +196,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public Register getRegisterForRole(int index) {
throw new UnsupportedOperationException();
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
// On x64, parameter locations are the same whether viewed
// from the caller or callee perspective
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
@Override
@ -230,7 +226,8 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
@ -250,14 +247,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
case Object:
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Float:
case Double:
if (currentSIMD < simdParameterRegisters.length) {
Register register = simdParameterRegisters[currentSIMD++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
default:
@ -265,14 +262,14 @@ public class AArch64HotSpotRegisterConfig implements RegisterConfig {
}
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
}
}
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
return new CallingConvention(currentStackOffset, returnLocation, locations);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot.amd64;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
@ -31,6 +31,7 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@ -38,7 +39,6 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.runtime.JVMCIBackend;
@ -152,7 +152,7 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
return new AMD64HotSpotRegisterConfig(target.arch, runtime.getConfig());
return new AMD64HotSpotRegisterConfig(target, runtime.getConfig());
}
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@ -206,7 +206,8 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
}
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection,
StackIntrospection stackIntrospection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -56,19 +56,20 @@ import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.ValueKindFactory;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
private final Architecture architecture;
private final TargetDescription target;
private final Register[] allocatable;
@ -96,7 +97,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
list.add(reg);
}
}
@ -145,13 +146,13 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
return registers;
}
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
this(target, config, initAllocatable(target.arch, config.useCompressedOops));
assert callerSaved.length >= allocatable.length;
}
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
this.architecture = architecture;
public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
this.target = target;
this.maxFrameSize = config.maxFrameSize;
if (config.windowsOs) {
@ -173,7 +174,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
allAllocatableAreCallerSaved = true;
attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
}
@Override
@ -192,19 +193,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
@Override
public Register getRegisterForRole(int index) {
throw new UnsupportedOperationException();
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
// On x64, parameter locations are the same whether viewed
// from the caller or callee perspective
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
@Override
@ -227,7 +223,8 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
@ -247,14 +244,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
case Object:
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Float:
case Double:
if (currentXMM < xmmParameterRegisters.length) {
Register register = xmmParameterRegisters[currentXMM++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
default:
@ -262,14 +259,14 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
}
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
}
}
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
return new CallingConvention(currentStackOffset, returnLocation, locations);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot.sparc;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import static jdk.vm.ci.common.InitTimer.timer;
import java.util.EnumSet;
@ -30,6 +30,7 @@ import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@ -37,7 +38,6 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.runtime.JVMCIBackend;
import jdk.vm.ci.sparc.SPARC;
import jdk.vm.ci.sparc.SPARC.CPUFeature;
@ -146,7 +146,7 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
TargetDescription target = createTarget(runtime.getConfig());
HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target.arch, runtime.getConfig());
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -78,19 +78,20 @@ import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.ValueKindFactory;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.ValueKind;
import jdk.vm.ci.sparc.SPARC;
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
private final Architecture architecture;
private final TargetDescription target;
private final Register[] allocatable;
@ -110,7 +111,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
list.add(reg);
}
}
@ -166,16 +167,16 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
return registers;
}
public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
this(arch, initAllocatable(arch, config.useCompressedOops), config);
public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
this(target, initAllocatable(target.arch, config.useCompressedOops), config);
}
public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
this.architecture = arch;
public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable, HotSpotVMConfig config) {
this.target = target;
this.allocatable = allocatable.clone();
this.addNativeRegisterArgumentSlots = config.linuxOs;
HashSet<Register> callerSaveSet = new HashSet<>();
Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
for (Register cs : calleeSaveRegisters) {
callerSaveSet.remove(cs);
}
@ -198,18 +199,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
@Override
public Register getRegisterForRole(int index) {
throw new UnsupportedOperationException();
}
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
if (type == HotSpotCallingConventionType.JavaCallee) {
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
}
throw JVMCIError.shouldNotReachHere();
}
@ -234,7 +230,8 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
ValueKindFactory<?> valueKindFactory) {
AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
int currentGeneral = 0;
@ -254,7 +251,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
case Object:
if (currentGeneral < generalParameterRegisters.length) {
Register register = generalParameterRegisters[currentGeneral++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Double:
@ -265,13 +262,13 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
Register register = fpuDoubleParameterRegisters[currentFloating];
currentFloating += 2; // Only every second is a double register
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
case Float:
if (currentFloating < fpuFloatParameterRegisters.length) {
Register register = fpuFloatParameterRegisters[currentFloating++];
locations[i] = register.asValue(target.getLIRKind(kind));
locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
}
break;
default:
@ -279,18 +276,18 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
// Stack slot is always aligned to its size in bytes but minimum wordsize
int typeSize = lirKind.getPlatformKind().getSizeInBytes();
int typeSize = valueKind.getPlatformKind().getSizeInBytes();
currentStackOffset = roundUp(currentStackOffset, typeSize);
int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
currentStackOffset += typeSize;
}
}
JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
int outArgSpillArea;
if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {

View File

@ -23,8 +23,8 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.common.InitTimer.timer;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@ -33,9 +33,9 @@ import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
@ -79,7 +79,7 @@ final class CompilerToVM {
native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
/**
* Gets the number of entries in {@code method}'s exception handler table or 0 if it has not
* Gets the number of entries in {@code method}'s exception handler table or 0 if it has no
* exception handler table.
*/
native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
@ -246,8 +246,8 @@ final class CompilerToVM {
native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
/**
* Ensures that the type referenced by the entry for a <a
* href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
* Ensures that the type referenced by the entry for a
* <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
* polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
* initialized.
*
@ -315,6 +315,21 @@ final class CompilerToVM {
*/
native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
/**
* Generates the VM metadata for some compiled code and copies them into {@code metaData}. This
* method does not install anything into the code cache.
*
* @param target the target where this code would be installed
* @param compiledCode the result of a compilation
* @param metaData the metadata is written to this object
* @return the outcome of the installation which will be one of
* {@link HotSpotVMConfig#codeInstallResultOk},
* {@link HotSpotVMConfig#codeInstallResultCacheFull},
* {@link HotSpotVMConfig#codeInstallResultCodeTooLarge},
* {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
* {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
* @throws JVMCIError if there is something wrong with the compiled code or the metadata
*/
public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
/**
@ -422,20 +437,6 @@ final class CompilerToVM {
*/
native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
/**
* Reads an object pointer within a VM data structure. That is, any {@link HotSpotVMField} whose
* {@link HotSpotVMField#type() type} is {@code "oop"} (e.g.,
* {@code ArrayKlass::_component_mirror}, {@code Klass::_java_mirror},
* {@code JavaThread::_threadObj}).
*
* Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
* {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
* structures are (currently) always uncompressed.
*
* @param address address of an oop field within a VM data structure
*/
native Object readUncompressedOop(long address);
/**
* Determines if {@code method} should not be inlined or compiled.
*/
@ -479,11 +480,6 @@ final class CompilerToVM {
*/
native String getSymbol(long metaspaceSymbol);
/**
* Lookup a VMSymbol from a String.
*/
native long lookupSymbol(String symbol);
/**
* Looks for the next Java stack frame matching an entry in {@code methods}.
*
@ -494,10 +490,10 @@ final class CompilerToVM {
native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod[] methods, int initialSkip);
/**
* Materializes all virtual objects within {@code stackFrame} updates its locals.
* Materializes all virtual objects within {@code stackFrame} and updates its locals.
*
* @param invalidate if {@code true}, the compiled method for the stack frame will be
* invalidated.
* invalidated
*/
native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
@ -514,7 +510,6 @@ final class CompilerToVM {
/**
* Determines if debug info should also be emitted at non-safepoint locations.
*/
native boolean shouldDebugNonSafepoints();
/**

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.CompilationRequestResult;
/**
* HotSpot specific information about the result of a {@link CompilationRequest}.
*/
public final class HotSpotCompilationRequestResult implements CompilationRequestResult {
/**
* A user readable description of the failure.
*
* This field is read by the VM.
*/
private final String failureMessage;
/**
* Whether this is a transient failure where retrying would help.
*
* This field is read by the VM.
*/
private final boolean retry;
/**
* Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root
* method.
*
* This field is read by the VM.
*/
private final int inlinedBytecodes;
private HotSpotCompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) {
this.failureMessage = failureMessage;
this.retry = retry;
this.inlinedBytecodes = inlinedBytecodes;
}
public Object getFailure() {
return failureMessage;
}
/**
* Creates a result representing a successful compilation.
*
* @param inlinedBytecodes number of bytecodes inlined into the compilation, exclusive of the
* bytecodes in the root method
*/
public static HotSpotCompilationRequestResult success(int inlinedBytecodes) {
return new HotSpotCompilationRequestResult(null, true, inlinedBytecodes);
}
/**
* Creates a result representing a failed compilation.
*
* @param failureMessage a description of the failure
* @param retry whether this is a transient failure where retrying may succeed
*/
public static HotSpotCompilationRequestResult failure(String failureMessage, boolean retry) {
return new HotSpotCompilationRequestResult(failureMessage, retry, 0);
}
public String getFailureMessage() {
return failureMessage;
}
public boolean getRetry() {
return retry;
}
public int getInlinedBytecodes() {
return inlinedBytecodes;
}
}

View File

@ -25,7 +25,6 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;

View File

@ -42,7 +42,7 @@ import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link ConstantPool} for HotSpot.
*/
final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
final class HotSpotConstantPool implements ConstantPool, MetaspaceWrapperObject {
/**
* Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.

View File

@ -22,19 +22,15 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
import java.lang.reflect.Array;
import java.util.Objects;
import jdk.internal.vm.annotation.Stable;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MemoryAccessProvider;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
@ -43,7 +39,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
/**
* HotSpot implementation of {@link ConstantReflectionProvider}.
*/
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider {
protected final HotSpotJVMCIRuntimeProvider runtime;
protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
@ -88,50 +84,6 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
return Array.getLength(arrayObject);
}
public JavaConstant readConstantArrayElement(JavaConstant array, int index) {
if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
JavaConstant element = readArrayElement(array, index);
if (element != null && (((HotSpotObjectConstantImpl) array).isDefaultStable() || !element.isDefaultForKind())) {
return element;
}
}
return null;
}
/**
* Try to convert {@code offset} into an an index into {@code array}.
*
* @return the computed index or -1 if the offset isn't within the array
*/
private int indexForOffset(JavaConstant array, long offset) {
if (array.getJavaKind() != JavaKind.Object || array.isNull()) {
return -1;
}
Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
JavaKind kind = runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(componentType).getJavaKind();
int arraybase = getArrayBaseOffset(kind);
int scale = getArrayIndexScale(kind);
if (offset < arraybase) {
return -1;
}
long index = offset - arraybase;
if (index % scale != 0) {
return -1;
}
long result = index / scale;
if (result >= Integer.MAX_VALUE) {
return -1;
}
return (int) result;
}
public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) {
if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
return readConstantArrayElement(array, indexForOffset(array, offset));
}
return null;
}
@Override
public JavaConstant readArrayElement(JavaConstant array, int index) {
if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) {
@ -145,11 +97,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
if (a instanceof Object[]) {
Object element = ((Object[]) a)[index];
if (((HotSpotObjectConstantImpl) array).getStableDimension() > 1) {
return HotSpotObjectConstantImpl.forStableArray(element, ((HotSpotObjectConstantImpl) array).getStableDimension() - 1, ((HotSpotObjectConstantImpl) array).isDefaultStable());
} else {
return HotSpotObjectConstantImpl.forObject(element);
}
return HotSpotObjectConstantImpl.forObject(element);
} else {
return JavaConstant.forBoxedPrimitive(Array.get(a, index));
}
@ -227,102 +175,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
return null;
}
private static final String SystemClassName = "Ljava/lang/System;";
/**
* Determines if a static field is constant for the purpose of
* {@link #readConstantFieldValue(ResolvedJavaField, JavaConstant)}.
*/
protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
if (staticField.isFinal() || (staticField.isStable() && runtime.getConfig().foldStableValues)) {
ResolvedJavaType holder = staticField.getDeclaringClass();
if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
return true;
}
}
return false;
}
/**
* Determines if a value read from a {@code final} instance field is considered constant. The
* implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
* not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
* {@link Option#TrustFinalDefaultFields} is true.
*
* @param value a value read from a {@code final} instance field
* @param receiverClass the {@link Object#getClass() class} of object from which the
* {@code value} was read
*/
protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
return !value.isDefaultForKind() || Option.TrustFinalDefaultFields.getBoolean();
}
/**
* Determines if a value read from a {@link Stable} instance field is considered constant. The
* implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
* not the {@link JavaConstant#isDefaultForKind default value} for its kind.
*
* @param value a value read from a {@link Stable} field
* @param receiverClass the {@link Object#getClass() class} of object from which the
* {@code value} was read
*/
protected boolean isStableInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
return !value.isDefaultForKind();
}
public JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) {
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
if (hotspotField.isStatic()) {
if (isStaticFieldConstant(hotspotField)) {
JavaConstant value = readFieldValue(field, receiver);
if (hotspotField.isFinal() || !value.isDefaultForKind()) {
return value;
}
}
} else {
/*
* for non-static final fields, we must assume that they are only initialized if they
* have a non-default value.
*/
Object object = receiver.isNull() ? null : ((HotSpotObjectConstantImpl) receiver).object();
// Canonicalization may attempt to process an unsafe read before
// processing a guard (e.g. a null check or a type check) for this read
// so we need to check the object being read
if (object != null) {
if (hotspotField.isFinal()) {
if (hotspotField.isInObject(object)) {
JavaConstant value = readFieldValue(field, receiver);
if (isFinalInstanceFieldValueConstant(value, object.getClass())) {
return value;
}
}
} else if (hotspotField.isStable() && runtime.getConfig().foldStableValues) {
if (hotspotField.isInObject(object)) {
JavaConstant value = readFieldValue(field, receiver);
if (isStableInstanceFieldValueConstant(value, object.getClass())) {
return value;
}
}
}
}
}
return null;
}
public JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) {
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
if (!hotspotField.isStable()) {
return readNonStableFieldValue(field, receiver);
} else if (runtime.getConfig().foldStableValues) {
return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
} else {
return null;
}
}
private JavaConstant readNonStableFieldValue(ResolvedJavaField field, JavaConstant receiver) {
HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
if (hotspotField.isStatic()) {
HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
@ -337,27 +190,6 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
return null;
}
public JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable) {
JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
if (fieldValue != null && fieldValue.isNonNull()) {
JavaType declaredType = field.getType();
if (declaredType.getComponentType() != null) {
int stableDimension = getArrayDimension(declaredType);
return HotSpotObjectConstantImpl.forStableArray(((HotSpotObjectConstantImpl) fieldValue).object(), stableDimension, isDefaultStable);
}
}
return fieldValue;
}
private static int getArrayDimension(JavaType type) {
int dimensions = 0;
JavaType componentType = type;
while ((componentType = componentType.getComponentType()) != null) {
dimensions++;
}
return dimensions;
}
@Override
public JavaConstant asJavaClass(ResolvedJavaType type) {
return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedJavaType) type).mirror());

View File

@ -23,9 +23,9 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.internal.misc.Unsafe;
import jdk.vm.ci.code.InstalledCode;
/**
* Implementation of {@link InstalledCode} for HotSpot.

View File

@ -22,27 +22,30 @@
*/
package jdk.vm.ci.hotspot;
import java.lang.reflect.Module;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.CompilationRequestResult;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.runtime.JVMCICompiler;
import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
import jdk.vm.ci.services.Services;
final class HotSpotJVMCICompilerConfig {
private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
private static class DummyCompilerFactory extends JVMCICompilerFactory implements JVMCICompiler {
public CompilationRequestResult compileMethod(CompilationRequest request) {
public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
throw new JVMCIError("no JVMCI compiler selected");
}
@Override
public String getCompilerName() {
return "<none>";
}
@Override
public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
return this;
}
@ -65,6 +68,9 @@ final class HotSpotJVMCICompilerConfig {
if (compilerName != null) {
for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
if (f.getCompilerName().equals(compilerName)) {
Module jvmciModule = JVMCICompilerFactory.class.getModule();
Services.exportJVMCITo(f.getClass());
f.onSelection();
factory = f;
}
}

View File

@ -30,7 +30,6 @@ import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaType;
@ -47,7 +46,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
* longer used.
*
*/
public class HotSpotJVMCIMetaAccessContext implements JVMCIMetaAccessContext {
public class HotSpotJVMCIMetaAccessContext {
/**
* The set of currently live contexts used for tracking of live metadata. Examined from the VM
@ -149,7 +148,11 @@ public class HotSpotJVMCIMetaAccessContext implements JVMCIMetaAccessContext {
private final Map<Class<?>, WeakReference<ResolvedJavaType>> typeMap = new WeakHashMap<>();
@Override
/**
* Gets the JVMCI mirror for a {@link Class} object.
*
* @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
*/
public synchronized ResolvedJavaType fromClass(Class<?> javaClass) {
WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
ResolvedJavaType type = typeRef != null ? typeRef.get() : null;

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import static jdk.vm.ci.common.InitTimer.timer;
import java.io.IOException;
import java.io.OutputStream;
@ -37,24 +37,23 @@ import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import jdk.internal.misc.VM;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CompilationRequestResult;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;
import jdk.vm.ci.runtime.JVMCIBackend;
import jdk.vm.ci.runtime.JVMCICompiler;
import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
import jdk.vm.ci.services.Services;
import jdk.internal.misc.VM;
//JaCoCo Exclude
/**
* HotSpot implementation of a JVMCI runtime.
@ -66,7 +65,7 @@ import jdk.internal.misc.VM;
* {@link #runtime()}. This allows the initialization to funnel back through
* {@link JVMCI#initialize()} without deadlocking.
*/
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
@SuppressWarnings("try")
static class DelayedInit {
@ -92,14 +91,12 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
*/
public enum Option {
Compiler(String.class, null, "Selects the system compiler."),
ImplicitStableValues(boolean.class, true, "Mark well-known stable fields as such."),
// Note: The following one is not used (see InitTimer.ENABLED).
InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."),
PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
TraceMethodDataFilter(String.class, null, ""),
TrustFinalDefaultFields(boolean.class, true, "Determines whether to treat final fields with default values as constant.");
TraceMethodDataFilter(String.class, null, "");
/**
* The prefix for system properties that are JVMCI options.
@ -203,13 +200,25 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
protected final HotSpotVMConfig config;
private final JVMCIBackend hostBackend;
private final JVMCICompilerFactory compilerFactory;
private final HotSpotJVMCICompilerFactory hsCompilerFactory;
private volatile JVMCICompiler compiler;
protected final JVMCIMetaAccessContext metaAccessContext;
protected final HotSpotJVMCIMetaAccessContext metaAccessContext;
/**
* Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so
* that it can be read from the VM.
*/
@SuppressWarnings("unused") private final int compilationLevelAdjustment;
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
private final Iterable<HotSpotVMEventListener> vmEventListeners;
/**
* Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can
* be read from the VM.
*/
@SuppressWarnings("unused") private final String[] trivialPrefixes;
@SuppressWarnings("try")
@ -233,17 +242,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
vmEventListeners = Services.load(HotSpotVMEventListener.class);
JVMCIMetaAccessContext context = null;
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
context = vmEventListener.createMetaAccessContext(this);
if (context != null) {
break;
}
}
if (context == null) {
context = new HotSpotJVMCIMetaAccessContext();
}
metaAccessContext = context;
metaAccessContext = new HotSpotJVMCIMetaAccessContext();
boolean printFlags = Option.PrintFlags.getBoolean();
boolean showFlags = Option.ShowFlags.getBoolean();
@ -258,7 +257,16 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
printConfig(config, compilerToVm);
}
trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();
compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
trivialPrefixes = hsCompilerFactory.getTrivialPrefixes();
compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config);
} else {
hsCompilerFactory = null;
trivialPrefixes = null;
compilationLevelAdjustment = 0;
}
}
private JVMCIBackend registerBackend(JVMCIBackend backend) {
@ -280,15 +288,11 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
return compilerToVm;
}
public JVMCIMetaAccessContext getMetaAccessContext() {
return metaAccessContext;
}
public JVMCICompiler getCompiler() {
if (compiler == null) {
synchronized (this) {
if (compiler == null) {
compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
compiler = compilerFactory.createCompiler(this);
}
}
}
@ -331,10 +335,32 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
* Called from the VM.
*/
@SuppressWarnings({"unused"})
private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level);
}
/**
* Called from the VM.
*/
@SuppressWarnings({"unused"})
private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
assert result != null : "compileMethod must always return something";
return result;
HotSpotCompilationRequestResult hsResult;
if (result instanceof HotSpotCompilationRequestResult) {
hsResult = (HotSpotCompilationRequestResult) result;
} else {
Object failure = result.getFailure();
if (failure != null) {
boolean retry = false; // Be conservative with unknown compiler
hsResult = HotSpotCompilationRequestResult.failure(failure.toString(), retry);
} else {
int inlinedBytecodes = -1;
hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes);
}
}
return hsResult;
}
/**
@ -349,6 +375,18 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
}
}
/**
* Notify on completion of a bootstrap.
*
* Called from the VM.
*/
@SuppressWarnings({"unused"})
private void bootstrapFinished() throws Exception {
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
vmEventListener.notifyBootstrapFinished();
}
}
/**
* Notify on successful install into the CodeCache.
*

View File

@ -24,15 +24,12 @@ package jdk.vm.ci.hotspot;
import java.io.OutputStream;
import jdk.internal.misc.Unsafe;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.internal.misc.Unsafe;
//JaCoCo Exclude
/**
* Configuration information for the HotSpot JVMCI runtime.
@ -70,8 +67,6 @@ public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
*/
ResolvedJavaType fromClass(Class<?> clazz);
JVMCIMetaAccessContext getMetaAccessContext();
/**
* The offset from the origin of an array to the first element.
*

View File

@ -39,6 +39,4 @@ public interface HotSpotMemoryAccessProvider extends MemoryAccessProvider {
Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding);
Constant readMethodPointerConstant(Constant base, long displacement);
Constant readSymbolConstant(Constant base, long displacement);
}

View File

@ -33,7 +33,7 @@ import jdk.vm.ci.meta.PrimitiveConstant;
/**
* HotSpot implementation of {@link MemoryAccessProvider}.
*/
class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider {
protected final HotSpotJVMCIRuntimeProvider runtime;
@ -135,7 +135,7 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho
if (base == null) {
assert !compressed;
displacement += asRawPointer(baseConstant);
ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
ret = UNSAFE.getUncompressedObject(displacement);
} else {
assert runtime.getConfig().useCompressedOops == compressed;
ret = UNSAFE.getObject(base, displacement);
@ -232,16 +232,4 @@ class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, Ho
HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
}
@Override
public Constant readSymbolConstant(Constant base, long displacement) {
int bits = runtime.getConfig().symbolPointerSize * Byte.SIZE;
long pointer = readRawValue(base, displacement, bits);
if (pointer == 0) {
return JavaConstant.NULL_POINTER;
} else {
String symbol = runtime.getCompilerToVM().getSymbol(pointer);
return new HotSpotSymbol(symbol, pointer).asConstant();
}
}
}

View File

@ -52,7 +52,7 @@ import jdk.vm.ci.meta.Signature;
/**
* HotSpot implementation of {@link MetaAccessProvider}.
*/
public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified {
public class HotSpotMetaAccessProvider implements MetaAccessProvider {
protected final HotSpotJVMCIRuntimeProvider runtime;
@ -78,15 +78,6 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
return new HotSpotSignature(runtime, signature);
}
public HotSpotSymbol lookupSymbol(String symbol) {
long pointer = runtime.getCompilerToVM().lookupSymbol(symbol);
if (pointer == 0) {
return null;
} else {
return new HotSpotSymbol(symbol, pointer);
}
}
/**
* {@link Field} object of {@link Method#slot}.
*/
@ -152,7 +143,8 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
int actionValue = convertDeoptAction(action);
int reasonValue = convertDeoptReason(reason);
int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits);
JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
JavaConstant c = JavaConstant.forInt(
~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
assert c.asInt() < 0;
return c;
}
@ -316,7 +308,6 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
return 0;
} else {
if (lookupJavaType.isArray()) {
// TODO(tw): Add compressed pointer support.
int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
ResolvedJavaType elementType = lookupJavaType.getComponentType();
JavaKind elementKind = elementType.getJavaKind();

View File

@ -22,8 +22,9 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
/**
* Encapsulates the VM metadata generated by {@link CompilerToVM#getMetadata}.
*/
public class HotSpotMetaData {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] pcDescBytes;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;

View File

@ -29,6 +29,4 @@ public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant {
HotSpotResolvedObjectType asResolvedJavaType();
HotSpotResolvedJavaMethod asResolvedJavaMethod();
HotSpotSymbol asSymbol();
}

View File

@ -27,7 +27,7 @@ import java.util.Objects;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.VMConstant;
final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant {
static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
@ -108,11 +108,4 @@ final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VM
}
return null;
}
public HotSpotSymbol asSymbol() {
if (metaspaceObject instanceof HotSpotSymbol) {
return (HotSpotSymbol) metaspaceObject;
}
return null;
}
}

View File

@ -32,7 +32,7 @@ import java.util.Formatter;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
abstract class HotSpotMethod implements JavaMethod, Formattable {
public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
if (flags == 0 && width < 0) {

View File

@ -33,7 +33,7 @@ import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider {
private final ConstantReflectionProvider constantReflection;

View File

@ -28,7 +28,6 @@ import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
@ -39,7 +38,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
* Represents a constant non-{@code null} object reference, within the compiler and across the
* compiler/runtime interface.
*/
final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
final class HotSpotObjectConstantImpl implements HotSpotObjectConstant {
static JavaConstant forObject(Object object) {
return forObject(object, false);
@ -53,15 +52,6 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
}
}
static JavaConstant forStableArray(Object object, int stableDimension, boolean isDefaultStable) {
if (object == null) {
return JavaConstant.NULL_POINTER;
} else {
assert object.getClass().isArray();
return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
}
}
public static JavaConstant forBoxedValue(JavaKind kind, Object value) {
if (kind == JavaKind.Object) {
return HotSpotObjectConstantImpl.forObject(value);
@ -82,22 +72,11 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
private final Object object;
private final boolean compressed;
private final byte stableDimension;
private final boolean isDefaultStable;
private HotSpotObjectConstantImpl(Object object, boolean compressed, int stableDimension, boolean isDefaultStable) {
this.object = object;
this.compressed = compressed;
this.stableDimension = (byte) stableDimension;
this.isDefaultStable = isDefaultStable;
assert object != null;
assert stableDimension == 0 || (object != null && object.getClass().isArray());
assert stableDimension >= 0 && stableDimension <= 255;
assert !isDefaultStable || stableDimension > 0;
}
private HotSpotObjectConstantImpl(Object object, boolean compressed) {
this(object, compressed, 0, false);
this.object = object;
this.compressed = compressed;
assert object != null;
}
@Override
@ -118,12 +97,12 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
public JavaConstant compress() {
assert !compressed;
return new HotSpotObjectConstantImpl(object, true, stableDimension, isDefaultStable);
return new HotSpotObjectConstantImpl(object, true);
}
public JavaConstant uncompress() {
assert compressed;
return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
return new HotSpotObjectConstantImpl(object, false);
}
public HotSpotResolvedObjectType getType() {
@ -248,7 +227,7 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
return true;
} else if (o instanceof HotSpotObjectConstantImpl) {
HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o;
return object == other.object && compressed == other.compressed && stableDimension == other.stableDimension && isDefaultStable == other.isDefaultStable;
return object == other.object && compressed == other.compressed;
}
return false;
}
@ -266,19 +245,4 @@ final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotP
public String toString() {
return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + JavaKind.Object.format(object) + "]";
}
/**
* Number of stable dimensions if this constant is a stable array.
*/
public int getStableDimension() {
return stableDimension & 0xff;
}
/**
* Returns {@code true} if this is a stable array constant and its elements should be considered
* as stable regardless of whether they are default values.
*/
public boolean isDefaultStable() {
return isDefaultStable;
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
public class HotSpotOopMap {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int offset;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int count;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] data;
public byte[] data() {
return data;
}
public int count() {
return count;
}
public int offset() {
return offset;
}
}

View File

@ -28,10 +28,7 @@ import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.TriState;
public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {
// private static final DebugMetric metricInsufficentSpace =
// Debug.metric("InsufficientSpaceForProfilingData");
public final class HotSpotProfilingInfo implements ProfilingInfo {
private final HotSpotMethodData methodData;
private final HotSpotResolvedJavaMethod method;
@ -162,7 +159,6 @@ public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxifi
if (!methodData.isWithin(currentPosition)) {
exceptionPossiblyNotRecorded = true;
// metricInsufficentSpace.increment();
}
}

View File

@ -53,7 +53,7 @@ public final class HotSpotReferenceMap extends ReferenceMap {
}
if (obj instanceof HotSpotReferenceMap) {
HotSpotReferenceMap that = (HotSpotReferenceMap) obj;
if (Arrays.equals(objects, that.objects)) {
if (sizeInBytes == that.sizeInBytes && maxRegisterSize == that.maxRegisterSize && Arrays.equals(objects, that.objects) && Arrays.equals(derivedBase, that.derivedBase)) {
return true;
}
}

View File

@ -43,11 +43,4 @@ public interface HotSpotResolvedJavaField extends ResolvedJavaField {
* Determines if this field should be treated as a constant.
*/
boolean isStable();
/**
* Determines if this field should be considered constant if it has the default value for its
* type (e.g, 0, null, etc.). The result of this method is undefined if this field is not
* {@linkplain #isStable() stable}.
*/
boolean isDefaultStable();
}

View File

@ -22,16 +22,15 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import jdk.internal.vm.annotation.Stable;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LocationIdentity;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
@ -40,7 +39,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Represents a field in a HotSpot type.
*/
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
private final HotSpotResolvedObjectTypeImpl holder;
private final String name;
@ -51,43 +50,6 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
* This value contains all flags as stored in the VM including internal ones.
*/
private final int modifiers;
private final LocationIdentity locationIdentity = new FieldLocationIdentity(this);
public static class FieldLocationIdentity extends LocationIdentity {
HotSpotResolvedJavaField inner;
FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
this.inner = inner;
}
@Override
public boolean isImmutable() {
return false;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof FieldLocationIdentity) {
FieldLocationIdentity fieldLocationIdentity = (FieldLocationIdentity) obj;
return inner.equals(fieldLocationIdentity.inner);
}
return false;
}
@Override
public int hashCode() {
return inner.hashCode();
}
@Override
public String toString() {
return inner.getName();
}
}
HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
this.holder = holder;
@ -190,14 +152,7 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
* @return true if field has {@link Stable} annotation, false otherwise
*/
public boolean isStable() {
if ((config().jvmAccFieldStable & modifiers) != 0) {
return true;
}
assert getAnnotation(Stable.class) == null;
if (Option.ImplicitStableValues.getBoolean() && isImplicitStableField()) {
return true;
}
return false;
return (config().jvmAccFieldStable & modifiers) != 0;
}
@Override
@ -209,6 +164,15 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
return new Annotation[0];
}
@Override
public Annotation[] getDeclaredAnnotations() {
Field javaField = toJava();
if (javaField != null) {
return javaField.getDeclaredAnnotations();
}
return new Annotation[0];
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
Field javaField = toJava();
@ -234,69 +198,4 @@ class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotP
return null;
}
}
private boolean isArray() {
JavaType fieldType = getType();
return fieldType instanceof ResolvedJavaType && ((ResolvedJavaType) fieldType).isArray();
}
private boolean isImplicitStableField() {
if (isSyntheticEnumSwitchMap()) {
return true;
}
if (isWellKnownImplicitStableField()) {
return true;
}
return false;
}
public boolean isDefaultStable() {
assert this.isStable();
if (isSyntheticEnumSwitchMap()) {
return true;
}
return false;
}
private boolean isSyntheticEnumSwitchMap() {
if (isSynthetic() && isStatic() && isArray()) {
if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
// generated int[] field for EnumClass::values()
return true;
} else if (name.startsWith("$SwitchMap$") || name.startsWith("$SWITCH_TABLE$")) {
// javac and ecj generate a static field in an inner class for a switch on an enum
// named $SwitchMap$p$k$g$EnumClass and $SWITCH_TABLE$p$k$g$EnumClass, respectively
return true;
}
}
return false;
}
private boolean isWellKnownImplicitStableField() {
return WellKnownImplicitStableField.test(this);
}
static class WellKnownImplicitStableField {
/**
* @return {@code true} if the field is a well-known stable field.
*/
public static boolean test(HotSpotResolvedJavaField field) {
return field.equals(STRING_VALUE_FIELD);
}
private static final ResolvedJavaField STRING_VALUE_FIELD;
static {
try {
MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();
STRING_VALUE_FIELD = metaAccess.lookupJavaField(String.class.getDeclaredField("value"));
} catch (SecurityException | NoSuchFieldException e) {
throw new JVMCIError(e);
}
}
}
public LocationIdentity getLocationIdentity() {
return locationIdentity;
}
}

View File

@ -46,11 +46,8 @@ import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LineNumberTable;
import jdk.vm.ci.meta.LineNumberTableImpl;
import jdk.vm.ci.meta.Local;
import jdk.vm.ci.meta.LocalImpl;
import jdk.vm.ci.meta.LocalVariableTable;
import jdk.vm.ci.meta.LocalVariableTableImpl;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -62,7 +59,7 @@ import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceWrapperObject {
/**
* Reference to metaspace Method object.
@ -472,7 +469,19 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
@Override
public Annotation[] getAnnotations() {
Executable javaMethod = toJava();
return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
if (javaMethod != null) {
return javaMethod.getAnnotations();
}
return new Annotation[0];
}
@Override
public Annotation[] getDeclaredAnnotations() {
Executable javaMethod = toJava();
if (javaMethod != null) {
return javaMethod.getDeclaredAnnotations();
}
return new Annotation[0];
}
@Override
@ -559,7 +568,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
line[i] = (int) values[i * 2 + 1];
}
return new LineNumberTableImpl(line, bci);
return new LineNumberTable(line, bci);
}
@Override
@ -584,13 +593,13 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
String localName = getConstantPool().lookupUtf8(nameCpIndex);
String localType = getConstantPool().lookupUtf8(typeCpIndex);
locals[i] = new LocalImpl(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot);
locals[i] = new Local(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot);
// Go to the next LocalVariableTableElement
localVariableTableElement += config.localVariableTableElementSize;
}
return new LocalVariableTableImpl(locals);
return new LocalVariableTable(locals);
}
/**

View File

@ -28,7 +28,6 @@ import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
@ -60,8 +59,6 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
HotSpotResolvedObjectType asExactType();
default boolean isPrimitive() {
return false;
}
@ -109,6 +106,4 @@ public interface HotSpotResolvedObjectType extends ResolvedJavaType {
HotSpotResolvedObjectType getEnclosingType();
ResolvedJavaMethod getClassInitializer();
ResolvedJavaField createField(String name, JavaType type, long offset, int modifiers);
}

View File

@ -52,12 +52,11 @@ import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.TrustedInterface;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceWrapperObject {
/**
* The Java class this type represents.
@ -128,9 +127,9 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
*/
long getMetaspaceKlass() {
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
return UNSAFE.getLong(javaClass, (long) config().klassOffset);
return UNSAFE.getLong(javaClass, config().klassOffset);
}
return UNSAFE.getInt(javaClass, (long) config().klassOffset) & 0xFFFFFFFFL;
return UNSAFE.getInt(javaClass, config().klassOffset) & 0xFFFFFFFFL;
}
public long getMetaspacePointer() {
@ -167,9 +166,25 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
if (isLeaf()) {
// No assumptions are required.
return new AssumptionResult<>(this);
}
HotSpotVMConfig config = config();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
ResolvedJavaType elementalType = getElementalType();
AssumptionResult<ResolvedJavaType> elementType = elementalType.findLeafConcreteSubtype();
if (elementType != null && elementType.getResult().equals(elementalType)) {
/*
* If the elementType is leaf then the array is leaf under the same assumptions but
* only if the element type is exactly the leaf type. The element type can be
* abstract even if there is only one implementor of the abstract type.
*/
AssumptionResult<ResolvedJavaType> result = new AssumptionResult<>(this);
result.add(elementType);
return result;
}
return null;
} else if (isInterface()) {
HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
/*
@ -192,8 +207,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
return null;
}
return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
return concreteSubtype(implementor);
} else {
HotSpotResolvedObjectTypeImpl type = this;
while (type.isAbstract()) {
@ -207,7 +221,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return null;
}
if (this.isAbstract()) {
return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
return concreteSubtype(type);
} else {
assert this.equals(type);
return new AssumptionResult<>(type, new LeafType(type));
@ -215,6 +229,14 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
}
private AssumptionResult<ResolvedJavaType> concreteSubtype(HotSpotResolvedObjectTypeImpl type) {
if (type.isLeaf()) {
return new AssumptionResult<>(type, new ConcreteSubtype(this, type));
} else {
return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
}
}
/**
* Returns if type {@code type} is a leaf class. This is the case if the
* {@code Klass::_subklass} field of the underlying class is zero.
@ -296,11 +318,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
}
}
@Override
public HotSpotResolvedObjectType asExactType() {
return isLeaf() ? this : null;
}
@Override
public AssumptionResult<Boolean> hasFinalizableSubclass() {
assert !isArray();
@ -470,7 +487,7 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return result;
}
public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
HotSpotResolvedJavaField result = null;
final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
@ -490,7 +507,12 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
fieldCache.put(id, result);
} else {
assert result.getName().equals(fieldName);
// assert result.getType().equals(type);
/*
* Comparing the types directly is too strict, because the type in the cache could be
* resolved while the incoming type is unresolved. The name comparison is sufficient
* because the type will always be resolved in the context of the holder.
*/
assert result.getType().getName().equals(type.getName());
assert result.offset() == offset;
assert result.getModifiers() == flags;
}
@ -744,6 +766,11 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return mirror().getAnnotations();
}
@Override
public Annotation[] getDeclaredAnnotations() {
return mirror().getDeclaredAnnotations();
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
return mirror().getAnnotation(annotationClass);
@ -878,11 +905,6 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
return "HotSpotType<" + getName() + ", resolved>";
}
@Override
public boolean isTrustedInterfaceType() {
return TrustedInterface.class.isAssignableFrom(mirror());
}
@Override
public boolean isCloneableWithAllocation() {
return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,7 +40,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for primitive HotSpot types.
*/
public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType implements HotSpotProxified {
public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType {
private final JavaKind kind;
@ -55,7 +55,7 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
* @param kind the Kind to create the mirror for
*/
public HotSpotResolvedPrimitiveType(JavaKind kind) {
super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
super(String.valueOf(kind.getTypeChar()));
this.kind = kind;
assert mirror().isPrimitive() : mirror() + " not a primitive type";
}
@ -83,11 +83,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
return null;
}
@Override
public ResolvedJavaType asExactType() {
return this;
}
@Override
public ResolvedJavaType getSuperclass() {
return null;
@ -203,6 +198,11 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
return new Annotation[0];
}
@Override
public Annotation[] getDeclaredAnnotations() {
return new Annotation[0];
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
return null;
@ -263,11 +263,6 @@ public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType
return null;
}
@Override
public boolean isTrustedInterfaceType() {
return false;
}
@Override
public boolean isCloneableWithAllocation() {
return false;

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,7 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.ValueKind;
import jdk.vm.ci.meta.VMConstant;
import jdk.vm.ci.meta.Value;
@ -32,8 +32,8 @@ public final class HotSpotSentinelConstant extends Value implements JavaConstant
private final JavaKind javaKind;
public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
super(lirKind);
public HotSpotSentinelConstant(ValueKind<?> valueKind, JavaKind javaKind) {
super(valueKind);
this.javaKind = javaKind;
}

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.Constant;
/**
* Class to access the C++ {@code vmSymbols} table.
*/
public final class HotSpotSymbol implements MetaspaceWrapperObject {
private final String symbol;
private final long pointer;
HotSpotSymbol(String symbol, long pointer) {
this.symbol = symbol;
this.pointer = pointer;
}
public String getSymbol() {
return symbol;
}
public Constant asConstant() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
@Override
public long getMetaspacePointer() {
return pointer;
}
@Override
public String toString() {
return "Symbol<" + symbol + ">";
}
}

View File

@ -22,7 +22,6 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.common.UnsafeUtil.readCString;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
@ -31,6 +30,8 @@ import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Iterator;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.Stable;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMConstant;
@ -38,9 +39,6 @@ import jdk.vm.ci.hotspotvmconfig.HotSpotVMData;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
import jdk.internal.misc.Unsafe;
//JaCoCo Exclude
/**
* Used to access native configuration details.
@ -108,6 +106,27 @@ public class HotSpotVMConfig {
return getClass().getSimpleName();
}
/**
* Reads a {@code '\0'} terminated C string from native memory and converts it to a
* {@link String}.
*
* @return a Java string
*/
private static String readCString(Unsafe unsafe, long address) {
if (address == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0;; i++) {
char c = (char) unsafe.getByte(address + i);
if (c == 0) {
break;
}
sb.append(c);
}
return sb.toString();
}
/**
* Initialize fields by reading their values from vmStructs.
*/
@ -1256,8 +1275,16 @@ public class HotSpotVMConfig {
@HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
@HotSpotVMField(name = "nmethod::_comp_level", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodCompLevelOffset;
@HotSpotVMConstant(name = "CompLevel_none") @Stable public int compilationLevelNone;
@HotSpotVMConstant(name = "CompLevel_simple") @Stable public int compilationLevelSimple;
@HotSpotVMConstant(name = "CompLevel_limited_profile") @Stable public int compilationLevelLimitedProfile;
@HotSpotVMConstant(name = "CompLevel_full_profile") @Stable public int compilationLevelFullProfile;
@HotSpotVMConstant(name = "CompLevel_full_optimization") @Stable public int compilationLevelFullOptimization;
@HotSpotVMConstant(name = "JVMCIRuntime::none") @Stable public int compLevelAdjustmentNone;
@HotSpotVMConstant(name = "JVMCIRuntime::by_holder") @Stable public int compLevelAdjustmentByHolder;
@HotSpotVMConstant(name = "JVMCIRuntime::by_full_signature") @Stable public int compLevelAdjustmentByFullSignature;
@HotSpotVMConstant(name = "InvocationEntryBci") @Stable public int invocationEntryBci;
@HotSpotVMField(name = "JVMCIEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvTaskOffset;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -20,19 +20,21 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation functions as an alias for the jdk.internal.vm.annotation.Stable annotation within JVMCI
* code. It is specially recognized during class file parsing in the same way as that annotation.
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Stable {
@interface SuppressFBWarnings {
/**
* The set of FindBugs
* <a href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
* suppressed in annotated element. The value can be a bug category, kind or pattern.
*/
String[] value();
/**
* Reason why the warning is suppressed.
*/
String justification();
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Logging framework for the HotSpot CRI implementation.
*/
package jdk.vm.ci.hotspot.logging;

View File

@ -20,23 +20,30 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot.events;
import jdk.vm.ci.common.JVMCIError;
package jdk.vm.ci.hotspot.services;
/**
* An empty implementation for {@link EventProvider}. This implementation is used when no logging is
* requested.
*/
public final class EmptyEventProvider implements EventProvider {
final class EmptyEventProvider extends EventProvider {
EmptyEventProvider() {
super(null);
}
static InternalError shouldNotReachHere() {
throw new InternalError("should not reach here");
}
@Override
public CompilationEvent newCompilationEvent() {
return new EmptyCompilationEvent();
}
public static class EmptyCompilationEvent implements CompilationEvent {
static class EmptyCompilationEvent implements CompilationEvent {
public void commit() {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public boolean shouldWrite() {
@ -51,41 +58,42 @@ public final class EmptyEventProvider implements EventProvider {
}
public void setMethod(String method) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setCompileId(int compileId) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setCompileLevel(int compileLevel) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setSucceeded(boolean succeeded) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setIsOsr(boolean isOsr) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setCodeSize(int codeSize) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setInlinedBytes(int inlinedBytes) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
}
@Override
public CompilerFailureEvent newCompilerFailureEvent() {
return new EmptyCompilerFailureEvent();
}
public static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
public void commit() {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public boolean shouldWrite() {
@ -94,11 +102,11 @@ public final class EmptyEventProvider implements EventProvider {
}
public void setCompileId(int compileId) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
public void setMessage(String message) {
throw JVMCIError.shouldNotReachHere();
throw shouldNotReachHere();
}
}

View File

@ -20,17 +20,65 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot.events;
package jdk.vm.ci.hotspot.services;
import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilationEvent;
import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilerFailureEvent;
import jdk.vm.ci.services.JVMCIPermission;
/**
* A provider that provides a specific implementation for events that can be logged in the compiler.
* Service-provider class for logging compiler related events.
*/
public interface EventProvider {
public abstract class EventProvider {
private static Void checkPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
return null;
}
@SuppressWarnings("unused")
EventProvider(Void ignore) {
}
/**
* Initializes a new instance of this class.
*
* @throws SecurityException if a security manager has been installed and it denies
* {@link JVMCIPermission}
*/
protected EventProvider() {
this(checkPermission());
}
/**
* Creates and returns an empty implementation for {@link EventProvider}. This implementation
* can be used when no logging is requested.
*/
public static EventProvider createEmptyEventProvider() {
return new EmptyEventProvider();
}
/**
* Creates and returns an empty implementation for {@link CompilationEvent}.
*/
public static CompilationEvent createEmptyCompilationEvent() {
return new EmptyCompilationEvent();
}
/**
* Creates and returns an empty implementation for {@link CompilationEvent}.
*/
public static CompilerFailureEvent createEmptyCompilerFailureEvent() {
return new EmptyCompilerFailureEvent();
}
/**
* An instant event is an event that is not considered to have taken any time.
*/
interface InstantEvent {
public interface InstantEvent {
/**
* Commits the event.
*/
@ -49,7 +97,7 @@ public interface EventProvider {
/**
* Timed events describe an operation that somehow consumes time.
*/
interface TimedEvent extends InstantEvent {
public interface TimedEvent extends InstantEvent {
/**
* Starts the timing for this event.
*/
@ -66,12 +114,12 @@ public interface EventProvider {
*
* @return a compilation event
*/
CompilationEvent newCompilationEvent();
public abstract CompilationEvent newCompilationEvent();
/**
* A compilation event.
*/
interface CompilationEvent extends TimedEvent {
public interface CompilationEvent extends TimedEvent {
void setMethod(String method);
void setCompileId(int compileId);
@ -92,12 +140,12 @@ public interface EventProvider {
*
* @return a compiler failure event
*/
CompilerFailureEvent newCompilerFailureEvent();
public abstract CompilerFailureEvent newCompilerFailureEvent();
/**
* A compiler failure event.
*/
interface CompilerFailureEvent extends InstantEvent {
public interface CompilerFailureEvent extends InstantEvent {
void setCompileId(int compileId);
void setMessage(String message);

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot.services;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
/**
* HotSpot extensions to {@link JVMCICompilerFactory}.
*/
public abstract class HotSpotJVMCICompilerFactory extends JVMCICompilerFactory {
/**
* Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
* (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
* prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
*
* @return 0 or more Strings identifying packages that should by compiled by the first tier only
* or null if no redirection to C1 should be performed.
*/
public String[] getTrivialPrefixes() {
return null;
}
/**
* Determines if this object may want to adjust the compilation level for a method that is being
* scheduled by the VM for compilation. The legal return values and their meanings are:
* <ul>
* <li>0 - no adjustment</li>
* <li>1 - adjust based on declaring class of method</li>
* <li>2 - adjust based on declaring class, name and signature of method</li>
* </ul>
*/
public int getCompilationLevelAdjustment(HotSpotVMConfig config) {
return config.compLevelAdjustmentNone;
}
/**
* Potentially modifies the compilation level currently selected by the VM compilation policy
* for a method.
*
* @param config object for reading HotSpot {@code CompLevel} enum values
* @param declaringClass the class in which the method is declared
* @param name the name of the method or {@code null} depending on the value that was returned
* by {@link #getCompilationLevelAdjustment(HotSpotVMConfig)}
* @param signature the signature of the method or {@code null} depending on the value that was
* returned by {@link #getCompilationLevelAdjustment(HotSpotVMConfig)}
* @param isOsr specifies if the compilation being scheduled in an OSR compilation
* @param level the compilation level currently selected by the VM compilation policy
* @return the compilation level to use for the compilation being scheduled (must be a valid
* {@code CompLevel} enum value)
*/
public int adjustCompilationLevel(HotSpotVMConfig config, Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
throw new InternalError("Should not reach here");
}
}

View File

@ -20,19 +20,44 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
package jdk.vm.ci.hotspot.services;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.services.JVMCIPermission;
public interface HotSpotVMEventListener {
/**
* Service-provider class for responding to VM events.
*/
public abstract class HotSpotVMEventListener {
private static Void checkPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
return null;
}
@SuppressWarnings("unused")
HotSpotVMEventListener(Void ignore) {
}
/**
* Initializes a new instance of this class.
*
* @throws SecurityException if a security manager has been installed and it denies
* {@link JVMCIPermission}
*/
protected HotSpotVMEventListener() {
this(checkPermission());
}
/**
* Notifies this client that the VM is shutting down.
*/
default void notifyShutdown() {
public void notifyShutdown() {
}
/**
@ -42,18 +67,12 @@ public interface HotSpotVMEventListener {
* @param installedCode
* @param compiledCode
*/
default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
public void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
}
/**
* Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded
* metadata. It a custom one isn't created then the default implementation will be a single
* context with globally shared instances of {@link ResolvedJavaType} that are never released.
*
* @param hotSpotJVMCIRuntime
* @return a custom context or null
* Notify on completion of a bootstrap.
*/
default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) {
return null;
public void notifyBootstrapFinished() {
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,7 @@ public abstract class AllocatableValue extends Value implements JavaValue {
public static final AllocatableValue[] NONE = {};
public AllocatableValue(LIRKind lirKind) {
super(lirKind);
public AllocatableValue(ValueKind<?> kind) {
super(kind);
}
}

View File

@ -44,7 +44,10 @@ public final class Assumptions implements Iterable<Assumptions.Assumption> {
/**
* A class for providing information that is only valid in association with a set of
* {@link Assumption}s.
* {@link Assumption}s. It is permissible for AssumptionResults to have no assumptions at all.
* For instance, if {@link ResolvedJavaType#isLeaf()} returns true for a type
* {@link ResolvedJavaType#findLeafConcreteSubtype()} can return an AssumptionResult with no
* assumptions since the leaf information is statically true.
*
* @param <T>
*/
@ -187,6 +190,7 @@ public final class Assumptions implements Iterable<Assumptions.Assumption> {
public final ResolvedJavaType context;
public LeafType(ResolvedJavaType context) {
assert !context.isLeaf() : "assumption isn't required for leaf types";
this.context = context;
}

View File

@ -55,40 +55,11 @@ public interface ConstantReflectionProvider {
*/
JavaConstant readArrayElement(JavaConstant array, int index);
/**
* Reads a value from the given array at the given index if it is a stable array. Returns
* {@code null} if the constant is not a stable array, if it is a default value, if the index is
* out of bounds, or if the value is not available at this point.
*/
JavaConstant readConstantArrayElement(JavaConstant array, int index);
/**
* Reads a value from the given array at the given offset if it is a stable array. The offset
* will be decoded relative to the platform addressing into an index into the array. Returns
* {@code null} if the constant is not a stable array, if it is a default value, if the offset
* is out of bounds, or if the value is not available at this point.
*/
JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset);
/**
* Gets the constant value of this field. Note that a {@code static final} field may not be
* considered constant if its declaring class is not yet initialized or if it is a well known
* field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}).
*
* @param receiver object from which this field's value is to be read. This value is ignored if
* this field is static.
* @return the constant value of this field or {@code null} if this field is not considered
* constant by the runtime
*/
JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver);
/**
* Gets the current value of this field for a given object, if available.
*
* There is no guarantee that the same value will be returned by this method for a field unless
* the field is considered to be
* {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
* runtime.
* the field is considered to be constant by the runtime.
*
* @param receiver object from which this field's value is to be read. This value is ignored if
* this field is static.
@ -97,23 +68,6 @@ public interface ConstantReflectionProvider {
*/
JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver);
/**
* Gets the current value of this field for a given object, if available. Like
* {@link #readFieldValue(ResolvedJavaField, JavaConstant)} but treats array fields as stable.
*
* There is no guarantee that the same value will be returned by this method for a field unless
* the field is considered to be
* {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
* runtime.
*
* @param receiver object from which this field's value is to be read. This value is ignored if
* this field is static.
* @param isDefaultStable if {@code true}, default values are considered stable
* @return the value of this field or {@code null} if the value is not available (e.g., because
* the field holder is not yet initialized).
*/
JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable);
/**
* Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed
* {@link JavaKind#Object object} constant, according to the Java boxing rules. Returns
@ -123,10 +77,10 @@ public interface ConstantReflectionProvider {
JavaConstant boxPrimitive(JavaConstant source);
/**
* Converts the given {@link JavaKind#Object object} constant to a
* {@link JavaKind#isPrimitive() primitive} constant, according to the Java unboxing rules.
* Returns {@code null} if the source is is not an object constant that can be unboxed, or the
* unboxed value is not available at this point.
* Converts the given {@link JavaKind#Object object} constant to a {@link JavaKind#isPrimitive()
* primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source
* is is not an object constant that can be unboxed, or the unboxed value is not available at
* this point.
*/
JavaConstant unboxPrimitive(JavaConstant source);

View File

@ -357,106 +357,4 @@ public interface JavaConstant extends Constant, JavaValue {
throw new IllegalArgumentException(kind.toString());
}
}
/**
* Returns the zero value for a given numeric kind.
*/
static JavaConstant zero(JavaKind kind) {
switch (kind) {
case Boolean:
return FALSE;
case Byte:
return forByte((byte) 0);
case Char:
return forChar((char) 0);
case Double:
return DOUBLE_0;
case Float:
return FLOAT_0;
case Int:
return INT_0;
case Long:
return LONG_0;
case Short:
return forShort((short) 0);
default:
throw new IllegalArgumentException(kind.toString());
}
}
/**
* Returns the one value for a given numeric kind.
*/
static JavaConstant one(JavaKind kind) {
switch (kind) {
case Boolean:
return TRUE;
case Byte:
return forByte((byte) 1);
case Char:
return forChar((char) 1);
case Double:
return DOUBLE_1;
case Float:
return FLOAT_1;
case Int:
return INT_1;
case Long:
return LONG_1;
case Short:
return forShort((short) 1);
default:
throw new IllegalArgumentException(kind.toString());
}
}
/**
* Adds two numeric constants.
*/
static JavaConstant add(JavaConstant x, JavaConstant y) {
assert x.getJavaKind() == y.getJavaKind();
switch (x.getJavaKind()) {
case Byte:
return forByte((byte) (x.asInt() + y.asInt()));
case Char:
return forChar((char) (x.asInt() + y.asInt()));
case Double:
return forDouble(x.asDouble() + y.asDouble());
case Float:
return forFloat(x.asFloat() + y.asFloat());
case Int:
return forInt(x.asInt() + y.asInt());
case Long:
return forLong(x.asLong() + y.asLong());
case Short:
return forShort((short) (x.asInt() + y.asInt()));
default:
throw new IllegalArgumentException(x.getJavaKind().toString());
}
}
/**
* Multiplies two numeric constants.
*/
static PrimitiveConstant mul(JavaConstant x, JavaConstant y) {
assert x.getJavaKind() == y.getJavaKind();
switch (x.getJavaKind()) {
case Byte:
return forByte((byte) (x.asInt() * y.asInt()));
case Char:
return forChar((char) (x.asInt() * y.asInt()));
case Double:
return forDouble(x.asDouble() * y.asDouble());
case Float:
return forFloat(x.asFloat() * y.asFloat());
case Int:
return forInt(x.asInt() * y.asInt());
case Long:
return forLong(x.asLong() * y.asLong());
case Short:
return forShort((short) (x.asInt() * y.asInt()));
default:
throw new IllegalArgumentException(x.getJavaKind().toString());
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,7 @@ import java.util.UnknownFormatConversionException;
* Represents a reference to a Java field, either resolved or unresolved fields. Fields, like
* methods and types, are resolved through {@link ConstantPool constant pools}.
*/
public interface JavaField extends TrustedInterface {
public interface JavaField {
/**
* Returns the name of this field.

View File

@ -33,34 +33,34 @@ import java.lang.reflect.Array;
*/
public enum JavaKind {
/** The primitive boolean kind, represented as an int on the stack. */
Boolean('z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
Boolean('Z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
/** The primitive byte kind, represented as an int on the stack. */
Byte('b', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
Byte('B', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
/** The primitive short kind, represented as an int on the stack. */
Short('s', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
Short('S', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
/** The primitive char kind, represented as an int on the stack. */
Char('c', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
Char('C', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
/** The primitive int kind, represented as an int on the stack. */
Int('i', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
Int('I', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
/** The primitive float kind. */
Float('f', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
Float('F', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
/** The primitive long kind. */
Long('j', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
Long('J', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
/** The primitive double kind. */
Double('d', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
Double('D', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
/** The Object kind, also used for arrays. */
Object('a', "Object", 1, false, null, null),
Object('A', "Object", 1, false, null, null),
/** The void float kind. */
Void('v', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
/** The void kind. */
Void('V', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
/** The non-type. */
Illegal('-', "illegal", 0, false, null, null);
@ -98,7 +98,11 @@ public enum JavaKind {
}
/**
* Returns the name of the kind as a single character.
* Returns the name of the kind as a single upper case character. For the void and primitive
* kinds, this is the <i>FieldType</i> term in
* <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-200">
* table 4.3-A</a> of the JVM Specification. For {@link #Object}, the character {@code 'A'} is
* returned and for {@link #Illegal}, {@code '-'} is returned.
*/
public char getTypeChar() {
return typeChar;
@ -204,7 +208,7 @@ public enum JavaKind {
/**
* Returns the kind from the character describing a primitive or void.
*
* @param ch the character
* @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()}
* @return the kind
*/
public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
@ -369,9 +373,9 @@ public enum JavaKind {
}
/**
* The minimum value that can be represented as a value of this kind.
* Gets the minimum value that can be represented as a value of this kind.
*
* @return the minimum value
* @return the minimum value represented as a {@code long}
*/
public long getMinValue() {
switch (this) {
@ -387,15 +391,19 @@ public enum JavaKind {
return java.lang.Integer.MIN_VALUE;
case Long:
return java.lang.Long.MIN_VALUE;
case Float:
return java.lang.Float.floatToRawIntBits(java.lang.Float.MIN_VALUE);
case Double:
return java.lang.Double.doubleToRawLongBits(java.lang.Double.MIN_VALUE);
default:
throw new IllegalArgumentException("illegal call to minValue on " + this);
}
}
/**
* The maximum value that can be represented as a value of this kind.
* Gets the maximum value that can be represented as a value of this kind.
*
* @return the maximum value
* @return the maximum value represented as a {@code long}
*/
public long getMaxValue() {
switch (this) {
@ -411,6 +419,10 @@ public enum JavaKind {
return java.lang.Integer.MAX_VALUE;
case Long:
return java.lang.Long.MAX_VALUE;
case Float:
return java.lang.Float.floatToRawIntBits(java.lang.Float.MAX_VALUE);
case Double:
return java.lang.Double.doubleToRawLongBits(java.lang.Double.MAX_VALUE);
default:
throw new IllegalArgumentException("illegal call to maxValue on " + this);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,7 @@ import java.util.UnknownFormatConversionException;
* Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and
* types, are resolved through {@link ConstantPool constant pools}.
*/
public interface JavaMethod extends TrustedInterface {
public interface JavaMethod {
/**
* Returns the name of this method.

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